From 12e8d499590b033a53d19769455dcc3ae3663388 Mon Sep 17 00:00:00 2001 From: Jacob Ronstadt Date: Thu, 26 Jun 2025 08:28:34 -0700 Subject: [PATCH 01/18] update gitignore --- .gitignore | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 290adb6b..fcd83d9e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,14 @@ # IDE folders .vscode/* **/.vs/* -Debug/* +**/Debug/* +**/Release/* +**/bin/* +**/obj/* +# Build directories +**/build/* +# Temporary files +**/temp/* src/drivers/test/**/driver/Debug/* src/drivers/test/**/driver/x64/* From 8712b402e34bdc013093e113cb587617da1707cb Mon Sep 17 00:00:00 2001 From: Jacob Ronstadt Date: Thu, 26 Jun 2025 08:29:26 -0700 Subject: [PATCH 02/18] update gitignore --- .gitignore | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index fcd83d9e..55897fd4 100644 --- a/.gitignore +++ b/.gitignore @@ -15,16 +15,16 @@ # Temporary files **/temp/* -src/drivers/test/**/driver/Debug/* -src/drivers/test/**/driver/x64/* -src/drivers/test/**/x64/* -src/drivers/test/**/Debug/* -src/drivers/test/TestDB/* -src/drivers/test/working/* -src/drivers/test/AnalysisFiles/* -AnalysisFiles/* -TestDB/* -working/* +**/src/drivers/test/**/driver/Debug/* +**/src/drivers/test/**/driver/x64/* +**/src/drivers/test/**/x64/* +**/src/drivers/test/**/Debug/* +**/src/drivers/test/TestDB/* +**/src/drivers/test/working/* +**/src/drivers/test/AnalysisFiles/* +**/AnalysisFiles/* +**/TestDB/* +**/working/* #excel files **/*.xlsx From c4ac971a45f384d7715deeb16a4fda70b6482081 Mon Sep 17 00:00:00 2001 From: Jacob Ronstadt Date: Thu, 26 Jun 2025 08:30:59 -0700 Subject: [PATCH 03/18] WIP standalone codeql extension for visual studio --- {src => codeql/src}/codeql-pack.lock.yml | 0 .../UnsafeCallInGlobalInit.qhelp | 0 .../UnsafeCallInGlobalInit.ql | 0 .../UnsafeCallInGlobalInit.sarif | 0 .../UnsafeCallInGlobalInit/driver_snippet.c | 0 .../drivers/general/DriverAlertSuppression.ql | 0 .../AnnotationSyntax/AnnotationSyntax.qhelp | 0 .../AnnotationSyntax/AnnotationSyntax.ql | 0 .../AnnotationSyntax/AnnotationSyntax.sarif | 0 .../queries/AnnotationSyntax/driver_snippet.c | 0 .../CurrentFunctionTypeNotCorrect.qhelp | 0 .../CurrentFunctionTypeNotCorrect.ql | 0 .../CurrentFunctionTypeNotCorrect.sarif | 0 .../driver_snippet.c | 0 .../DefaultPoolTag/DefaultPoolTag.qhelp | 0 .../queries/DefaultPoolTag/DefaultPoolTag.ql | 0 .../DefaultPoolTag/DefaultPoolTag.sarif | 0 .../queries/DefaultPoolTag/driver_snippet.c | 0 .../DriverEntrySaveBuffer.qhelp | 0 .../DriverEntrySaveBuffer.ql | 0 .../DriverEntrySaveBuffer.sarif | 0 .../DriverEntrySaveBuffer/driver_snippet.c | 0 .../queries/ExaminedValue/ExaminedValue.qhelp | 0 .../queries/ExaminedValue/ExaminedValue.ql | 0 .../queries/ExaminedValue/ExaminedValue.sarif | 0 .../queries/ExaminedValue/driver_snippet.c | 0 .../ExtendedDeprecatedApis.qhelp | 0 .../ExtendedDeprecatedApis.ql | 0 .../ExtendedDeprecatedApis.sarif | 898 ++++---- .../ExtendedDeprecatedApis/driver_snippet.c | 0 .../FloatHardwareStateProtection.qhelp | 0 .../FloatHardwareStateProtection.ql | 0 .../FloatHardwareStateProtection.sarif | 0 .../driver_snippet.c | 0 .../IRPStackEntryCopy/IRPStackEntryCopy.qhelp | 0 .../IRPStackEntryCopy/IRPStackEntryCopy.ql | 0 .../IRPStackEntryCopy/IRPStackEntryCopy.sarif | 0 .../IRPStackEntryCopy/driver_snippet.c | 0 .../ImportantFunctionCallOptimizedOut.qhelp | 0 .../ImportantFunctionCallOptimizedOut.ql | 0 .../ImportantFunctionCallOptimizedOut.sarif | 0 .../driver_snippet.c | 0 .../ImproperNotOperatorOnZero.qhelp | 0 .../ImproperNotOperatorOnZero.ql | 0 .../ImproperNotOperatorOnZero.sarif | 0 .../driver_snippet.c | 0 .../InvalidFunctionClassTypedef.qhelp | 0 .../InvalidFunctionClassTypedef.ql | 0 .../InvalidFunctionClassTypedef.sarif | 0 .../driver_snippet.c | 0 .../InvalidFunctionPointerAnnotation.qhelp | 0 .../InvalidFunctionPointerAnnotation.ql | 0 .../InvalidFunctionPointerAnnotation.sarif | 0 .../driver_snippet.c | 0 .../IoInitializeTimerCall.qhelp | 0 .../IoInitializeTimerCall.ql | 0 .../IoInitializeTimerCall.sarif | 0 .../IoInitializeTimerCall/driver_snippet.c | 0 .../IrqlAnnotationIssue.qhelp | 0 .../IrqlAnnotationIssue.ql | 0 .../IrqlAnnotationIssue.sarif | 0 .../IrqlAnnotationIssue/driver_snippet.c | 0 .../IrqlCancelRoutine/IrqlCancelRoutine.qhelp | 0 .../IrqlCancelRoutine/IrqlCancelRoutine.ql | 0 .../IrqlCancelRoutine/IrqlCancelRoutine.sarif | 0 .../IrqlCancelRoutine/driver_snippet.c | 0 .../IrqlFloatStateMismatch.qhelp | 0 .../IrqlFloatStateMismatch.ql | 0 .../IrqlFloatStateMismatch.sarif | 0 .../IrqlFloatStateMismatch/driver_snippet.c | 0 .../IrqlFunctionNotAnnotated.qhelp | 0 .../IrqlFunctionNotAnnotated.ql | 0 .../IrqlFunctionNotAnnotated.sarif | 0 .../IrqlFunctionNotAnnotated/driver_snippet.c | 0 .../IrqlIllegalValue/IrqlIllegalValue.qhelp | 0 .../IrqlIllegalValue/IrqlIllegalValue.ql | 0 .../IrqlIllegalValue/IrqlIllegalValue.sarif | 0 .../queries/IrqlIllegalValue/driver_snippet.c | 0 .../IrqlInconsistentWithRequired.qhelp | 0 .../IrqlInconsistentWithRequired.ql | 0 .../IrqlInconsistentWithRequired.sarif | 0 .../driver_snippet.c | 0 .../IrqlLoweredImproperly.qhelp | 0 .../IrqlLoweredImproperly.ql | 0 .../IrqlLoweredImproperly.sarif | 0 .../IrqlLoweredImproperly/driver_snippet.c | 0 .../queries/IrqlNotSaved/IrqlNotSaved.qhelp | 0 .../queries/IrqlNotSaved/IrqlNotSaved.ql | 0 .../queries/IrqlNotSaved/IrqlNotSaved.sarif | 0 .../queries/IrqlNotSaved/driver_snippet.c | 0 .../queries/IrqlNotUsed/IrqlNotUsed.qhelp | 0 .../queries/IrqlNotUsed/IrqlNotUsed.ql | 0 .../queries/IrqlNotUsed/IrqlNotUsed.sarif | 0 .../queries/IrqlNotUsed/driver_snippet.c | 0 .../IrqlSetTooHigh/IrqlSetTooHigh.qhelp | 0 .../queries/IrqlSetTooHigh/IrqlSetTooHigh.ql | 0 .../IrqlSetTooHigh/IrqlSetTooHigh.sarif | 0 .../queries/IrqlSetTooHigh/driver_snippet.c | 0 .../queries/IrqlSetTooLow/IrqlSetTooLow.qhelp | 0 .../queries/IrqlSetTooLow/IrqlSetTooLow.ql | 0 .../queries/IrqlSetTooLow/IrqlSetTooLow.sarif | 0 .../queries/IrqlSetTooLow/driver_snippet.c | 0 .../queries/IrqlTooHigh/IrqlTooHigh.qhelp | 0 .../queries/IrqlTooHigh/IrqlTooHigh.ql | 0 .../queries/IrqlTooHigh/IrqlTooHigh.sarif | 0 .../queries/IrqlTooHigh/driver_snippet.c | 0 .../queries/IrqlTooLow/IrqlTooLow.qhelp | 0 .../general/queries/IrqlTooLow/IrqlTooLow.ql | 0 .../queries/IrqlTooLow/IrqlTooLow.sarif | 0 .../queries/IrqlTooLow/driver_snippet.c | 0 .../KeSetEventPageable.qhelp | 0 .../KeSetEventPageable/KeSetEventPageable.ql | 0 .../KeSetEventPageable.sarif | 0 .../KeSetEventPageable/driver_snippet.c | 0 .../MultipleFunctionClassAnnotations.qhelp | 0 .../MultipleFunctionClassAnnotations.ql | 0 .../MultipleFunctionClassAnnotations.sarif | 0 .../driver_snippet.c | 0 .../MultithreadedAVCondition.qhelp | 0 .../MultithreadedAVCondition.ql | 0 .../MultithreadedAVCondition.sarif | 0 .../driver_snippet.cpp | 0 .../NtstatusExplicitCast.qhelp | 0 .../NtstatusExplicitCast.ql | 0 .../NtstatusExplicitCast.sarif | 0 .../NtstatusExplicitCast/driver_snippet.c | 0 .../NtstatusExplicitCast2.qhelp | 0 .../NtstatusExplicitCast2.ql | 0 .../NtstatusExplicitCast2.sarif | 0 .../NtstatusExplicitCast2/driver_snippet.c | 0 .../NtstatusExplicitCast3.qhelp | 0 .../NtstatusExplicitCast3.ql | 0 .../NtstatusExplicitCast3.sarif | 0 .../NtstatusExplicitCast3/driver_snippet.c | 0 .../NullCharacterPointerAssignment.qhelp | 0 .../NullCharacterPointerAssignment.ql | 0 .../NullCharacterPointerAssignment.sarif | 0 .../driver_snippet.c | 0 .../OperandAssignment/OperandAssignment.qhelp | 0 .../OperandAssignment/OperandAssignment.ql | 0 .../OperandAssignment/OperandAssignment.sarif | 0 .../OperandAssignment/driver_snippet.c | 0 .../PointerVariableSize.qhelp | 0 .../PointerVariableSize.ql | 0 .../PointerVariableSize.sarif | 0 .../PointerVariableSize/driver_snippet.c | 0 .../PoolTagIntegral/PoolTagIntegral.qhelp | 0 .../PoolTagIntegral/PoolTagIntegral.ql | 0 .../PoolTagIntegral/PoolTagIntegral.sarif | 0 .../queries/PoolTagIntegral/driver_snippet.c | 0 .../RoleTypeCorrectlyUsed.qhelp | 0 .../RoleTypeCorrectlyUsed.ql | 0 .../RoleTypeCorrectlyUsed.sarif | 398 ++-- .../RoleTypeCorrectlyUsed/driver_snippet.c | 0 .../RoutineFunctionTypeNotExpected.qhelp | 0 .../RoutineFunctionTypeNotExpected.ql | 0 .../RoutineFunctionTypeNotExpected.sarif | 824 +++---- .../driver_snippet.c | 0 .../StaticInitializer/StaticInitializer.qhelp | 0 .../StaticInitializer/StaticInitializer.ql | 0 .../StaticInitializer/StaticInitializer.sarif | 0 .../StaticInitializer/driver_snippet.cpp | 0 .../general/queries/StrSafe/StrSafe.qhelp | 0 .../general/queries/StrSafe/StrSafe.ql | 0 .../general/queries/StrSafe/StrSafe.sarif | 0 .../general/queries/StrSafe/driver_snippet.c | 0 .../StrictTypeMatch/StrictTypeMatch.qhelp | 0 .../StrictTypeMatch/StrictTypeMatch.ql | 0 .../StrictTypeMatch/StrictTypeMatch.sarif | 0 .../queries/StrictTypeMatch/driver_snippet.c | 0 .../WdkDeprecatedApis/WdkDeprecatedApis.sarif | 0 .../WdkDeprecatedApis/driver_snippet.c | 0 .../wdk-deprecated-api.qhelp | 0 .../WdkDeprecatedApis/wdk-deprecated-api.ql | 0 .../DefaultPoolTagExtended.qhelp | 0 .../DefaultPoolTagExtended.ql | 0 .../DefaultPoolTagExtended.sarif | 0 .../DefaultPoolTagExtended/driver_snippet.c | 0 .../DriverIsolationRtlViolation.qhelp | 0 .../DriverIsolationRtlViolation.ql | 0 .../DriverIsolationRtlViolation.sarif | 0 .../driver_snippet.c | 0 .../DriverIsolationZwViolation1.qhelp | 0 .../DriverIsolationZwViolation1.ql | 0 .../DriverIsolationZwViolation1.sarif | 0 .../driver_snippet.c | 0 .../DriverIsolationZwViolation2.qhelp | 0 .../DriverIsolationZwViolation2.ql | 0 .../DriverIsolationZwViolation2.sarif | 0 .../driver_snippet.c | 0 .../KeSetEventIrql/KeSetEventIrql.qhelp | 0 .../KeSetEventIrql/KeSetEventIrql.ql | 0 .../KeSetEventIrql/KeSetEventIrql.sarif | 0 .../KeSetEventIrql/driver_snippet.c | 0 .../UnicodeStringFreed.qhelp | 0 .../UnicodeStringFreed/UnicodeStringFreed.ql | 0 .../UnicodeStringFreed.sarif | 0 .../UnicodeStringFreed/driver_snippet.c | 0 .../drivers/kmdf/libraries/KmdfDrivers.qll | 2004 ++++++++--------- .../queries/FloatSafeExit/FloatSafeExit.qhelp | 0 .../queries/FloatSafeExit/FloatSafeExit.ql | 0 .../queries/FloatSafeExit/FloatSafeExit.sarif | 0 .../queries/FloatSafeExit/driver_snippet.c | 0 .../FloatUnsafeExit/FloatUnsafeExit.qhelp | 0 .../FloatUnsafeExit/FloatUnsafeExit.ql | 0 .../FloatUnsafeExit/FloatUnsafeExit.sarif | 0 .../queries/FloatUnsafeExit/driver_snippet.c | 0 .../DeviceInitApi/DeviceInitApi.ql | 0 .../DeviceInitApi/DeviceInitApi.sarif | 0 .../DeviceInitApi/__test_device_init_api.c | 0 .../DeviceInitApi/driver_snippet.c | 0 .../ConnectRedirectHandleCreation.qlhelp | 0 .../ConnectRedirectHandleCreation.sarif | 0 ...nectRedirectMultipleCallsHandleCreation.ql | 0 .../driver_snippet.c | 0 .../ConnectRedirectPendClassify.ql | 0 .../ConnectRedirectPendClassify.qlhelp | 0 .../ConnectRedirectPendClassify.sarif | 0 .../driver_snippet.c | 0 .../FlowLayerCalloutReturnsBlock.ql | 0 .../FlowLayerCalloutReturnsBlock.qlhelp | 0 .../FlowLayerCalloutReturnsBlock.sarif | 0 .../driver_snippet.c | 0 ...tRedirectCalloutShouldNotSetReauthorize.ql | 0 ...irectCalloutShouldNotSetReauthorize.qlhelp | 0 ...directCalloutShouldNotSetReauthorize.sarif | 0 .../InlineConnectRedirect/driver_snippet.c | 0 .../OobStreamInjectionReturnsBlock.ql | 0 .../OobStreamInjectionReturnsBlock.qlhelp | 0 .../OobStreamInjectionReturnsBlock.sarif | 0 .../wfp/OobStreamInjection/driver_snippet.c | 0 .../StreamCalloutSetActionType.qlhelp | 0 .../StreamCalloutSetActionType.sarif | 0 .../StreamCalloutsSetActionType.ql | 0 .../driver_snippet.c | 0 .../StreamInspectionFunctionCallViolation.ql | 0 ...reamInspectionFunctionCallViolation.qlhelp | 0 ...treamInspectionFunctionCallViolation.sarif | 0 .../driver_snippet.c | 0 ...ortLayerCannotInjectCloneDuringClassify.ql | 0 ...ayerCannotInjectCloneDuringClassify.qlhelp | 0 ...LayerCannotInjectCloneDuringclassify.sarif | 0 .../driver_snippet.c | 0 .../drivers/libraries/DriverIsolation.qll | 0 .../src}/drivers/libraries/Irql.qll | 1770 +++++++-------- .../src}/drivers/libraries/IrqlDataFlow.qll | 0 .../src}/drivers/libraries/IrqlDebug.qll | 0 .../src}/drivers/libraries/Page.qll | 212 +- .../src}/drivers/libraries/RoleTypes.qll | 700 +++--- {src => codeql/src}/drivers/libraries/SAL.qll | 0 .../src}/drivers/libraries/Suppression.qll | 0 {src => codeql/src}/drivers/libraries/wfp.qll | 0 .../drivers/ndis/libraries/NdisDrivers.qll | 1690 +++++++------- .../storport/libraries/StorportDrivers.qll | 502 ++--- {src => codeql/src}/drivers/test/README.md | 0 .../ApplicationForDriversTestTemplate.sln | 0 .../ApplicationForDriversTestTemplate.vcxproj | 0 ...tionForDriversTestTemplate.vcxproj.filters | 0 ...icationForDriversTestTemplate.vcxproj.user | 0 .../Source.cpp | 0 .../driver_snippet.c | 0 .../CppKMDFTestTemplate.inf | 0 .../CppKMDFTestTemplate.sln | 0 .../CppKMDFTestTemplate.vcxproj | 0 .../CppKMDFTestTemplate.vcxproj.filters | 0 .../CppKMDFTestTemplate/Device.c | 0 .../CppKMDFTestTemplate/Device.h | 0 .../CppKMDFTestTemplate/Driver.cpp | 0 .../CppKMDFTestTemplate/Driver.h | 0 .../CppKMDFTestTemplate/Public.h | 0 .../TestTemplates/CppKMDFTestTemplate/Queue.c | 0 .../TestTemplates/CppKMDFTestTemplate/Queue.h | 0 .../CppKMDFTestTemplate/ReadMe.txt | 0 .../TestTemplates/CppKMDFTestTemplate/Trace.h | 0 .../driver/driver_snippet.cpp | 0 .../TestTemplates/KMDFTestTemplate/Device.c | 0 .../TestTemplates/KMDFTestTemplate/Device.h | 0 .../TestTemplates/KMDFTestTemplate/Driver.c | 0 .../TestTemplates/KMDFTestTemplate/Driver.h | 0 .../KMDFTestTemplate/KMDFTestTemplate.inf | 0 .../KMDFTestTemplate/KMDFTestTemplate.sln | 0 .../KMDFTestTemplate/KMDFTestTemplate.vcxproj | 0 .../KMDFTestTemplate.vcxproj.filters | 0 .../TestTemplates/KMDFTestTemplate/Public.h | 0 .../TestTemplates/KMDFTestTemplate/Queue.c | 0 .../TestTemplates/KMDFTestTemplate/Queue.h | 0 .../TestTemplates/KMDFTestTemplate/ReadMe.txt | 0 .../TestTemplates/KMDFTestTemplate/Trace.h | 0 .../KMDFTestTemplate/driver/driver_snippet.c | 0 .../QueryTemplate/QueryTemplate.qhelp | 0 .../QueryTemplate/QueryTemplate.ql | 0 .../QueryTemplate/QueryTemplate.sarif | 0 .../QueryTemplate/driver_snippet.c | 0 .../TestTemplates/WDMTestTemplate/README.md | 0 .../WDMTestTemplate/WDMTestTemplate.sln | 0 .../WDMTestTemplate/driver/driver_snippet.c | 0 .../WDMTestTemplate/driver/fail_driver1.c | 0 .../WDMTestTemplate/driver/fail_driver1.h | 0 .../driver/fail_driver1.vcxproj | 0 .../driver/fail_driver1.vcxproj.Filters | 0 .../driver/fail_driver1.vcxproj.user | 0 .../drivers/test/build_create_analyze_test.py | 0 .../src}/drivers/test/compare_results.py | 0 .../drivers/test/diff/AnnotationSyntax.sarif | 0 .../diff/CurrentFunctionTypeNotCorrect.sarif | 0 .../drivers/test/diff/DefaultPoolTag.sarif | 0 .../test/diff/DefaultPoolTagExtended.sarif | 0 .../drivers/test/diff/DeviceInitApi.sarif | 0 .../test/diff/DriverEntrySaveBuffer.sarif | 0 .../diff/DriverIsolationRtlViolation.sarif | 0 .../diff/DriverIsolationZwViolation1.sarif | 0 .../diff/DriverIsolationZwViolation2.sarif | 0 .../src/drivers/test/diff/ExaminedValue.sarif | 0 .../test/diff/ExtendedDeprecatedApis.sarif | 0 .../diff/FloatHardwareStateProtection.sarif | 0 .../src/drivers/test/diff/FloatSafeExit.sarif | 0 .../drivers/test/diff/FloatUnsafeExit.sarif | 0 .../drivers/test/diff/IRPStackEntryCopy.sarif | 0 .../test/diff/IllegalFieldAccess.sarif | 0 .../test/diff/IllegalFieldAccess2.sarif | 0 .../drivers/test/diff/IllegalFieldWrite.sarif | 0 .../ImportantFunctionCallOptimizedOut.sarif | 0 .../test/diff/ImproperNotOperatorOnZero.sarif | 0 .../drivers/test/diff/InitNotCleared.sarif | 0 .../diff/InvalidFunctionClassTypedef.sarif | 0 .../InvalidFunctionPointerAnnotation.sarif | 0 .../test/diff/IoInitializeTimerCall.sarif | 0 .../src/drivers/test/diff/IrqTooHigh.sarif | 0 .../src/drivers/test/diff/IrqTooLow.sarif | 0 .../test/diff/IrqlAnnotationIssue.sarif | 0 .../drivers/test/diff/IrqlCancelRoutine.sarif | 0 .../test/diff/IrqlFloatStateMismatch.sarif | 0 .../test/diff/IrqlFunctionNotAnnotated.sarif | 0 .../drivers/test/diff/IrqlIllegalValue.sarif | 0 .../diff/IrqlInconsistentWithRequired.sarif | 0 .../test/diff/IrqlLoweredImproperly.sarif | 0 .../src/drivers/test/diff/IrqlNotSaved.sarif | 0 .../src/drivers/test/diff/IrqlNotUsed.sarif | 0 .../drivers/test/diff/IrqlSetTooHigh.sarif | 0 .../drivers/test/diff/IrqlSetTooLow.sarif | 0 .../src/drivers/test/diff/IrqlTooHigh.sarif | 0 .../src/drivers/test/diff/IrqlTooLow.sarif | 0 .../drivers/test/diff/KeSetEventIrql.sarif | 0 .../test/diff/KeSetEventPageable.sarif | 0 .../src/drivers/test/diff/KeWaitLocal.sarif | 0 .../MultipleFunctionClassAnnotations.sarif | 0 .../drivers/test/diff/MultiplePagedCode.sarif | 0 .../test/diff/MultithreadedAVCondition.sarif | 0 .../src/drivers/test/diff/NoPagedCode.sarif | 0 .../drivers/test/diff/NoPagingSegment.sarif | 0 .../test/diff/NtstatusExplicitCast.sarif | 40 +- .../test/diff/NtstatusExplicitCast2.sarif | 40 +- .../test/diff/NtstatusExplicitCast3.sarif | 40 +- .../diff/NullCharacterPointerAssignment.sarif | 40 +- .../drivers/test/diff/ObReferenceMode.sarif | 21 + .../src}/drivers/test/diff/OpaqueMdlUse.sarif | 40 +- .../drivers/test/diff/OpaqueMdlWrite.sarif | 40 +- .../drivers/test/diff/OperandAssignment.sarif | 21 + .../test/diff/PendingStatusError.sarif | 40 +- .../test/diff/PointerVariableSize.sarif | 21 + .../drivers/test/diff/PoolTagIntegral.sarif | 21 + .../test/diff/RoleTypeCorrectlyUsed.sarif | 40 +- .../diff/RoutineFunctionTypeNotExpected.sarif | 21 + .../drivers/test/diff/StaticInitializer.sarif | 21 + .../src}/drivers/test/diff/StrSafe.sarif | 40 +- .../drivers/test/diff/StrictTypeMatch.sarif | 21 + .../test/diff/UnicodeStringFreed.sarif | 40 +- .../test/diff/UnsafeCallInGlobalInit.sarif | 21 + .../drivers/test/diff/WdkDeprecatedApis.sarif | 21 + .../diff/WrongDispatchTableAssignment.sarif | 40 +- .../src}/drivers/test/dvl_tests/dvl_tests.ps1 | 0 .../expected_results/clean_expected.sarif | 0 .../expected_results/mustfix_expected.sarif | 0 .../src}/drivers/test/requirements.txt | 0 .../src}/drivers/wdm/libraries/Mdl.qll | 0 .../src}/drivers/wdm/libraries/WdmDrivers.qll | 0 .../IllegalFieldAccess.qhelp | 0 .../IllegalFieldAccess/IllegalFieldAccess.ql | 0 .../IllegalFieldAccess.sarif | 0 .../IllegalFieldAccess/driver_snippet.c | 0 .../IllegalFieldAccess2.qhelp | 0 .../IllegalFieldAccess2.ql | 0 .../IllegalFieldAccess2.sarif | 0 .../IllegalFieldAccess2/driver_snippet.c | 0 .../IllegalFieldWrite/IllegalFieldWrite.qhelp | 0 .../IllegalFieldWrite/IllegalFieldWrite.ql | 0 .../IllegalFieldWrite/IllegalFieldWrite.sarif | 0 .../IllegalFieldWrite/driver_snippet.c | 0 .../InconsistentDispatchAnnotations.ql | 0 .../InitNotCleared/InitNotCleared.qhelp | 0 .../queries/InitNotCleared/InitNotCleared.ql | 0 .../InitNotCleared/InitNotCleared.sarif | 0 .../queries/InitNotCleared/driver_snippet.c | 0 .../wdm/queries/KeWaitLocal/KeWaitLocal.qhelp | 0 .../wdm/queries/KeWaitLocal/KeWaitLocal.ql | 62 +- .../wdm/queries/KeWaitLocal/KeWaitLocal.sarif | 470 ++-- .../wdm/queries/KeWaitLocal/driver_snippet.c | 0 .../MultiplePagedCode/MultiplePagedCode.qhelp | 48 +- .../MultiplePagedCode/MultiplePagedCode.ql | 72 +- .../MultiplePagedCode/MultiplePagedCode.sarif | 226 +- .../MultiplePagedCode/driver_snippet.c | 116 +- .../wdm/queries/NoPagedCode/NoPagedCode.qhelp | 50 +- .../wdm/queries/NoPagedCode/NoPagedCode.ql | 64 +- .../wdm/queries/NoPagedCode/NoPagedCode.sarif | 336 +-- .../wdm/queries/NoPagedCode/driver_snippet.c | 146 +- .../NoPagingSegment/NoPagingSegment.qhelp | 48 +- .../NoPagingSegment/NoPagingSegment.ql | 66 +- .../NoPagingSegment/NoPagingSegment.sarif | 280 +-- .../queries/NoPagingSegment/driver_snippet.c | 150 +- .../ObReferenceMode/ObReferenceMode.qhelp | 0 .../ObReferenceMode/ObReferenceMode.ql | 0 .../ObReferenceMode/ObReferenceMode.sarif | 0 .../queries/ObReferenceMode/driver_snippet.c | 0 .../queries/OpaqueMdlUse/OpaqueMdlUse.qhelp | 0 .../wdm/queries/OpaqueMdlUse/OpaqueMdlUse.ql | 0 .../queries/OpaqueMdlUse/OpaqueMdlUse.sarif | 0 .../wdm/queries/OpaqueMdlUse/driver_snippet.c | 0 .../OpaqueMdlWrite/OpaqueMdlWrite.qhelp | 0 .../queries/OpaqueMdlWrite/OpaqueMdlWrite.ql | 0 .../OpaqueMdlWrite/OpaqueMdlWrite.sarif | 0 .../queries/OpaqueMdlWrite/driver_snippet.c | 0 .../PendingStatusError.qhelp | 0 .../PendingStatusError/PendingStatusError.ql | 146 +- .../PendingStatusError.sarif | 226 +- .../PendingStatusError/driver_snippet.c | 124 +- .../src}/drivers/wdm/queries/README.md | 12 +- .../WrongDispatchTableAssignment.qhelp | 88 +- .../WrongDispatchTableAssignment.ql | 190 +- .../WrongDispatchTableAssignment.sarif | 338 +-- .../driver_snippet.c | 52 +- .../PaddingByteInformationDisclosure.qhelp | 0 .../PaddingByteInformationDisclosure.ql | 0 .../PaddingByteInformationDisclosureBadCode.c | 0 ...PaddingByteInformationDisclosureGoodCode.c | 0 .../Conversion/BadOverflowGuard.qhelp | 0 .../Conversion/BadOverflowGuard.ql | 0 .../Conversion/BadOverflowGuardBadCode.c | 0 .../Conversion/BadOverflowGuardGoodCode.c | 0 .../Likely Bugs/Conversion/InfiniteLoop.qhelp | 0 .../Likely Bugs/Conversion/InfiniteLoop.ql | 0 .../Conversion/InfiniteLoopBadCode.c | 0 .../Conversion/InfiniteLoopGoodCode.c | 0 .../UseAfterFree/ProbableUseAfterFree.qhelp | 0 .../UseAfterFree/ProbableUseAfterFree.ql | 0 .../UseAfterFree/UseAfterFree.qhelp | 0 .../UseAfterFree/UseAfterFree.ql | 0 .../UseAfterFree/UseAfterFreeLib.qhelp | 0 .../UseAfterFree/UseAfterFreeLib.qll | 0 .../UseAfterFree/UseAfterFree_bad.c | 0 .../UseAfterFree/UseAfterFree_good.c | 0 .../Likely Bugs/UninitializedPtrField.qhelp | 0 .../Likely Bugs/UninitializedPtrField.ql | 0 .../UninitializedPtrFieldBadCode.c | 0 .../UninitializedPtrFieldGoodCode.c | 0 .../CWE/CWE-704/WcharCharConversion.cpp | 0 .../CWE-704/WcharCharConversionLimited.qhelp | 0 .../CWE/CWE-704/WcharCharConversionLimited.ql | 0 .../Crytpography/HardcodedIVCNG.qhelp | 0 .../Security/Crytpography/HardcodedIVCNG.ql | 0 .../src}/microsoft/commons/Literals.qll | 0 .../microsoft/commons/MemoryAllocation.qll | 0 {src => codeql/src}/qlpack.yml | 0 .../src}/windows-driver-suites/mustfix.qls | 0 .../src}/windows-driver-suites/mustrun.qls | 0 .../ported_driver_ca_checks.qls | 0 .../windows-driver-suites/recommended.qls | 0 src/drivers/test/diff/IrqlNotSaved.sarif | 21 - src/drivers/test/diff/IrqlNotUsed.sarif | 21 - src/drivers/test/diff/IrqlSetTooHigh.sarif | 21 - src/drivers/test/diff/IrqlTooHigh.sarif | 21 - src/drivers/test/diff/IrqlTooLow.sarif | 21 - src/drivers/test/diff/KeWaitLocal.sarif | 21 - src/drivers/test/diff/MultiplePagedCode.sarif | 21 - src/drivers/test/diff/NoPagedCode.sarif | 21 - src/drivers/test/diff/NoPagingSegment.sarif | 21 - .../CodeQL.VisualStudio.Core.projitems | 53 + .../CodeQL.VisualStudio.Core.shproj | 13 + .../CodeQL.VisualStudio.Core/CodeQLCommand.cs | 387 ++++ .../CodeQLExceptions.cs | 95 + .../CodeQLGeneralOptions.cs | 78 + .../CodeQLGeneralOptionsControl.xaml | 91 + .../CodeQLGeneralOptionsControl.xaml.cs | 26 + .../CodeQLGeneralOptionsPage.cs | 67 + .../CodeQLInstallHelper.xaml | 75 + .../CodeQLInstallHelper.xaml.cs | 153 ++ .../CodeQL.VisualStudio.Core/CodeQLPackage.cs | 259 +++ .../CodeQL.VisualStudio.Core/CodeQLRunner.cs | 701 ++++++ .../CodeQL.VisualStudio.Core/CodeQLService.cs | 367 +++ .../ICodeQLGeneralOptions.cs | 14 + .../CodeQL.VisualStudio.Core/InfoBar.cs | 183 ++ .../InstallWindow.xaml | 16 + .../InstallWindow.xaml.cs | 100 + .../CodeQL.VisualStudio.Core/License.txt | 7 + .../CodeQL.VisualStudio.Core/ProjectHelper.cs | 334 +++ .../Resources.Designer.cs | 852 +++++++ .../CodeQL.VisualStudio.Core/Resources.resx | 120 + .../CodeQL.VisualStudio.sln | 43 + .../CodeQL.VisualStudio/App.config | 23 + .../CodeQL.VisualStudio.csproj | 127 ++ .../CodeQL.VisualStudio/CodeQLPackage.vsct | 235 ++ .../CodeQL.VisualStudio/License.txt | 7 + .../Properties/AssemblyInfo.cs | 46 + .../CodeQL.VisualStudio/VSPackage.resx | 126 ++ .../CodeQL.VisualStudio/icon.png | Bin 0 -> 4600 bytes .../source.extension.vsixmanifest | 43 + tools/extensions/CodeQL.VisualStudio/LICENSE | 21 + 506 files changed, 11225 insertions(+), 6563 deletions(-) rename {src => codeql/src}/codeql-pack.lock.yml (100%) rename {src => codeql/src}/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.qhelp (100%) rename {src => codeql/src}/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.ql (100%) rename {src => codeql/src}/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.sarif (100%) rename {src => codeql/src}/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/DriverAlertSuppression.ql (100%) rename {src => codeql/src}/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.ql (100%) rename {src => codeql/src}/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.sarif (100%) rename {src => codeql/src}/drivers/general/queries/AnnotationSyntax/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.ql (100%) rename {src => codeql/src}/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.sarif (100%) rename {src => codeql/src}/drivers/general/queries/CurrentFunctionTypeNotCorrect/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.ql (100%) rename {src => codeql/src}/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.sarif (100%) rename {src => codeql/src}/drivers/general/queries/DefaultPoolTag/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.ql (100%) rename {src => codeql/src}/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.sarif (100%) rename {src => codeql/src}/drivers/general/queries/DriverEntrySaveBuffer/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/ExaminedValue/ExaminedValue.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/ExaminedValue/ExaminedValue.ql (100%) rename {src => codeql/src}/drivers/general/queries/ExaminedValue/ExaminedValue.sarif (100%) rename {src => codeql/src}/drivers/general/queries/ExaminedValue/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.ql (100%) rename {src => codeql/src}/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.sarif (97%) rename {src => codeql/src}/drivers/general/queries/ExtendedDeprecatedApis/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.ql (100%) rename {src => codeql/src}/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.sarif (100%) rename {src => codeql/src}/drivers/general/queries/FloatHardwareStateProtection/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.ql (100%) rename {src => codeql/src}/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IRPStackEntryCopy/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.ql (100%) rename {src => codeql/src}/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.sarif (100%) rename {src => codeql/src}/drivers/general/queries/ImportantFunctionCallOptimizedOut/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.ql (100%) rename {src => codeql/src}/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.sarif (100%) rename {src => codeql/src}/drivers/general/queries/ImproperNotOperatorOnZero/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.ql (100%) rename {src => codeql/src}/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.sarif (100%) rename {src => codeql/src}/drivers/general/queries/InvalidFunctionClassTypedef/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.ql (100%) rename {src => codeql/src}/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.sarif (100%) rename {src => codeql/src}/drivers/general/queries/InvalidFunctionPointerAnnotation/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.ql (100%) rename {src => codeql/src}/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IoInitializeTimerCall/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlAnnotationIssue/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlCancelRoutine/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlFloatStateMismatch/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlFunctionNotAnnotated/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlIllegalValue/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlInconsistentWithRequired/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlLoweredImproperly/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlNotSaved/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlNotUsed/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlSetTooHigh/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlSetTooLow/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlTooHigh/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/IrqlTooLow/IrqlTooLow.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/IrqlTooLow/IrqlTooLow.ql (100%) rename {src => codeql/src}/drivers/general/queries/IrqlTooLow/IrqlTooLow.sarif (100%) rename {src => codeql/src}/drivers/general/queries/IrqlTooLow/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.ql (100%) rename {src => codeql/src}/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.sarif (100%) rename {src => codeql/src}/drivers/general/queries/KeSetEventPageable/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.ql (100%) rename {src => codeql/src}/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.sarif (100%) rename {src => codeql/src}/drivers/general/queries/MultipleFunctionClassAnnotations/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.ql (100%) rename {src => codeql/src}/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.sarif (100%) rename {src => codeql/src}/drivers/general/queries/MultithreadedAVCondition/driver_snippet.cpp (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.ql (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.sarif (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.ql (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.sarif (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast2/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.ql (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.sarif (100%) rename {src => codeql/src}/drivers/general/queries/NtstatusExplicitCast3/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.ql (100%) rename {src => codeql/src}/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.sarif (100%) rename {src => codeql/src}/drivers/general/queries/NullCharacterPointerAssignment/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/OperandAssignment/OperandAssignment.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/OperandAssignment/OperandAssignment.ql (100%) rename {src => codeql/src}/drivers/general/queries/OperandAssignment/OperandAssignment.sarif (100%) rename {src => codeql/src}/drivers/general/queries/OperandAssignment/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/PointerVariableSize/PointerVariableSize.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/PointerVariableSize/PointerVariableSize.ql (100%) rename {src => codeql/src}/drivers/general/queries/PointerVariableSize/PointerVariableSize.sarif (100%) rename {src => codeql/src}/drivers/general/queries/PointerVariableSize/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.ql (100%) rename {src => codeql/src}/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.sarif (100%) rename {src => codeql/src}/drivers/general/queries/PoolTagIntegral/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.ql (100%) rename {src => codeql/src}/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.sarif (96%) rename {src => codeql/src}/drivers/general/queries/RoleTypeCorrectlyUsed/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.ql (100%) rename {src => codeql/src}/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.sarif (96%) rename {src => codeql/src}/drivers/general/queries/RoutineFunctionTypeNotExpected/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/StaticInitializer/StaticInitializer.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/StaticInitializer/StaticInitializer.ql (100%) rename {src => codeql/src}/drivers/general/queries/StaticInitializer/StaticInitializer.sarif (100%) rename {src => codeql/src}/drivers/general/queries/StaticInitializer/driver_snippet.cpp (100%) rename {src => codeql/src}/drivers/general/queries/StrSafe/StrSafe.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/StrSafe/StrSafe.ql (100%) rename {src => codeql/src}/drivers/general/queries/StrSafe/StrSafe.sarif (100%) rename {src => codeql/src}/drivers/general/queries/StrSafe/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.ql (100%) rename {src => codeql/src}/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.sarif (100%) rename {src => codeql/src}/drivers/general/queries/StrictTypeMatch/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/WdkDeprecatedApis/WdkDeprecatedApis.sarif (100%) rename {src => codeql/src}/drivers/general/queries/WdkDeprecatedApis/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/WdkDeprecatedApis/wdk-deprecated-api.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/WdkDeprecatedApis/wdk-deprecated-api.ql (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.ql (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.sarif (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DefaultPoolTagExtended/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.ql (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.sarif (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationRtlViolation/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.ql (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.sarif (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationZwViolation1/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.ql (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.sarif (100%) rename {src => codeql/src}/drivers/general/queries/experimental/DriverIsolationZwViolation2/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.ql (100%) rename {src => codeql/src}/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.sarif (100%) rename {src => codeql/src}/drivers/general/queries/experimental/KeSetEventIrql/driver_snippet.c (100%) rename {src => codeql/src}/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.qhelp (100%) rename {src => codeql/src}/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.ql (100%) rename {src => codeql/src}/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.sarif (100%) rename {src => codeql/src}/drivers/general/queries/experimental/UnicodeStringFreed/driver_snippet.c (100%) rename {src => codeql/src}/drivers/kmdf/libraries/KmdfDrivers.qll (97%) rename {src => codeql/src}/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.qhelp (100%) rename {src => codeql/src}/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.ql (100%) rename {src => codeql/src}/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.sarif (100%) rename {src => codeql/src}/drivers/kmdf/queries/FloatSafeExit/driver_snippet.c (100%) rename {src => codeql/src}/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.qhelp (100%) rename {src => codeql/src}/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.ql (100%) rename {src => codeql/src}/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.sarif (100%) rename {src => codeql/src}/drivers/kmdf/queries/FloatUnsafeExit/driver_snippet.c (100%) rename {src => codeql/src}/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.ql (100%) rename {src => codeql/src}/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.sarif (100%) rename {src => codeql/src}/drivers/kmdf/queries/experimental/DeviceInitApi/__test_device_init_api.c (100%) rename {src => codeql/src}/drivers/kmdf/queries/experimental/DeviceInitApi/driver_snippet.c (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectHandleCreation.qlhelp (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectHandleCreation.sarif (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectMultipleCallsHandleCreation.ql (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/driver_snippet.c (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.ql (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.qlhelp (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.sarif (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/driver_snippet.c (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.ql (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.qlhelp (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.sarif (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/driver_snippet.c (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.ql (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.qlhelp (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.sarif (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/InlineConnectRedirect/driver_snippet.c (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.ql (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.qlhelp (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.sarif (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/OobStreamInjection/driver_snippet.c (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutSetActionType.qlhelp (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutSetActionType.sarif (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutsSetActionType.ql (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/driver_snippet.c (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.ql (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.qlhelp (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.sarif (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/driver_snippet.c (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.ql (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.qlhelp (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringclassify.sarif (100%) rename {src => codeql/src}/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/driver_snippet.c (100%) rename {src => codeql/src}/drivers/libraries/DriverIsolation.qll (100%) rename {src => codeql/src}/drivers/libraries/Irql.qll (97%) rename {src => codeql/src}/drivers/libraries/IrqlDataFlow.qll (100%) rename {src => codeql/src}/drivers/libraries/IrqlDebug.qll (100%) rename {src => codeql/src}/drivers/libraries/Page.qll (96%) rename {src => codeql/src}/drivers/libraries/RoleTypes.qll (96%) rename {src => codeql/src}/drivers/libraries/SAL.qll (100%) rename {src => codeql/src}/drivers/libraries/Suppression.qll (100%) rename {src => codeql/src}/drivers/libraries/wfp.qll (100%) rename {src => codeql/src}/drivers/ndis/libraries/NdisDrivers.qll (97%) rename {src => codeql/src}/drivers/storport/libraries/StorportDrivers.qll (97%) rename {src => codeql/src}/drivers/test/README.md (100%) rename {src => codeql/src}/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.sln (100%) rename {src => codeql/src}/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj (100%) rename {src => codeql/src}/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj.filters (100%) rename {src => codeql/src}/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj.user (100%) rename {src => codeql/src}/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/Source.cpp (100%) rename {src => codeql/src}/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/driver_snippet.c (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.inf (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.sln (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj.filters (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/Device.c (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/Device.h (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/Driver.cpp (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/Driver.h (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/Public.h (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/Queue.c (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/Queue.h (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/ReadMe.txt (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/Trace.h (100%) rename {src => codeql/src}/drivers/test/TestTemplates/CppKMDFTestTemplate/driver/driver_snippet.cpp (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/Device.c (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/Device.h (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/Driver.c (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/Driver.h (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.inf (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.sln (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj.filters (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/Public.h (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/Queue.c (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/Queue.h (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/ReadMe.txt (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/Trace.h (100%) rename {src => codeql/src}/drivers/test/TestTemplates/KMDFTestTemplate/driver/driver_snippet.c (100%) rename {src => codeql/src}/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.qhelp (100%) rename {src => codeql/src}/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.ql (100%) rename {src => codeql/src}/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.sarif (100%) rename {src => codeql/src}/drivers/test/TestTemplates/QueryTemplate/driver_snippet.c (100%) rename {src => codeql/src}/drivers/test/TestTemplates/WDMTestTemplate/README.md (100%) rename {src => codeql/src}/drivers/test/TestTemplates/WDMTestTemplate/WDMTestTemplate.sln (100%) rename {src => codeql/src}/drivers/test/TestTemplates/WDMTestTemplate/driver/driver_snippet.c (100%) rename {src => codeql/src}/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.c (100%) rename {src => codeql/src}/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.h (100%) rename {src => codeql/src}/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj (100%) rename {src => codeql/src}/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj.Filters (100%) rename {src => codeql/src}/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj.user (100%) rename {src => codeql/src}/drivers/test/build_create_analyze_test.py (100%) rename {src => codeql/src}/drivers/test/compare_results.py (100%) rename {src => codeql/src}/drivers/test/diff/AnnotationSyntax.sarif (100%) rename {src => codeql/src}/drivers/test/diff/CurrentFunctionTypeNotCorrect.sarif (100%) rename {src => codeql/src}/drivers/test/diff/DefaultPoolTag.sarif (100%) rename {src => codeql/src}/drivers/test/diff/DefaultPoolTagExtended.sarif (100%) rename {src => codeql/src}/drivers/test/diff/DeviceInitApi.sarif (100%) rename {src => codeql/src}/drivers/test/diff/DriverEntrySaveBuffer.sarif (100%) rename {src => codeql/src}/drivers/test/diff/DriverIsolationRtlViolation.sarif (100%) rename {src => codeql/src}/drivers/test/diff/DriverIsolationZwViolation1.sarif (100%) rename {src => codeql/src}/drivers/test/diff/DriverIsolationZwViolation2.sarif (100%) rename src/drivers/test/diff/ExtendedDeprecatedApis.sarif => codeql/src/drivers/test/diff/ExaminedValue.sarif (100%) rename src/drivers/test/diff/FloatHardwareStateProtection.sarif => codeql/src/drivers/test/diff/ExtendedDeprecatedApis.sarif (100%) rename src/drivers/test/diff/FloatSafeExit.sarif => codeql/src/drivers/test/diff/FloatHardwareStateProtection.sarif (100%) rename src/drivers/test/diff/FloatUnsafeExit.sarif => codeql/src/drivers/test/diff/FloatSafeExit.sarif (100%) rename src/drivers/test/diff/IRPStackEntryCopy.sarif => codeql/src/drivers/test/diff/FloatUnsafeExit.sarif (100%) rename src/drivers/test/diff/ImportantFunctionCallOptimizedOut.sarif => codeql/src/drivers/test/diff/IRPStackEntryCopy.sarif (100%) rename src/drivers/test/diff/ImproperNotOperatorOnZero.sarif => codeql/src/drivers/test/diff/IllegalFieldAccess.sarif (100%) rename src/drivers/test/diff/InitNotCleared.sarif => codeql/src/drivers/test/diff/IllegalFieldAccess2.sarif (100%) rename src/drivers/test/diff/InvalidFunctionClassTypedef.sarif => codeql/src/drivers/test/diff/IllegalFieldWrite.sarif (100%) rename src/drivers/test/diff/InvalidFunctionPointerAnnotation.sarif => codeql/src/drivers/test/diff/ImportantFunctionCallOptimizedOut.sarif (100%) rename src/drivers/test/diff/IoInitializeTimerCall.sarif => codeql/src/drivers/test/diff/ImproperNotOperatorOnZero.sarif (100%) rename src/drivers/test/diff/IrqTooHigh.sarif => codeql/src/drivers/test/diff/InitNotCleared.sarif (100%) rename src/drivers/test/diff/IrqTooLow.sarif => codeql/src/drivers/test/diff/InvalidFunctionClassTypedef.sarif (100%) rename src/drivers/test/diff/IrqlAnnotationIssue.sarif => codeql/src/drivers/test/diff/InvalidFunctionPointerAnnotation.sarif (100%) rename src/drivers/test/diff/IrqlCancelRoutine.sarif => codeql/src/drivers/test/diff/IoInitializeTimerCall.sarif (100%) rename src/drivers/test/diff/IrqlFloatStateMismatch.sarif => codeql/src/drivers/test/diff/IrqTooHigh.sarif (100%) rename src/drivers/test/diff/IrqlFunctionNotAnnotated.sarif => codeql/src/drivers/test/diff/IrqTooLow.sarif (100%) rename src/drivers/test/diff/IrqlIllegalValue.sarif => codeql/src/drivers/test/diff/IrqlAnnotationIssue.sarif (100%) rename src/drivers/test/diff/IrqlInconsistentWithRequired.sarif => codeql/src/drivers/test/diff/IrqlCancelRoutine.sarif (100%) rename src/drivers/test/diff/IrqlLoweredImproperly.sarif => codeql/src/drivers/test/diff/IrqlFloatStateMismatch.sarif (100%) rename src/drivers/test/diff/KeSetEventIrql.sarif => codeql/src/drivers/test/diff/IrqlFunctionNotAnnotated.sarif (100%) rename src/drivers/test/diff/KeSetEventPageable.sarif => codeql/src/drivers/test/diff/IrqlIllegalValue.sarif (100%) rename src/drivers/test/diff/MultipleFunctionClassAnnotations.sarif => codeql/src/drivers/test/diff/IrqlInconsistentWithRequired.sarif (100%) rename src/drivers/test/diff/MultithreadedAVCondition.sarif => codeql/src/drivers/test/diff/IrqlLoweredImproperly.sarif (100%) rename src/drivers/test/diff/NtstatusExplicitCast.sarif => codeql/src/drivers/test/diff/IrqlNotSaved.sarif (100%) rename src/drivers/test/diff/NtstatusExplicitCast2.sarif => codeql/src/drivers/test/diff/IrqlNotUsed.sarif (100%) rename src/drivers/test/diff/NtstatusExplicitCast3.sarif => codeql/src/drivers/test/diff/IrqlSetTooHigh.sarif (100%) rename {src => codeql/src}/drivers/test/diff/IrqlSetTooLow.sarif (100%) rename src/drivers/test/diff/NullCharacterPointerAssignment.sarif => codeql/src/drivers/test/diff/IrqlTooHigh.sarif (100%) rename src/drivers/test/diff/ObReferenceMode.sarif => codeql/src/drivers/test/diff/IrqlTooLow.sarif (100%) rename src/drivers/test/diff/OperandAssignment.sarif => codeql/src/drivers/test/diff/KeSetEventIrql.sarif (100%) rename src/drivers/test/diff/PointerVariableSize.sarif => codeql/src/drivers/test/diff/KeSetEventPageable.sarif (100%) rename src/drivers/test/diff/PoolTagIntegral.sarif => codeql/src/drivers/test/diff/KeWaitLocal.sarif (100%) rename src/drivers/test/diff/RoutineFunctionTypeNotExpected.sarif => codeql/src/drivers/test/diff/MultipleFunctionClassAnnotations.sarif (100%) rename src/drivers/test/diff/StaticInitializer.sarif => codeql/src/drivers/test/diff/MultiplePagedCode.sarif (100%) rename src/drivers/test/diff/StrictTypeMatch.sarif => codeql/src/drivers/test/diff/MultithreadedAVCondition.sarif (100%) rename src/drivers/test/diff/UnsafeCallInGlobalInit.sarif => codeql/src/drivers/test/diff/NoPagedCode.sarif (100%) rename src/drivers/test/diff/WdkDeprecatedApis.sarif => codeql/src/drivers/test/diff/NoPagingSegment.sarif (100%) rename src/drivers/test/diff/IllegalFieldAccess2.sarif => codeql/src/drivers/test/diff/NtstatusExplicitCast.sarif (93%) rename src/drivers/test/diff/IllegalFieldWrite.sarif => codeql/src/drivers/test/diff/NtstatusExplicitCast2.sarif (93%) rename src/drivers/test/diff/ExaminedValue.sarif => codeql/src/drivers/test/diff/NtstatusExplicitCast3.sarif (93%) rename src/drivers/test/diff/IllegalFieldAccess.sarif => codeql/src/drivers/test/diff/NullCharacterPointerAssignment.sarif (93%) create mode 100644 codeql/src/drivers/test/diff/ObReferenceMode.sarif rename {src => codeql/src}/drivers/test/diff/OpaqueMdlUse.sarif (93%) rename {src => codeql/src}/drivers/test/diff/OpaqueMdlWrite.sarif (93%) create mode 100644 codeql/src/drivers/test/diff/OperandAssignment.sarif rename {src => codeql/src}/drivers/test/diff/PendingStatusError.sarif (93%) create mode 100644 codeql/src/drivers/test/diff/PointerVariableSize.sarif create mode 100644 codeql/src/drivers/test/diff/PoolTagIntegral.sarif rename {src => codeql/src}/drivers/test/diff/RoleTypeCorrectlyUsed.sarif (93%) create mode 100644 codeql/src/drivers/test/diff/RoutineFunctionTypeNotExpected.sarif create mode 100644 codeql/src/drivers/test/diff/StaticInitializer.sarif rename {src => codeql/src}/drivers/test/diff/StrSafe.sarif (93%) create mode 100644 codeql/src/drivers/test/diff/StrictTypeMatch.sarif rename {src => codeql/src}/drivers/test/diff/UnicodeStringFreed.sarif (93%) create mode 100644 codeql/src/drivers/test/diff/UnsafeCallInGlobalInit.sarif create mode 100644 codeql/src/drivers/test/diff/WdkDeprecatedApis.sarif rename {src => codeql/src}/drivers/test/diff/WrongDispatchTableAssignment.sarif (93%) rename {src => codeql/src}/drivers/test/dvl_tests/dvl_tests.ps1 (100%) rename {src => codeql/src}/drivers/test/dvl_tests/expected_results/clean_expected.sarif (100%) rename {src => codeql/src}/drivers/test/dvl_tests/expected_results/mustfix_expected.sarif (100%) rename {src => codeql/src}/drivers/test/requirements.txt (100%) rename {src => codeql/src}/drivers/wdm/libraries/Mdl.qll (100%) rename {src => codeql/src}/drivers/wdm/libraries/WdmDrivers.qll (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.qhelp (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.ql (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.sarif (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldAccess/driver_snippet.c (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.qhelp (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.ql (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.sarif (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldAccess2/driver_snippet.c (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.qhelp (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.ql (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.sarif (100%) rename {src => codeql/src}/drivers/wdm/queries/IllegalFieldWrite/driver_snippet.c (100%) rename {src => codeql/src}/drivers/wdm/queries/InconsistentDispatchAnnotations.ql (100%) rename {src => codeql/src}/drivers/wdm/queries/InitNotCleared/InitNotCleared.qhelp (100%) rename {src => codeql/src}/drivers/wdm/queries/InitNotCleared/InitNotCleared.ql (100%) rename {src => codeql/src}/drivers/wdm/queries/InitNotCleared/InitNotCleared.sarif (100%) rename {src => codeql/src}/drivers/wdm/queries/InitNotCleared/driver_snippet.c (100%) rename {src => codeql/src}/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.qhelp (100%) rename {src => codeql/src}/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.ql (97%) rename {src => codeql/src}/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.sarif (96%) rename {src => codeql/src}/drivers/wdm/queries/KeWaitLocal/driver_snippet.c (100%) rename {src => codeql/src}/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.qhelp (97%) rename {src => codeql/src}/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.ql (97%) rename {src => codeql/src}/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.sarif (97%) rename {src => codeql/src}/drivers/wdm/queries/MultiplePagedCode/driver_snippet.c (94%) rename {src => codeql/src}/drivers/wdm/queries/NoPagedCode/NoPagedCode.qhelp (96%) rename {src => codeql/src}/drivers/wdm/queries/NoPagedCode/NoPagedCode.ql (97%) rename {src => codeql/src}/drivers/wdm/queries/NoPagedCode/NoPagedCode.sarif (97%) rename {src => codeql/src}/drivers/wdm/queries/NoPagedCode/driver_snippet.c (94%) rename {src => codeql/src}/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.qhelp (97%) rename {src => codeql/src}/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.ql (97%) rename {src => codeql/src}/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.sarif (97%) rename {src => codeql/src}/drivers/wdm/queries/NoPagingSegment/driver_snippet.c (94%) rename {src => codeql/src}/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.qhelp (100%) rename {src => codeql/src}/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.ql (100%) rename {src => codeql/src}/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.sarif (100%) rename {src => codeql/src}/drivers/wdm/queries/ObReferenceMode/driver_snippet.c (100%) rename {src => codeql/src}/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.qhelp (100%) rename {src => codeql/src}/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.ql (100%) rename {src => codeql/src}/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.sarif (100%) rename {src => codeql/src}/drivers/wdm/queries/OpaqueMdlUse/driver_snippet.c (100%) rename {src => codeql/src}/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.qhelp (100%) rename {src => codeql/src}/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.ql (100%) rename {src => codeql/src}/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.sarif (100%) rename {src => codeql/src}/drivers/wdm/queries/OpaqueMdlWrite/driver_snippet.c (100%) rename {src => codeql/src}/drivers/wdm/queries/PendingStatusError/PendingStatusError.qhelp (100%) rename {src => codeql/src}/drivers/wdm/queries/PendingStatusError/PendingStatusError.ql (97%) rename {src => codeql/src}/drivers/wdm/queries/PendingStatusError/PendingStatusError.sarif (97%) rename {src => codeql/src}/drivers/wdm/queries/PendingStatusError/driver_snippet.c (95%) rename {src => codeql/src}/drivers/wdm/queries/README.md (98%) rename {src => codeql/src}/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.qhelp (97%) rename {src => codeql/src}/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.ql (97%) rename {src => codeql/src}/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.sarif (97%) rename {src => codeql/src}/drivers/wdm/queries/WrongDispatchTableAssignment/driver_snippet.c (95%) rename {src => codeql/src}/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.qhelp (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.ql (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosureBadCode.c (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosureGoodCode.c (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Conversion/BadOverflowGuard.qhelp (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Conversion/BadOverflowGuard.ql (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Conversion/BadOverflowGuardBadCode.c (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Conversion/BadOverflowGuardGoodCode.c (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Conversion/InfiniteLoop.qhelp (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Conversion/InfiniteLoop.ql (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Conversion/InfiniteLoopBadCode.c (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Conversion/InfiniteLoopGoodCode.c (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.qhelp (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.ql (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.qhelp (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.ql (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFreeLib.qhelp (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFreeLib.qll (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree_bad.c (100%) rename {src => codeql/src}/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree_good.c (100%) rename {src => codeql/src}/microsoft/Likely Bugs/UninitializedPtrField.qhelp (100%) rename {src => codeql/src}/microsoft/Likely Bugs/UninitializedPtrField.ql (100%) rename {src => codeql/src}/microsoft/Likely Bugs/UninitializedPtrFieldBadCode.c (100%) rename {src => codeql/src}/microsoft/Likely Bugs/UninitializedPtrFieldGoodCode.c (100%) rename {src => codeql/src}/microsoft/Security/CWE/CWE-704/WcharCharConversion.cpp (100%) rename {src => codeql/src}/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.qhelp (100%) rename {src => codeql/src}/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.ql (100%) rename {src => codeql/src}/microsoft/Security/Crytpography/HardcodedIVCNG.qhelp (100%) rename {src => codeql/src}/microsoft/Security/Crytpography/HardcodedIVCNG.ql (100%) rename {src => codeql/src}/microsoft/commons/Literals.qll (100%) rename {src => codeql/src}/microsoft/commons/MemoryAllocation.qll (100%) rename {src => codeql/src}/qlpack.yml (100%) rename {src => codeql/src}/windows-driver-suites/mustfix.qls (100%) rename {src => codeql/src}/windows-driver-suites/mustrun.qls (100%) rename {src => codeql/src}/windows-driver-suites/ported_driver_ca_checks.qls (100%) rename {src => codeql/src}/windows-driver-suites/recommended.qls (100%) delete mode 100644 src/drivers/test/diff/IrqlNotSaved.sarif delete mode 100644 src/drivers/test/diff/IrqlNotUsed.sarif delete mode 100644 src/drivers/test/diff/IrqlSetTooHigh.sarif delete mode 100644 src/drivers/test/diff/IrqlTooHigh.sarif delete mode 100644 src/drivers/test/diff/IrqlTooLow.sarif delete mode 100644 src/drivers/test/diff/KeWaitLocal.sarif delete mode 100644 src/drivers/test/diff/MultiplePagedCode.sarif delete mode 100644 src/drivers/test/diff/NoPagedCode.sarif delete mode 100644 src/drivers/test/diff/NoPagingSegment.sarif create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.projitems create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.shproj create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLCommand.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLExceptions.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptions.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsControl.xaml create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsControl.xaml.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsPage.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLInstallHelper.xaml create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLInstallHelper.xaml.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLPackage.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLRunner.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLService.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/ICodeQLGeneralOptions.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/InfoBar.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/InstallWindow.xaml create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/InstallWindow.xaml.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/License.txt create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/ProjectHelper.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/Resources.Designer.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/Resources.resx create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.sln create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/App.config create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/License.txt create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Properties/AssemblyInfo.cs create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/VSPackage.resx create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/icon.png create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/source.extension.vsixmanifest create mode 100644 tools/extensions/CodeQL.VisualStudio/LICENSE diff --git a/src/codeql-pack.lock.yml b/codeql/src/codeql-pack.lock.yml similarity index 100% rename from src/codeql-pack.lock.yml rename to codeql/src/codeql-pack.lock.yml diff --git a/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.qhelp b/codeql/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.qhelp similarity index 100% rename from src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.qhelp rename to codeql/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.qhelp diff --git a/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.ql b/codeql/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.ql similarity index 100% rename from src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.ql rename to codeql/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.ql diff --git a/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.sarif b/codeql/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.sarif similarity index 100% rename from src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.sarif rename to codeql/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/UnsafeCallInGlobalInit.sarif diff --git a/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/driver_snippet.c b/codeql/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/driver_snippet.c similarity index 100% rename from src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/driver_snippet.c rename to codeql/src/drivers/apps/queries/experimental/UnsafeCallInGlobalInit/driver_snippet.c diff --git a/src/drivers/general/DriverAlertSuppression.ql b/codeql/src/drivers/general/DriverAlertSuppression.ql similarity index 100% rename from src/drivers/general/DriverAlertSuppression.ql rename to codeql/src/drivers/general/DriverAlertSuppression.ql diff --git a/src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.qhelp b/codeql/src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.qhelp similarity index 100% rename from src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.qhelp rename to codeql/src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.qhelp diff --git a/src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.ql b/codeql/src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.ql similarity index 100% rename from src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.ql rename to codeql/src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.ql diff --git a/src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.sarif b/codeql/src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.sarif similarity index 100% rename from src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.sarif rename to codeql/src/drivers/general/queries/AnnotationSyntax/AnnotationSyntax.sarif diff --git a/src/drivers/general/queries/AnnotationSyntax/driver_snippet.c b/codeql/src/drivers/general/queries/AnnotationSyntax/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/AnnotationSyntax/driver_snippet.c rename to codeql/src/drivers/general/queries/AnnotationSyntax/driver_snippet.c diff --git a/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.qhelp b/codeql/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.qhelp similarity index 100% rename from src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.qhelp rename to codeql/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.qhelp diff --git a/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.ql b/codeql/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.ql similarity index 100% rename from src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.ql rename to codeql/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.ql diff --git a/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.sarif b/codeql/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.sarif similarity index 100% rename from src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.sarif rename to codeql/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/CurrentFunctionTypeNotCorrect.sarif diff --git a/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/driver_snippet.c b/codeql/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/CurrentFunctionTypeNotCorrect/driver_snippet.c rename to codeql/src/drivers/general/queries/CurrentFunctionTypeNotCorrect/driver_snippet.c diff --git a/src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.qhelp b/codeql/src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.qhelp similarity index 100% rename from src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.qhelp rename to codeql/src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.qhelp diff --git a/src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.ql b/codeql/src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.ql similarity index 100% rename from src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.ql rename to codeql/src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.ql diff --git a/src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.sarif b/codeql/src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.sarif similarity index 100% rename from src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.sarif rename to codeql/src/drivers/general/queries/DefaultPoolTag/DefaultPoolTag.sarif diff --git a/src/drivers/general/queries/DefaultPoolTag/driver_snippet.c b/codeql/src/drivers/general/queries/DefaultPoolTag/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/DefaultPoolTag/driver_snippet.c rename to codeql/src/drivers/general/queries/DefaultPoolTag/driver_snippet.c diff --git a/src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.qhelp b/codeql/src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.qhelp similarity index 100% rename from src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.qhelp rename to codeql/src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.qhelp diff --git a/src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.ql b/codeql/src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.ql similarity index 100% rename from src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.ql rename to codeql/src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.ql diff --git a/src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.sarif b/codeql/src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.sarif similarity index 100% rename from src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.sarif rename to codeql/src/drivers/general/queries/DriverEntrySaveBuffer/DriverEntrySaveBuffer.sarif diff --git a/src/drivers/general/queries/DriverEntrySaveBuffer/driver_snippet.c b/codeql/src/drivers/general/queries/DriverEntrySaveBuffer/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/DriverEntrySaveBuffer/driver_snippet.c rename to codeql/src/drivers/general/queries/DriverEntrySaveBuffer/driver_snippet.c diff --git a/src/drivers/general/queries/ExaminedValue/ExaminedValue.qhelp b/codeql/src/drivers/general/queries/ExaminedValue/ExaminedValue.qhelp similarity index 100% rename from src/drivers/general/queries/ExaminedValue/ExaminedValue.qhelp rename to codeql/src/drivers/general/queries/ExaminedValue/ExaminedValue.qhelp diff --git a/src/drivers/general/queries/ExaminedValue/ExaminedValue.ql b/codeql/src/drivers/general/queries/ExaminedValue/ExaminedValue.ql similarity index 100% rename from src/drivers/general/queries/ExaminedValue/ExaminedValue.ql rename to codeql/src/drivers/general/queries/ExaminedValue/ExaminedValue.ql diff --git a/src/drivers/general/queries/ExaminedValue/ExaminedValue.sarif b/codeql/src/drivers/general/queries/ExaminedValue/ExaminedValue.sarif similarity index 100% rename from src/drivers/general/queries/ExaminedValue/ExaminedValue.sarif rename to codeql/src/drivers/general/queries/ExaminedValue/ExaminedValue.sarif diff --git a/src/drivers/general/queries/ExaminedValue/driver_snippet.c b/codeql/src/drivers/general/queries/ExaminedValue/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/ExaminedValue/driver_snippet.c rename to codeql/src/drivers/general/queries/ExaminedValue/driver_snippet.c diff --git a/src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.qhelp b/codeql/src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.qhelp similarity index 100% rename from src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.qhelp rename to codeql/src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.qhelp diff --git a/src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.ql b/codeql/src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.ql similarity index 100% rename from src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.ql rename to codeql/src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.ql diff --git a/src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.sarif b/codeql/src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.sarif similarity index 97% rename from src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.sarif rename to codeql/src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.sarif index 295c092c..7ea7bf55 100644 --- a/src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.sarif +++ b/codeql/src/drivers/general/queries/ExtendedDeprecatedApis/ExtendedDeprecatedApis.sarif @@ -1,450 +1,450 @@ -{ - "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", - "version" : "2.1.0", - "runs" : [ { - "tool" : { - "driver" : { - "name" : "CodeQL", - "organization" : "GitHub", - "semanticVersion" : "2.11.5", - "rules" : [ { - "id" : "cpp/drivers/extended-deprecated-apis", - "name" : "cpp/drivers/extended-deprecated-apis", - "shortDescription" : { - "text" : "Use of deprecated function or macro (C28719, C28726, C28735, C28750)" - }, - "fullDescription" : { - "text" : "Use of deprecated APIs causes correctness or safety issues. This is a port of Code Analysis checks C28719, C28726, and C28750." - }, - "defaultConfiguration" : { - "enabled" : true, - "level" : "warning" - }, - "properties" : { - "tags" : [ "correctness", "security" ], - "description" : "Use of deprecated APIs causes correctness or safety issues. This is a port of Code Analysis checks C28719, C28726, and C28750.", - "feature.area" : "Multiple", - "id" : "cpp/drivers/extended-deprecated-apis", - "impact" : "Attack Surface Reduction", - "kind" : "problem", - "name" : "Use of deprecated function or macro (C28719, C28726, C28735, C28750)", - "opaqueid" : "CQLD-C28719", - "owner.email:" : "sdat@microsoft.com", - "platform" : "Desktop", - "precision" : "high", - "problem.severity" : "warning", - "query-version" : "v1", - "repro.text" : "The following code locations contain calls to an unsafe, deprecated function or macro.", - "scope" : "generic", - "security.severity" : "Low" - } - } ] - }, - "extensions" : [ { - "name" : "microsoft/windows-drivers", - "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", - "locations" : [ { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - }, { - "name" : "legacy-upgrades", - "semanticVersion" : "0.0.0", - "locations" : [ { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - } ] - }, - "artifacts" : [ { - "location" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - } ], - "results" : [ { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 37, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "82e29691df499d5d:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 40, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "a0f4009610bac07b:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 43, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "969c85f34783b0c9:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 46, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "35b38347e72e53ee:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 49, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "457c58a531c32719:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 53, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "23936499fc6ec6db:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 57, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "b8199b93e64f724c:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 60, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "67adf17cf52f9cb0:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 63, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "37878d516b970fae:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 66, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "d24a502aa610bd2e:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 69, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "6a27d42186f1df7d:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 72, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "af4c1b7ec005cdbe:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/extended-deprecated-apis", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/extended-deprecated-apis", - "index" : 0 - }, - "message" : { - "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 25, - "startColumn" : 5, - "endColumn" : 11 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "7b4677b91dfe9311:1", - "primaryLocationStartColumnFingerprint" : "0" - } - } ], - "columnKind" : "utf16CodeUnits", - "properties" : { - "semmle.formatSpecifier" : "sarifv2.1.0" - } - } ] +{ + "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", + "version" : "2.1.0", + "runs" : [ { + "tool" : { + "driver" : { + "name" : "CodeQL", + "organization" : "GitHub", + "semanticVersion" : "2.11.5", + "rules" : [ { + "id" : "cpp/drivers/extended-deprecated-apis", + "name" : "cpp/drivers/extended-deprecated-apis", + "shortDescription" : { + "text" : "Use of deprecated function or macro (C28719, C28726, C28735, C28750)" + }, + "fullDescription" : { + "text" : "Use of deprecated APIs causes correctness or safety issues. This is a port of Code Analysis checks C28719, C28726, and C28750." + }, + "defaultConfiguration" : { + "enabled" : true, + "level" : "warning" + }, + "properties" : { + "tags" : [ "correctness", "security" ], + "description" : "Use of deprecated APIs causes correctness or safety issues. This is a port of Code Analysis checks C28719, C28726, and C28750.", + "feature.area" : "Multiple", + "id" : "cpp/drivers/extended-deprecated-apis", + "impact" : "Attack Surface Reduction", + "kind" : "problem", + "name" : "Use of deprecated function or macro (C28719, C28726, C28735, C28750)", + "opaqueid" : "CQLD-C28719", + "owner.email:" : "sdat@microsoft.com", + "platform" : "Desktop", + "precision" : "high", + "problem.severity" : "warning", + "query-version" : "v1", + "repro.text" : "The following code locations contain calls to an unsafe, deprecated function or macro.", + "scope" : "generic", + "security.severity" : "Low" + } + } ] + }, + "extensions" : [ { + "name" : "microsoft/windows-drivers", + "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", + "locations" : [ { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + }, { + "name" : "legacy-upgrades", + "semanticVersion" : "0.0.0", + "locations" : [ { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + } ] + }, + "artifacts" : [ { + "location" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + } ], + "results" : [ { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 37, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "82e29691df499d5d:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 40, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "a0f4009610bac07b:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 43, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "969c85f34783b0c9:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 46, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "35b38347e72e53ee:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 49, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "457c58a531c32719:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 53, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "23936499fc6ec6db:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 57, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "b8199b93e64f724c:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 60, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "67adf17cf52f9cb0:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 63, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "37878d516b970fae:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 66, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "d24a502aa610bd2e:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 69, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "6a27d42186f1df7d:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 72, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "af4c1b7ec005cdbe:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/extended-deprecated-apis", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/extended-deprecated-apis", + "index" : 0 + }, + "message" : { + "text" : "strcpy is insecure and has been marked deprecated. Replace it with one of the following safe replacements: strcpy_s, StringCbCopy, StringCbCopyEx, StringCchCopy, StringCchCopyEx, strlcpy." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 25, + "startColumn" : 5, + "endColumn" : 11 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "7b4677b91dfe9311:1", + "primaryLocationStartColumnFingerprint" : "0" + } + } ], + "columnKind" : "utf16CodeUnits", + "properties" : { + "semmle.formatSpecifier" : "sarifv2.1.0" + } + } ] } \ No newline at end of file diff --git a/src/drivers/general/queries/ExtendedDeprecatedApis/driver_snippet.c b/codeql/src/drivers/general/queries/ExtendedDeprecatedApis/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/ExtendedDeprecatedApis/driver_snippet.c rename to codeql/src/drivers/general/queries/ExtendedDeprecatedApis/driver_snippet.c diff --git a/src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.qhelp b/codeql/src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.qhelp similarity index 100% rename from src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.qhelp rename to codeql/src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.qhelp diff --git a/src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.ql b/codeql/src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.ql similarity index 100% rename from src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.ql rename to codeql/src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.ql diff --git a/src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.sarif b/codeql/src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.sarif similarity index 100% rename from src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.sarif rename to codeql/src/drivers/general/queries/FloatHardwareStateProtection/FloatHardwareStateProtection.sarif diff --git a/src/drivers/general/queries/FloatHardwareStateProtection/driver_snippet.c b/codeql/src/drivers/general/queries/FloatHardwareStateProtection/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/FloatHardwareStateProtection/driver_snippet.c rename to codeql/src/drivers/general/queries/FloatHardwareStateProtection/driver_snippet.c diff --git a/src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.qhelp b/codeql/src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.qhelp similarity index 100% rename from src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.qhelp rename to codeql/src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.qhelp diff --git a/src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.ql b/codeql/src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.ql similarity index 100% rename from src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.ql rename to codeql/src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.ql diff --git a/src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.sarif b/codeql/src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.sarif similarity index 100% rename from src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.sarif rename to codeql/src/drivers/general/queries/IRPStackEntryCopy/IRPStackEntryCopy.sarif diff --git a/src/drivers/general/queries/IRPStackEntryCopy/driver_snippet.c b/codeql/src/drivers/general/queries/IRPStackEntryCopy/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IRPStackEntryCopy/driver_snippet.c rename to codeql/src/drivers/general/queries/IRPStackEntryCopy/driver_snippet.c diff --git a/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.qhelp b/codeql/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.qhelp similarity index 100% rename from src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.qhelp rename to codeql/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.qhelp diff --git a/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.ql b/codeql/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.ql similarity index 100% rename from src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.ql rename to codeql/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.ql diff --git a/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.sarif b/codeql/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.sarif similarity index 100% rename from src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.sarif rename to codeql/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/ImportantFunctionCallOptimizedOut.sarif diff --git a/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/driver_snippet.c b/codeql/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/ImportantFunctionCallOptimizedOut/driver_snippet.c rename to codeql/src/drivers/general/queries/ImportantFunctionCallOptimizedOut/driver_snippet.c diff --git a/src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.qhelp b/codeql/src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.qhelp similarity index 100% rename from src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.qhelp rename to codeql/src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.qhelp diff --git a/src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.ql b/codeql/src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.ql similarity index 100% rename from src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.ql rename to codeql/src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.ql diff --git a/src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.sarif b/codeql/src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.sarif similarity index 100% rename from src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.sarif rename to codeql/src/drivers/general/queries/ImproperNotOperatorOnZero/ImproperNotOperatorOnZero.sarif diff --git a/src/drivers/general/queries/ImproperNotOperatorOnZero/driver_snippet.c b/codeql/src/drivers/general/queries/ImproperNotOperatorOnZero/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/ImproperNotOperatorOnZero/driver_snippet.c rename to codeql/src/drivers/general/queries/ImproperNotOperatorOnZero/driver_snippet.c diff --git a/src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.qhelp b/codeql/src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.qhelp similarity index 100% rename from src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.qhelp rename to codeql/src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.qhelp diff --git a/src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.ql b/codeql/src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.ql similarity index 100% rename from src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.ql rename to codeql/src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.ql diff --git a/src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.sarif b/codeql/src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.sarif similarity index 100% rename from src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.sarif rename to codeql/src/drivers/general/queries/InvalidFunctionClassTypedef/InvalidFunctionClassTypedef.sarif diff --git a/src/drivers/general/queries/InvalidFunctionClassTypedef/driver_snippet.c b/codeql/src/drivers/general/queries/InvalidFunctionClassTypedef/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/InvalidFunctionClassTypedef/driver_snippet.c rename to codeql/src/drivers/general/queries/InvalidFunctionClassTypedef/driver_snippet.c diff --git a/src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.qhelp b/codeql/src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.qhelp similarity index 100% rename from src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.qhelp rename to codeql/src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.qhelp diff --git a/src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.ql b/codeql/src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.ql similarity index 100% rename from src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.ql rename to codeql/src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.ql diff --git a/src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.sarif b/codeql/src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.sarif similarity index 100% rename from src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.sarif rename to codeql/src/drivers/general/queries/InvalidFunctionPointerAnnotation/InvalidFunctionPointerAnnotation.sarif diff --git a/src/drivers/general/queries/InvalidFunctionPointerAnnotation/driver_snippet.c b/codeql/src/drivers/general/queries/InvalidFunctionPointerAnnotation/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/InvalidFunctionPointerAnnotation/driver_snippet.c rename to codeql/src/drivers/general/queries/InvalidFunctionPointerAnnotation/driver_snippet.c diff --git a/src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.qhelp b/codeql/src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.qhelp similarity index 100% rename from src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.qhelp rename to codeql/src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.qhelp diff --git a/src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.ql b/codeql/src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.ql similarity index 100% rename from src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.ql rename to codeql/src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.ql diff --git a/src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.sarif b/codeql/src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.sarif similarity index 100% rename from src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.sarif rename to codeql/src/drivers/general/queries/IoInitializeTimerCall/IoInitializeTimerCall.sarif diff --git a/src/drivers/general/queries/IoInitializeTimerCall/driver_snippet.c b/codeql/src/drivers/general/queries/IoInitializeTimerCall/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IoInitializeTimerCall/driver_snippet.c rename to codeql/src/drivers/general/queries/IoInitializeTimerCall/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.qhelp b/codeql/src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.qhelp rename to codeql/src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.qhelp diff --git a/src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.ql b/codeql/src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.ql similarity index 100% rename from src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.ql rename to codeql/src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.ql diff --git a/src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.sarif b/codeql/src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.sarif similarity index 100% rename from src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.sarif rename to codeql/src/drivers/general/queries/IrqlAnnotationIssue/IrqlAnnotationIssue.sarif diff --git a/src/drivers/general/queries/IrqlAnnotationIssue/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlAnnotationIssue/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlAnnotationIssue/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlAnnotationIssue/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.qhelp b/codeql/src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.qhelp rename to codeql/src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.qhelp diff --git a/src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.ql b/codeql/src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.ql similarity index 100% rename from src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.ql rename to codeql/src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.ql diff --git a/src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.sarif b/codeql/src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.sarif similarity index 100% rename from src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.sarif rename to codeql/src/drivers/general/queries/IrqlCancelRoutine/IrqlCancelRoutine.sarif diff --git a/src/drivers/general/queries/IrqlCancelRoutine/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlCancelRoutine/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlCancelRoutine/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlCancelRoutine/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.qhelp b/codeql/src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.qhelp rename to codeql/src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.qhelp diff --git a/src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.ql b/codeql/src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.ql similarity index 100% rename from src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.ql rename to codeql/src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.ql diff --git a/src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.sarif b/codeql/src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.sarif similarity index 100% rename from src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.sarif rename to codeql/src/drivers/general/queries/IrqlFloatStateMismatch/IrqlFloatStateMismatch.sarif diff --git a/src/drivers/general/queries/IrqlFloatStateMismatch/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlFloatStateMismatch/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlFloatStateMismatch/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlFloatStateMismatch/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.qhelp b/codeql/src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.qhelp rename to codeql/src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.qhelp diff --git a/src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.ql b/codeql/src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.ql similarity index 100% rename from src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.ql rename to codeql/src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.ql diff --git a/src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.sarif b/codeql/src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.sarif similarity index 100% rename from src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.sarif rename to codeql/src/drivers/general/queries/IrqlFunctionNotAnnotated/IrqlFunctionNotAnnotated.sarif diff --git a/src/drivers/general/queries/IrqlFunctionNotAnnotated/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlFunctionNotAnnotated/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlFunctionNotAnnotated/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlFunctionNotAnnotated/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.qhelp b/codeql/src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.qhelp rename to codeql/src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.qhelp diff --git a/src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.ql b/codeql/src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.ql similarity index 100% rename from src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.ql rename to codeql/src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.ql diff --git a/src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.sarif b/codeql/src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.sarif similarity index 100% rename from src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.sarif rename to codeql/src/drivers/general/queries/IrqlIllegalValue/IrqlIllegalValue.sarif diff --git a/src/drivers/general/queries/IrqlIllegalValue/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlIllegalValue/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlIllegalValue/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlIllegalValue/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.qhelp b/codeql/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.qhelp rename to codeql/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.qhelp diff --git a/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.ql b/codeql/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.ql similarity index 100% rename from src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.ql rename to codeql/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.ql diff --git a/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.sarif b/codeql/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.sarif similarity index 100% rename from src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.sarif rename to codeql/src/drivers/general/queries/IrqlInconsistentWithRequired/IrqlInconsistentWithRequired.sarif diff --git a/src/drivers/general/queries/IrqlInconsistentWithRequired/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlInconsistentWithRequired/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlInconsistentWithRequired/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlInconsistentWithRequired/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.qhelp b/codeql/src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.qhelp rename to codeql/src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.qhelp diff --git a/src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.ql b/codeql/src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.ql similarity index 100% rename from src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.ql rename to codeql/src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.ql diff --git a/src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.sarif b/codeql/src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.sarif similarity index 100% rename from src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.sarif rename to codeql/src/drivers/general/queries/IrqlLoweredImproperly/IrqlLoweredImproperly.sarif diff --git a/src/drivers/general/queries/IrqlLoweredImproperly/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlLoweredImproperly/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlLoweredImproperly/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlLoweredImproperly/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.qhelp b/codeql/src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.qhelp rename to codeql/src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.qhelp diff --git a/src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.ql b/codeql/src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.ql similarity index 100% rename from src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.ql rename to codeql/src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.ql diff --git a/src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.sarif b/codeql/src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.sarif similarity index 100% rename from src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.sarif rename to codeql/src/drivers/general/queries/IrqlNotSaved/IrqlNotSaved.sarif diff --git a/src/drivers/general/queries/IrqlNotSaved/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlNotSaved/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlNotSaved/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlNotSaved/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.qhelp b/codeql/src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.qhelp rename to codeql/src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.qhelp diff --git a/src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.ql b/codeql/src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.ql similarity index 100% rename from src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.ql rename to codeql/src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.ql diff --git a/src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.sarif b/codeql/src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.sarif similarity index 100% rename from src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.sarif rename to codeql/src/drivers/general/queries/IrqlNotUsed/IrqlNotUsed.sarif diff --git a/src/drivers/general/queries/IrqlNotUsed/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlNotUsed/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlNotUsed/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlNotUsed/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.qhelp b/codeql/src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.qhelp rename to codeql/src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.qhelp diff --git a/src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.ql b/codeql/src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.ql similarity index 100% rename from src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.ql rename to codeql/src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.ql diff --git a/src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.sarif b/codeql/src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.sarif similarity index 100% rename from src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.sarif rename to codeql/src/drivers/general/queries/IrqlSetTooHigh/IrqlSetTooHigh.sarif diff --git a/src/drivers/general/queries/IrqlSetTooHigh/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlSetTooHigh/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlSetTooHigh/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlSetTooHigh/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.qhelp b/codeql/src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.qhelp rename to codeql/src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.qhelp diff --git a/src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.ql b/codeql/src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.ql similarity index 100% rename from src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.ql rename to codeql/src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.ql diff --git a/src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.sarif b/codeql/src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.sarif similarity index 100% rename from src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.sarif rename to codeql/src/drivers/general/queries/IrqlSetTooLow/IrqlSetTooLow.sarif diff --git a/src/drivers/general/queries/IrqlSetTooLow/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlSetTooLow/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlSetTooLow/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlSetTooLow/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.qhelp b/codeql/src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.qhelp rename to codeql/src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.qhelp diff --git a/src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.ql b/codeql/src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.ql similarity index 100% rename from src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.ql rename to codeql/src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.ql diff --git a/src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.sarif b/codeql/src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.sarif similarity index 100% rename from src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.sarif rename to codeql/src/drivers/general/queries/IrqlTooHigh/IrqlTooHigh.sarif diff --git a/src/drivers/general/queries/IrqlTooHigh/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlTooHigh/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlTooHigh/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlTooHigh/driver_snippet.c diff --git a/src/drivers/general/queries/IrqlTooLow/IrqlTooLow.qhelp b/codeql/src/drivers/general/queries/IrqlTooLow/IrqlTooLow.qhelp similarity index 100% rename from src/drivers/general/queries/IrqlTooLow/IrqlTooLow.qhelp rename to codeql/src/drivers/general/queries/IrqlTooLow/IrqlTooLow.qhelp diff --git a/src/drivers/general/queries/IrqlTooLow/IrqlTooLow.ql b/codeql/src/drivers/general/queries/IrqlTooLow/IrqlTooLow.ql similarity index 100% rename from src/drivers/general/queries/IrqlTooLow/IrqlTooLow.ql rename to codeql/src/drivers/general/queries/IrqlTooLow/IrqlTooLow.ql diff --git a/src/drivers/general/queries/IrqlTooLow/IrqlTooLow.sarif b/codeql/src/drivers/general/queries/IrqlTooLow/IrqlTooLow.sarif similarity index 100% rename from src/drivers/general/queries/IrqlTooLow/IrqlTooLow.sarif rename to codeql/src/drivers/general/queries/IrqlTooLow/IrqlTooLow.sarif diff --git a/src/drivers/general/queries/IrqlTooLow/driver_snippet.c b/codeql/src/drivers/general/queries/IrqlTooLow/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/IrqlTooLow/driver_snippet.c rename to codeql/src/drivers/general/queries/IrqlTooLow/driver_snippet.c diff --git a/src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.qhelp b/codeql/src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.qhelp similarity index 100% rename from src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.qhelp rename to codeql/src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.qhelp diff --git a/src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.ql b/codeql/src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.ql similarity index 100% rename from src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.ql rename to codeql/src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.ql diff --git a/src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.sarif b/codeql/src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.sarif similarity index 100% rename from src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.sarif rename to codeql/src/drivers/general/queries/KeSetEventPageable/KeSetEventPageable.sarif diff --git a/src/drivers/general/queries/KeSetEventPageable/driver_snippet.c b/codeql/src/drivers/general/queries/KeSetEventPageable/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/KeSetEventPageable/driver_snippet.c rename to codeql/src/drivers/general/queries/KeSetEventPageable/driver_snippet.c diff --git a/src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.qhelp b/codeql/src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.qhelp similarity index 100% rename from src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.qhelp rename to codeql/src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.qhelp diff --git a/src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.ql b/codeql/src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.ql similarity index 100% rename from src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.ql rename to codeql/src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.ql diff --git a/src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.sarif b/codeql/src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.sarif similarity index 100% rename from src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.sarif rename to codeql/src/drivers/general/queries/MultipleFunctionClassAnnotations/MultipleFunctionClassAnnotations.sarif diff --git a/src/drivers/general/queries/MultipleFunctionClassAnnotations/driver_snippet.c b/codeql/src/drivers/general/queries/MultipleFunctionClassAnnotations/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/MultipleFunctionClassAnnotations/driver_snippet.c rename to codeql/src/drivers/general/queries/MultipleFunctionClassAnnotations/driver_snippet.c diff --git a/src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.qhelp b/codeql/src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.qhelp similarity index 100% rename from src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.qhelp rename to codeql/src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.qhelp diff --git a/src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.ql b/codeql/src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.ql similarity index 100% rename from src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.ql rename to codeql/src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.ql diff --git a/src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.sarif b/codeql/src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.sarif similarity index 100% rename from src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.sarif rename to codeql/src/drivers/general/queries/MultithreadedAVCondition/MultithreadedAVCondition.sarif diff --git a/src/drivers/general/queries/MultithreadedAVCondition/driver_snippet.cpp b/codeql/src/drivers/general/queries/MultithreadedAVCondition/driver_snippet.cpp similarity index 100% rename from src/drivers/general/queries/MultithreadedAVCondition/driver_snippet.cpp rename to codeql/src/drivers/general/queries/MultithreadedAVCondition/driver_snippet.cpp diff --git a/src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.qhelp b/codeql/src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.qhelp similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.qhelp rename to codeql/src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.qhelp diff --git a/src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.ql b/codeql/src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.ql similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.ql rename to codeql/src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.ql diff --git a/src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.sarif b/codeql/src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.sarif similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.sarif rename to codeql/src/drivers/general/queries/NtstatusExplicitCast/NtstatusExplicitCast.sarif diff --git a/src/drivers/general/queries/NtstatusExplicitCast/driver_snippet.c b/codeql/src/drivers/general/queries/NtstatusExplicitCast/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast/driver_snippet.c rename to codeql/src/drivers/general/queries/NtstatusExplicitCast/driver_snippet.c diff --git a/src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.qhelp b/codeql/src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.qhelp similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.qhelp rename to codeql/src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.qhelp diff --git a/src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.ql b/codeql/src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.ql similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.ql rename to codeql/src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.ql diff --git a/src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.sarif b/codeql/src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.sarif similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.sarif rename to codeql/src/drivers/general/queries/NtstatusExplicitCast2/NtstatusExplicitCast2.sarif diff --git a/src/drivers/general/queries/NtstatusExplicitCast2/driver_snippet.c b/codeql/src/drivers/general/queries/NtstatusExplicitCast2/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast2/driver_snippet.c rename to codeql/src/drivers/general/queries/NtstatusExplicitCast2/driver_snippet.c diff --git a/src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.qhelp b/codeql/src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.qhelp similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.qhelp rename to codeql/src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.qhelp diff --git a/src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.ql b/codeql/src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.ql similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.ql rename to codeql/src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.ql diff --git a/src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.sarif b/codeql/src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.sarif similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.sarif rename to codeql/src/drivers/general/queries/NtstatusExplicitCast3/NtstatusExplicitCast3.sarif diff --git a/src/drivers/general/queries/NtstatusExplicitCast3/driver_snippet.c b/codeql/src/drivers/general/queries/NtstatusExplicitCast3/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/NtstatusExplicitCast3/driver_snippet.c rename to codeql/src/drivers/general/queries/NtstatusExplicitCast3/driver_snippet.c diff --git a/src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.qhelp b/codeql/src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.qhelp similarity index 100% rename from src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.qhelp rename to codeql/src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.qhelp diff --git a/src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.ql b/codeql/src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.ql similarity index 100% rename from src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.ql rename to codeql/src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.ql diff --git a/src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.sarif b/codeql/src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.sarif similarity index 100% rename from src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.sarif rename to codeql/src/drivers/general/queries/NullCharacterPointerAssignment/NullCharacterPointerAssignment.sarif diff --git a/src/drivers/general/queries/NullCharacterPointerAssignment/driver_snippet.c b/codeql/src/drivers/general/queries/NullCharacterPointerAssignment/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/NullCharacterPointerAssignment/driver_snippet.c rename to codeql/src/drivers/general/queries/NullCharacterPointerAssignment/driver_snippet.c diff --git a/src/drivers/general/queries/OperandAssignment/OperandAssignment.qhelp b/codeql/src/drivers/general/queries/OperandAssignment/OperandAssignment.qhelp similarity index 100% rename from src/drivers/general/queries/OperandAssignment/OperandAssignment.qhelp rename to codeql/src/drivers/general/queries/OperandAssignment/OperandAssignment.qhelp diff --git a/src/drivers/general/queries/OperandAssignment/OperandAssignment.ql b/codeql/src/drivers/general/queries/OperandAssignment/OperandAssignment.ql similarity index 100% rename from src/drivers/general/queries/OperandAssignment/OperandAssignment.ql rename to codeql/src/drivers/general/queries/OperandAssignment/OperandAssignment.ql diff --git a/src/drivers/general/queries/OperandAssignment/OperandAssignment.sarif b/codeql/src/drivers/general/queries/OperandAssignment/OperandAssignment.sarif similarity index 100% rename from src/drivers/general/queries/OperandAssignment/OperandAssignment.sarif rename to codeql/src/drivers/general/queries/OperandAssignment/OperandAssignment.sarif diff --git a/src/drivers/general/queries/OperandAssignment/driver_snippet.c b/codeql/src/drivers/general/queries/OperandAssignment/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/OperandAssignment/driver_snippet.c rename to codeql/src/drivers/general/queries/OperandAssignment/driver_snippet.c diff --git a/src/drivers/general/queries/PointerVariableSize/PointerVariableSize.qhelp b/codeql/src/drivers/general/queries/PointerVariableSize/PointerVariableSize.qhelp similarity index 100% rename from src/drivers/general/queries/PointerVariableSize/PointerVariableSize.qhelp rename to codeql/src/drivers/general/queries/PointerVariableSize/PointerVariableSize.qhelp diff --git a/src/drivers/general/queries/PointerVariableSize/PointerVariableSize.ql b/codeql/src/drivers/general/queries/PointerVariableSize/PointerVariableSize.ql similarity index 100% rename from src/drivers/general/queries/PointerVariableSize/PointerVariableSize.ql rename to codeql/src/drivers/general/queries/PointerVariableSize/PointerVariableSize.ql diff --git a/src/drivers/general/queries/PointerVariableSize/PointerVariableSize.sarif b/codeql/src/drivers/general/queries/PointerVariableSize/PointerVariableSize.sarif similarity index 100% rename from src/drivers/general/queries/PointerVariableSize/PointerVariableSize.sarif rename to codeql/src/drivers/general/queries/PointerVariableSize/PointerVariableSize.sarif diff --git a/src/drivers/general/queries/PointerVariableSize/driver_snippet.c b/codeql/src/drivers/general/queries/PointerVariableSize/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/PointerVariableSize/driver_snippet.c rename to codeql/src/drivers/general/queries/PointerVariableSize/driver_snippet.c diff --git a/src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.qhelp b/codeql/src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.qhelp similarity index 100% rename from src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.qhelp rename to codeql/src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.qhelp diff --git a/src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.ql b/codeql/src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.ql similarity index 100% rename from src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.ql rename to codeql/src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.ql diff --git a/src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.sarif b/codeql/src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.sarif similarity index 100% rename from src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.sarif rename to codeql/src/drivers/general/queries/PoolTagIntegral/PoolTagIntegral.sarif diff --git a/src/drivers/general/queries/PoolTagIntegral/driver_snippet.c b/codeql/src/drivers/general/queries/PoolTagIntegral/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/PoolTagIntegral/driver_snippet.c rename to codeql/src/drivers/general/queries/PoolTagIntegral/driver_snippet.c diff --git a/src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.qhelp b/codeql/src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.qhelp similarity index 100% rename from src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.qhelp rename to codeql/src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.qhelp diff --git a/src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.ql b/codeql/src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.ql similarity index 100% rename from src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.ql rename to codeql/src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.ql diff --git a/src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.sarif b/codeql/src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.sarif similarity index 96% rename from src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.sarif rename to codeql/src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.sarif index aab47630..e696dab2 100644 --- a/src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.sarif +++ b/codeql/src/drivers/general/queries/RoleTypeCorrectlyUsed/RoleTypeCorrectlyUsed.sarif @@ -1,200 +1,200 @@ -{ - "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", - "version" : "2.1.0", - "runs" : [ { - "tool" : { - "driver" : { - "name" : "CodeQL", - "organization" : "GitHub", - "semanticVersion" : "2.15.4", - "notifications" : [ { - "id" : "cpp/baseline/expected-extracted-files", - "name" : "cpp/baseline/expected-extracted-files", - "shortDescription" : { - "text" : "Expected extracted files" - }, - "fullDescription" : { - "text" : "Files appearing in the source archive that are expected to be extracted." - }, - "defaultConfiguration" : { - "enabled" : true - }, - "properties" : { - "tags" : [ "expected-extracted-files", "telemetry" ] - } - } ], - "rules" : [ { - "id" : "cpp/drivers/role-type-correctly-used", - "name" : "cpp/drivers/role-type-correctly-used", - "shortDescription" : { - "text" : "Incorrect Role Type Use" - }, - "fullDescription" : { - "text" : "A function is declared with a role type but used as an argument in a function that expects a different role type for that argument." - }, - "defaultConfiguration" : { - "enabled" : true, - "level" : "warning" - }, - "properties" : { - "tags" : [ "correctness" ], - "description" : "A function is declared with a role type but used as an argument in a function that expects a different role type for that argument.", - "feature.area" : "Multiple", - "id" : "cpp/drivers/role-type-correctly-used", - "impact" : "Insecure Coding Practice", - "kind" : "problem", - "name" : "Incorrect Role Type Use", - "opaqueid" : "CQLD-D0007", - "owner.email:" : "sdat@microsoft.com", - "platform" : "Desktop", - "precision" : "medium", - "problem.severity" : "warning", - "query-version" : "v2", - "repro.text" : "", - "scope" : "domainspecific" - } - } ] - }, - "extensions" : [ { - "name" : "microsoft/windows-drivers", - "semanticVersion" : "1.1.0+2affc3c634804dac7504a483a378cc9ba22a0f0b", - "locations" : [ { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - } ] - }, - "invocations" : [ { - "toolExecutionNotifications" : [ { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 1 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - }, { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - }, { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/fail_driver1.h", - "uriBaseId" : "%SRCROOT%", - "index" : 2 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - } ], - "executionSuccessful" : true - } ], - "artifacts" : [ { - "location" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - }, { - "location" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 1 - } - }, { - "location" : { - "uri" : "driver/fail_driver1.h", - "uriBaseId" : "%SRCROOT%", - "index" : 2 - } - } ], - "results" : [ { - "ruleId" : "cpp/drivers/role-type-correctly-used", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/role-type-correctly-used", - "index" : 0 - }, - "message" : { - "text" : "Function BadUnload declared with role type but role type DRIVER_UNLOAD is expected." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 38, - "startColumn" : 34, - "endColumn" : 43 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "9b23495b84787ea7:1", - "primaryLocationStartColumnFingerprint" : "29" - } - } ], - "columnKind" : "utf16CodeUnits", - "properties" : { - "semmle.formatSpecifier" : "sarifv2.1.0" - } - } ] +{ + "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", + "version" : "2.1.0", + "runs" : [ { + "tool" : { + "driver" : { + "name" : "CodeQL", + "organization" : "GitHub", + "semanticVersion" : "2.15.4", + "notifications" : [ { + "id" : "cpp/baseline/expected-extracted-files", + "name" : "cpp/baseline/expected-extracted-files", + "shortDescription" : { + "text" : "Expected extracted files" + }, + "fullDescription" : { + "text" : "Files appearing in the source archive that are expected to be extracted." + }, + "defaultConfiguration" : { + "enabled" : true + }, + "properties" : { + "tags" : [ "expected-extracted-files", "telemetry" ] + } + } ], + "rules" : [ { + "id" : "cpp/drivers/role-type-correctly-used", + "name" : "cpp/drivers/role-type-correctly-used", + "shortDescription" : { + "text" : "Incorrect Role Type Use" + }, + "fullDescription" : { + "text" : "A function is declared with a role type but used as an argument in a function that expects a different role type for that argument." + }, + "defaultConfiguration" : { + "enabled" : true, + "level" : "warning" + }, + "properties" : { + "tags" : [ "correctness" ], + "description" : "A function is declared with a role type but used as an argument in a function that expects a different role type for that argument.", + "feature.area" : "Multiple", + "id" : "cpp/drivers/role-type-correctly-used", + "impact" : "Insecure Coding Practice", + "kind" : "problem", + "name" : "Incorrect Role Type Use", + "opaqueid" : "CQLD-D0007", + "owner.email:" : "sdat@microsoft.com", + "platform" : "Desktop", + "precision" : "medium", + "problem.severity" : "warning", + "query-version" : "v2", + "repro.text" : "", + "scope" : "domainspecific" + } + } ] + }, + "extensions" : [ { + "name" : "microsoft/windows-drivers", + "semanticVersion" : "1.1.0+2affc3c634804dac7504a483a378cc9ba22a0f0b", + "locations" : [ { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + } ] + }, + "invocations" : [ { + "toolExecutionNotifications" : [ { + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/fail_driver1.c", + "uriBaseId" : "%SRCROOT%", + "index" : 1 + } + } + } ], + "message" : { + "text" : "" + }, + "level" : "none", + "descriptor" : { + "id" : "cpp/baseline/expected-extracted-files", + "index" : 0 + }, + "properties" : { + "formattedMessage" : { + "text" : "" + } + } + }, { + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + } + } ], + "message" : { + "text" : "" + }, + "level" : "none", + "descriptor" : { + "id" : "cpp/baseline/expected-extracted-files", + "index" : 0 + }, + "properties" : { + "formattedMessage" : { + "text" : "" + } + } + }, { + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/fail_driver1.h", + "uriBaseId" : "%SRCROOT%", + "index" : 2 + } + } + } ], + "message" : { + "text" : "" + }, + "level" : "none", + "descriptor" : { + "id" : "cpp/baseline/expected-extracted-files", + "index" : 0 + }, + "properties" : { + "formattedMessage" : { + "text" : "" + } + } + } ], + "executionSuccessful" : true + } ], + "artifacts" : [ { + "location" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + }, { + "location" : { + "uri" : "driver/fail_driver1.c", + "uriBaseId" : "%SRCROOT%", + "index" : 1 + } + }, { + "location" : { + "uri" : "driver/fail_driver1.h", + "uriBaseId" : "%SRCROOT%", + "index" : 2 + } + } ], + "results" : [ { + "ruleId" : "cpp/drivers/role-type-correctly-used", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/role-type-correctly-used", + "index" : 0 + }, + "message" : { + "text" : "Function BadUnload declared with role type but role type DRIVER_UNLOAD is expected." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 38, + "startColumn" : 34, + "endColumn" : 43 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "9b23495b84787ea7:1", + "primaryLocationStartColumnFingerprint" : "29" + } + } ], + "columnKind" : "utf16CodeUnits", + "properties" : { + "semmle.formatSpecifier" : "sarifv2.1.0" + } + } ] } \ No newline at end of file diff --git a/src/drivers/general/queries/RoleTypeCorrectlyUsed/driver_snippet.c b/codeql/src/drivers/general/queries/RoleTypeCorrectlyUsed/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/RoleTypeCorrectlyUsed/driver_snippet.c rename to codeql/src/drivers/general/queries/RoleTypeCorrectlyUsed/driver_snippet.c diff --git a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.qhelp b/codeql/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.qhelp similarity index 100% rename from src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.qhelp rename to codeql/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.qhelp diff --git a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.ql b/codeql/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.ql similarity index 100% rename from src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.ql rename to codeql/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.ql diff --git a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.sarif b/codeql/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.sarif similarity index 96% rename from src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.sarif rename to codeql/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.sarif index 7ea811e5..a2fba07e 100644 --- a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.sarif +++ b/codeql/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.sarif @@ -1,413 +1,413 @@ -{ - "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", - "version" : "2.1.0", - "runs" : [ { - "tool" : { - "driver" : { - "name" : "CodeQL", - "organization" : "GitHub", - "semanticVersion" : "2.15.4", - "notifications" : [ { - "id" : "cpp/baseline/expected-extracted-files", - "name" : "cpp/baseline/expected-extracted-files", - "shortDescription" : { - "text" : "Expected extracted files" - }, - "fullDescription" : { - "text" : "Files appearing in the source archive that are expected to be extracted." - }, - "defaultConfiguration" : { - "enabled" : true - }, - "properties" : { - "tags" : [ "expected-extracted-files", "telemetry" ] - } - } ], - "rules" : [ { - "id" : "cpp/drivers/routine-function-type-not-expected", - "name" : "cpp/drivers/routine-function-type-not-expected", - "shortDescription" : { - "text" : "Unexpected function return type for routine (C28127)" - }, - "fullDescription" : { - "text" : "The function being used as a routine does not exactly match the type expected." - }, - "defaultConfiguration" : { - "enabled" : true, - "level" : "warning" - }, - "properties" : { - "tags" : [ "correctness", "wddst" ], - "description" : "The function being used as a routine does not exactly match the type expected.", - "feature.area" : "Multiple", - "id" : "cpp/drivers/routine-function-type-not-expected", - "impact" : "Attack Surface Reduction", - "kind" : "problem", - "name" : "Unexpected function return type for routine (C28127)", - "opaqueid" : "CQLD-C28127", - "owner.email" : "sdat@microsoft.com", - "platform" : "Desktop", - "precision" : "high", - "problem.severity" : "warning", - "query-version" : "v2", - "repro.text" : "The following code locations use a function pointer with a return type that does not match the expected type", - "scope" : "domainspecific", - "security.severity" : "Low" - } - } ] - }, - "extensions" : [ { - "name" : "microsoft/windows-drivers", - "semanticVersion" : "1.0.12+7ade7ce2ebcb754809ebf7d2d9801d5d76167d5b", - "locations" : [ { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - } ] - }, - "invocations" : [ { - "toolExecutionNotifications" : [ { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - }, { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 1 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - }, { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/fail_driver1.h", - "uriBaseId" : "%SRCROOT%", - "index" : 2 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - } ], - "executionSuccessful" : true - } ], - "artifacts" : [ { - "location" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - }, { - "location" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 1 - } - }, { - "location" : { - "uri" : "driver/fail_driver1.h", - "uriBaseId" : "%SRCROOT%", - "index" : 2 - } - } ], - "results" : [ { - "ruleId" : "cpp/drivers/routine-function-type-not-expected", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/routine-function-type-not-expected", - "index" : 0 - }, - "message" : { - "text" : "Function call [call to functionCallThatUsesFunctionPointer](1) passes in a function pointer [intFunctionToCall](2) for parameter [functionPointer](3), but the function signature of the provided function does not match what is expected: return type mismatch: expected: void, actual: int" - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 92, - "startColumn" : 5, - "endColumn" : 40 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "3156b91ec348a1bb:1", - "primaryLocationStartColumnFingerprint" : "0" - }, - "relatedLocations" : [ { - "id" : 1, - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 92, - "startColumn" : 5, - "endColumn" : 40 - } - }, - "message" : { - "text" : "call to functionCallThatUsesFunctionPointer" - } - }, { - "id" : 2, - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 38, - "startColumn" : 5, - "endColumn" : 22 - } - }, - "message" : { - "text" : "intFunctionToCall" - } - }, { - "id" : 3, - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 50, - "startColumn" : 51, - "endColumn" : 66 - } - }, - "message" : { - "text" : "functionPointer" - } - } ] - }, { - "ruleId" : "cpp/drivers/routine-function-type-not-expected", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/routine-function-type-not-expected", - "index" : 0 - }, - "message" : { - "text" : "Function call [call to functionCallThatUsesFunctionPointer2](1) passes in a function pointer [intFunctionToCall](2) for parameter [functionPointer](3), but the function signature of the provided function does not match what is expected: return type mismatch: expected: void, actual: int" - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 96, - "startColumn" : 5, - "endColumn" : 41 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "b2e192116459028c:1", - "primaryLocationStartColumnFingerprint" : "0" - }, - "relatedLocations" : [ { - "id" : 1, - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 96, - "startColumn" : 5, - "endColumn" : 41 - } - }, - "message" : { - "text" : "call to functionCallThatUsesFunctionPointer2" - } - }, { - "id" : 2, - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 38, - "startColumn" : 5, - "endColumn" : 22 - } - }, - "message" : { - "text" : "intFunctionToCall" - } - }, { - "id" : 3, - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 55, - "startColumn" : 60, - "endColumn" : 75 - } - }, - "message" : { - "text" : "functionPointer" - } - } ] - }, { - "ruleId" : "cpp/drivers/routine-function-type-not-expected", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/routine-function-type-not-expected", - "index" : 0 - }, - "message" : { - "text" : "Function call [call to functionCallThatUsesFunctionPointer3](1) passes in a function pointer [voidFunctionToCall](2) for parameter [functionPointer](3), but the function signature of the provided function does not match what is expected: parameter count mismatch: expected: 3 parameters, actual: 0 parameters" - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 105, - "startColumn" : 5, - "endColumn" : 41 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "69e17f41c5580c20:1", - "primaryLocationStartColumnFingerprint" : "0" - }, - "relatedLocations" : [ { - "id" : 1, - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 105, - "startColumn" : 5, - "endColumn" : 41 - } - }, - "message" : { - "text" : "call to functionCallThatUsesFunctionPointer3" - } - }, { - "id" : 2, - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 29, - "startColumn" : 6, - "endColumn" : 24 - } - }, - "message" : { - "text" : "voidFunctionToCall" - } - }, { - "id" : 3, - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 66, - "startColumn" : 53, - "endColumn" : 68 - } - }, - "message" : { - "text" : "functionPointer" - } - } ] - } ], - "columnKind" : "utf16CodeUnits", - "properties" : { - "semmle.formatSpecifier" : "sarifv2.1.0" - } - } ] +{ + "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", + "version" : "2.1.0", + "runs" : [ { + "tool" : { + "driver" : { + "name" : "CodeQL", + "organization" : "GitHub", + "semanticVersion" : "2.15.4", + "notifications" : [ { + "id" : "cpp/baseline/expected-extracted-files", + "name" : "cpp/baseline/expected-extracted-files", + "shortDescription" : { + "text" : "Expected extracted files" + }, + "fullDescription" : { + "text" : "Files appearing in the source archive that are expected to be extracted." + }, + "defaultConfiguration" : { + "enabled" : true + }, + "properties" : { + "tags" : [ "expected-extracted-files", "telemetry" ] + } + } ], + "rules" : [ { + "id" : "cpp/drivers/routine-function-type-not-expected", + "name" : "cpp/drivers/routine-function-type-not-expected", + "shortDescription" : { + "text" : "Unexpected function return type for routine (C28127)" + }, + "fullDescription" : { + "text" : "The function being used as a routine does not exactly match the type expected." + }, + "defaultConfiguration" : { + "enabled" : true, + "level" : "warning" + }, + "properties" : { + "tags" : [ "correctness", "wddst" ], + "description" : "The function being used as a routine does not exactly match the type expected.", + "feature.area" : "Multiple", + "id" : "cpp/drivers/routine-function-type-not-expected", + "impact" : "Attack Surface Reduction", + "kind" : "problem", + "name" : "Unexpected function return type for routine (C28127)", + "opaqueid" : "CQLD-C28127", + "owner.email" : "sdat@microsoft.com", + "platform" : "Desktop", + "precision" : "high", + "problem.severity" : "warning", + "query-version" : "v2", + "repro.text" : "The following code locations use a function pointer with a return type that does not match the expected type", + "scope" : "domainspecific", + "security.severity" : "Low" + } + } ] + }, + "extensions" : [ { + "name" : "microsoft/windows-drivers", + "semanticVersion" : "1.0.12+7ade7ce2ebcb754809ebf7d2d9801d5d76167d5b", + "locations" : [ { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + } ] + }, + "invocations" : [ { + "toolExecutionNotifications" : [ { + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + } + } ], + "message" : { + "text" : "" + }, + "level" : "none", + "descriptor" : { + "id" : "cpp/baseline/expected-extracted-files", + "index" : 0 + }, + "properties" : { + "formattedMessage" : { + "text" : "" + } + } + }, { + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/fail_driver1.c", + "uriBaseId" : "%SRCROOT%", + "index" : 1 + } + } + } ], + "message" : { + "text" : "" + }, + "level" : "none", + "descriptor" : { + "id" : "cpp/baseline/expected-extracted-files", + "index" : 0 + }, + "properties" : { + "formattedMessage" : { + "text" : "" + } + } + }, { + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/fail_driver1.h", + "uriBaseId" : "%SRCROOT%", + "index" : 2 + } + } + } ], + "message" : { + "text" : "" + }, + "level" : "none", + "descriptor" : { + "id" : "cpp/baseline/expected-extracted-files", + "index" : 0 + }, + "properties" : { + "formattedMessage" : { + "text" : "" + } + } + } ], + "executionSuccessful" : true + } ], + "artifacts" : [ { + "location" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + }, { + "location" : { + "uri" : "driver/fail_driver1.c", + "uriBaseId" : "%SRCROOT%", + "index" : 1 + } + }, { + "location" : { + "uri" : "driver/fail_driver1.h", + "uriBaseId" : "%SRCROOT%", + "index" : 2 + } + } ], + "results" : [ { + "ruleId" : "cpp/drivers/routine-function-type-not-expected", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/routine-function-type-not-expected", + "index" : 0 + }, + "message" : { + "text" : "Function call [call to functionCallThatUsesFunctionPointer](1) passes in a function pointer [intFunctionToCall](2) for parameter [functionPointer](3), but the function signature of the provided function does not match what is expected: return type mismatch: expected: void, actual: int" + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 92, + "startColumn" : 5, + "endColumn" : 40 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "3156b91ec348a1bb:1", + "primaryLocationStartColumnFingerprint" : "0" + }, + "relatedLocations" : [ { + "id" : 1, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 92, + "startColumn" : 5, + "endColumn" : 40 + } + }, + "message" : { + "text" : "call to functionCallThatUsesFunctionPointer" + } + }, { + "id" : 2, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 38, + "startColumn" : 5, + "endColumn" : 22 + } + }, + "message" : { + "text" : "intFunctionToCall" + } + }, { + "id" : 3, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 50, + "startColumn" : 51, + "endColumn" : 66 + } + }, + "message" : { + "text" : "functionPointer" + } + } ] + }, { + "ruleId" : "cpp/drivers/routine-function-type-not-expected", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/routine-function-type-not-expected", + "index" : 0 + }, + "message" : { + "text" : "Function call [call to functionCallThatUsesFunctionPointer2](1) passes in a function pointer [intFunctionToCall](2) for parameter [functionPointer](3), but the function signature of the provided function does not match what is expected: return type mismatch: expected: void, actual: int" + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 96, + "startColumn" : 5, + "endColumn" : 41 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "b2e192116459028c:1", + "primaryLocationStartColumnFingerprint" : "0" + }, + "relatedLocations" : [ { + "id" : 1, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 96, + "startColumn" : 5, + "endColumn" : 41 + } + }, + "message" : { + "text" : "call to functionCallThatUsesFunctionPointer2" + } + }, { + "id" : 2, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 38, + "startColumn" : 5, + "endColumn" : 22 + } + }, + "message" : { + "text" : "intFunctionToCall" + } + }, { + "id" : 3, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 55, + "startColumn" : 60, + "endColumn" : 75 + } + }, + "message" : { + "text" : "functionPointer" + } + } ] + }, { + "ruleId" : "cpp/drivers/routine-function-type-not-expected", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/routine-function-type-not-expected", + "index" : 0 + }, + "message" : { + "text" : "Function call [call to functionCallThatUsesFunctionPointer3](1) passes in a function pointer [voidFunctionToCall](2) for parameter [functionPointer](3), but the function signature of the provided function does not match what is expected: parameter count mismatch: expected: 3 parameters, actual: 0 parameters" + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 105, + "startColumn" : 5, + "endColumn" : 41 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "69e17f41c5580c20:1", + "primaryLocationStartColumnFingerprint" : "0" + }, + "relatedLocations" : [ { + "id" : 1, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 105, + "startColumn" : 5, + "endColumn" : 41 + } + }, + "message" : { + "text" : "call to functionCallThatUsesFunctionPointer3" + } + }, { + "id" : 2, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 29, + "startColumn" : 6, + "endColumn" : 24 + } + }, + "message" : { + "text" : "voidFunctionToCall" + } + }, { + "id" : 3, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 66, + "startColumn" : 53, + "endColumn" : 68 + } + }, + "message" : { + "text" : "functionPointer" + } + } ] + } ], + "columnKind" : "utf16CodeUnits", + "properties" : { + "semmle.formatSpecifier" : "sarifv2.1.0" + } + } ] } \ No newline at end of file diff --git a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/driver_snippet.c b/codeql/src/drivers/general/queries/RoutineFunctionTypeNotExpected/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/RoutineFunctionTypeNotExpected/driver_snippet.c rename to codeql/src/drivers/general/queries/RoutineFunctionTypeNotExpected/driver_snippet.c diff --git a/src/drivers/general/queries/StaticInitializer/StaticInitializer.qhelp b/codeql/src/drivers/general/queries/StaticInitializer/StaticInitializer.qhelp similarity index 100% rename from src/drivers/general/queries/StaticInitializer/StaticInitializer.qhelp rename to codeql/src/drivers/general/queries/StaticInitializer/StaticInitializer.qhelp diff --git a/src/drivers/general/queries/StaticInitializer/StaticInitializer.ql b/codeql/src/drivers/general/queries/StaticInitializer/StaticInitializer.ql similarity index 100% rename from src/drivers/general/queries/StaticInitializer/StaticInitializer.ql rename to codeql/src/drivers/general/queries/StaticInitializer/StaticInitializer.ql diff --git a/src/drivers/general/queries/StaticInitializer/StaticInitializer.sarif b/codeql/src/drivers/general/queries/StaticInitializer/StaticInitializer.sarif similarity index 100% rename from src/drivers/general/queries/StaticInitializer/StaticInitializer.sarif rename to codeql/src/drivers/general/queries/StaticInitializer/StaticInitializer.sarif diff --git a/src/drivers/general/queries/StaticInitializer/driver_snippet.cpp b/codeql/src/drivers/general/queries/StaticInitializer/driver_snippet.cpp similarity index 100% rename from src/drivers/general/queries/StaticInitializer/driver_snippet.cpp rename to codeql/src/drivers/general/queries/StaticInitializer/driver_snippet.cpp diff --git a/src/drivers/general/queries/StrSafe/StrSafe.qhelp b/codeql/src/drivers/general/queries/StrSafe/StrSafe.qhelp similarity index 100% rename from src/drivers/general/queries/StrSafe/StrSafe.qhelp rename to codeql/src/drivers/general/queries/StrSafe/StrSafe.qhelp diff --git a/src/drivers/general/queries/StrSafe/StrSafe.ql b/codeql/src/drivers/general/queries/StrSafe/StrSafe.ql similarity index 100% rename from src/drivers/general/queries/StrSafe/StrSafe.ql rename to codeql/src/drivers/general/queries/StrSafe/StrSafe.ql diff --git a/src/drivers/general/queries/StrSafe/StrSafe.sarif b/codeql/src/drivers/general/queries/StrSafe/StrSafe.sarif similarity index 100% rename from src/drivers/general/queries/StrSafe/StrSafe.sarif rename to codeql/src/drivers/general/queries/StrSafe/StrSafe.sarif diff --git a/src/drivers/general/queries/StrSafe/driver_snippet.c b/codeql/src/drivers/general/queries/StrSafe/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/StrSafe/driver_snippet.c rename to codeql/src/drivers/general/queries/StrSafe/driver_snippet.c diff --git a/src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.qhelp b/codeql/src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.qhelp similarity index 100% rename from src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.qhelp rename to codeql/src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.qhelp diff --git a/src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.ql b/codeql/src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.ql similarity index 100% rename from src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.ql rename to codeql/src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.ql diff --git a/src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.sarif b/codeql/src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.sarif similarity index 100% rename from src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.sarif rename to codeql/src/drivers/general/queries/StrictTypeMatch/StrictTypeMatch.sarif diff --git a/src/drivers/general/queries/StrictTypeMatch/driver_snippet.c b/codeql/src/drivers/general/queries/StrictTypeMatch/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/StrictTypeMatch/driver_snippet.c rename to codeql/src/drivers/general/queries/StrictTypeMatch/driver_snippet.c diff --git a/src/drivers/general/queries/WdkDeprecatedApis/WdkDeprecatedApis.sarif b/codeql/src/drivers/general/queries/WdkDeprecatedApis/WdkDeprecatedApis.sarif similarity index 100% rename from src/drivers/general/queries/WdkDeprecatedApis/WdkDeprecatedApis.sarif rename to codeql/src/drivers/general/queries/WdkDeprecatedApis/WdkDeprecatedApis.sarif diff --git a/src/drivers/general/queries/WdkDeprecatedApis/driver_snippet.c b/codeql/src/drivers/general/queries/WdkDeprecatedApis/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/WdkDeprecatedApis/driver_snippet.c rename to codeql/src/drivers/general/queries/WdkDeprecatedApis/driver_snippet.c diff --git a/src/drivers/general/queries/WdkDeprecatedApis/wdk-deprecated-api.qhelp b/codeql/src/drivers/general/queries/WdkDeprecatedApis/wdk-deprecated-api.qhelp similarity index 100% rename from src/drivers/general/queries/WdkDeprecatedApis/wdk-deprecated-api.qhelp rename to codeql/src/drivers/general/queries/WdkDeprecatedApis/wdk-deprecated-api.qhelp diff --git a/src/drivers/general/queries/WdkDeprecatedApis/wdk-deprecated-api.ql b/codeql/src/drivers/general/queries/WdkDeprecatedApis/wdk-deprecated-api.ql similarity index 100% rename from src/drivers/general/queries/WdkDeprecatedApis/wdk-deprecated-api.ql rename to codeql/src/drivers/general/queries/WdkDeprecatedApis/wdk-deprecated-api.ql diff --git a/src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.qhelp b/codeql/src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.qhelp similarity index 100% rename from src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.qhelp rename to codeql/src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.qhelp diff --git a/src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.ql b/codeql/src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.ql similarity index 100% rename from src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.ql rename to codeql/src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.ql diff --git a/src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.sarif b/codeql/src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.sarif similarity index 100% rename from src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.sarif rename to codeql/src/drivers/general/queries/experimental/DefaultPoolTagExtended/DefaultPoolTagExtended.sarif diff --git a/src/drivers/general/queries/experimental/DefaultPoolTagExtended/driver_snippet.c b/codeql/src/drivers/general/queries/experimental/DefaultPoolTagExtended/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/experimental/DefaultPoolTagExtended/driver_snippet.c rename to codeql/src/drivers/general/queries/experimental/DefaultPoolTagExtended/driver_snippet.c diff --git a/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.qhelp b/codeql/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.qhelp similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.qhelp rename to codeql/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.qhelp diff --git a/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.ql b/codeql/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.ql similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.ql rename to codeql/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.ql diff --git a/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.sarif b/codeql/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.sarif similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.sarif rename to codeql/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/DriverIsolationRtlViolation.sarif diff --git a/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/driver_snippet.c b/codeql/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationRtlViolation/driver_snippet.c rename to codeql/src/drivers/general/queries/experimental/DriverIsolationRtlViolation/driver_snippet.c diff --git a/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.qhelp b/codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.qhelp similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.qhelp rename to codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.qhelp diff --git a/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.ql b/codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.ql similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.ql rename to codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.ql diff --git a/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.sarif b/codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.sarif similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.sarif rename to codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/DriverIsolationZwViolation1.sarif diff --git a/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/driver_snippet.c b/codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationZwViolation1/driver_snippet.c rename to codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation1/driver_snippet.c diff --git a/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.qhelp b/codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.qhelp similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.qhelp rename to codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.qhelp diff --git a/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.ql b/codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.ql similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.ql rename to codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.ql diff --git a/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.sarif b/codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.sarif similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.sarif rename to codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/DriverIsolationZwViolation2.sarif diff --git a/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/driver_snippet.c b/codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/experimental/DriverIsolationZwViolation2/driver_snippet.c rename to codeql/src/drivers/general/queries/experimental/DriverIsolationZwViolation2/driver_snippet.c diff --git a/src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.qhelp b/codeql/src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.qhelp similarity index 100% rename from src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.qhelp rename to codeql/src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.qhelp diff --git a/src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.ql b/codeql/src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.ql similarity index 100% rename from src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.ql rename to codeql/src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.ql diff --git a/src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.sarif b/codeql/src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.sarif similarity index 100% rename from src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.sarif rename to codeql/src/drivers/general/queries/experimental/KeSetEventIrql/KeSetEventIrql.sarif diff --git a/src/drivers/general/queries/experimental/KeSetEventIrql/driver_snippet.c b/codeql/src/drivers/general/queries/experimental/KeSetEventIrql/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/experimental/KeSetEventIrql/driver_snippet.c rename to codeql/src/drivers/general/queries/experimental/KeSetEventIrql/driver_snippet.c diff --git a/src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.qhelp b/codeql/src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.qhelp similarity index 100% rename from src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.qhelp rename to codeql/src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.qhelp diff --git a/src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.ql b/codeql/src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.ql similarity index 100% rename from src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.ql rename to codeql/src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.ql diff --git a/src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.sarif b/codeql/src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.sarif similarity index 100% rename from src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.sarif rename to codeql/src/drivers/general/queries/experimental/UnicodeStringFreed/UnicodeStringFreed.sarif diff --git a/src/drivers/general/queries/experimental/UnicodeStringFreed/driver_snippet.c b/codeql/src/drivers/general/queries/experimental/UnicodeStringFreed/driver_snippet.c similarity index 100% rename from src/drivers/general/queries/experimental/UnicodeStringFreed/driver_snippet.c rename to codeql/src/drivers/general/queries/experimental/UnicodeStringFreed/driver_snippet.c diff --git a/src/drivers/kmdf/libraries/KmdfDrivers.qll b/codeql/src/drivers/kmdf/libraries/KmdfDrivers.qll similarity index 97% rename from src/drivers/kmdf/libraries/KmdfDrivers.qll rename to codeql/src/drivers/kmdf/libraries/KmdfDrivers.qll index 0c47e2fd..eee58774 100644 --- a/src/drivers/kmdf/libraries/KmdfDrivers.qll +++ b/codeql/src/drivers/kmdf/libraries/KmdfDrivers.qll @@ -1,1002 +1,1002 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -import cpp - -/** - * A KMDF Typedef type. This class is incomplete. It is used to represent a TypedefType in the KMDF library. - */ -class KmdfRoleTypeType extends TypedefType { - /* Callbacks */ - KmdfRoleTypeType() { - - this.getName().matches("EVT_WDF_CHILD_LIST_CREATE_DEVICE") or - this.getName().matches("EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN") or - this.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COPY") or - this.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE") or - this.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE") or - this.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_CLEANUP") or - this.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_COPY") or - this.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_DUPLICATE") or - this.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_CLEANUP") or - this.getName().matches("EVT_WDF_CHILD_LIST_DEVICE_REENUMERATED") or - this.getName().matches("EVT_WDF_DEVICE_SHUTDOWN_NOTIFICATION") or - this.getName().matches("EVT_WDF_DEVICE_FILE_CREATE") or - this.getName().matches("EVT_WDF_FILE_CLOSE") or - this.getName().matches("EVT_WDF_FILE_CLEANUP") or - this.getName().matches("EVT_WDF_DEVICE_PNP_STATE_CHANGE_NOTIFICATION") or - this.getName().matches("EVT_WDF_DEVICE_POWER_STATE_CHANGE_NOTIFICATION") or - this.getName().matches("EVT_WDF_DEVICE_POWER_POLICY_STATE_CHANGE_NOTIFICATION") or - this.getName().matches("EVT_WDF_DEVICE_D0_ENTRY") or - this.getName().matches("EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED") or - this.getName().matches("EVT_WDF_DEVICE_D0_ENTRY_POST_HARDWARE_ENABLED") or - this.getName().matches("EVT_WDF_DEVICE_D0_EXIT") or - this.getName().matches("EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED") or - this.getName().matches("EVT_WDF_DEVICE_D0_EXIT_PRE_HARDWARE_DISABLED") or - this.getName().matches("EVT_WDF_DEVICE_PREPARE_HARDWARE") or - this.getName().matches("EVT_WDF_DEVICE_RELEASE_HARDWARE") or - this.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP") or - this.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_FLUSH") or - this.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT") or - this.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_SUSPEND") or - this.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_RESTART") or - this.getName().matches("EVT_WDF_DEVICE_QUERY_STOP") or - this.getName().matches("EVT_WDF_DEVICE_QUERY_REMOVE") or - this.getName().matches("EVT_WDF_DEVICE_SURPRISE_REMOVAL") or - this.getName().matches("EVT_WDF_DEVICE_USAGE_NOTIFICATION") or - this.getName().matches("EVT_WDF_DEVICE_USAGE_NOTIFICATION_EX") or - this.getName().matches("EVT_WDF_DEVICE_RELATIONS_QUERY") or - this.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_S0") or - this.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_SX") or - this.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_SX_WITH_REASON") or - this.getName().matches("EVT_WDF_DEVICE_DISARM_WAKE_FROM_S0") or - this.getName().matches("EVT_WDF_DEVICE_DISARM_WAKE_FROM_SX") or - this.getName().matches("EVT_WDF_DEVICE_WAKE_FROM_S0_TRIGGERED") or - this.getName().matches("EVT_WDF_DEVICE_WAKE_FROM_SX_TRIGGERED") or - this.getName().matches("EVT_WDFDEVICE_WDM_IRP_PREPROCESS") or - this.getName().matches("EVT_WDFDEVICE_WDM_IRP_DISPATCH") or - this.getName().matches("EVT_WDF_IO_IN_CALLER_CONTEXT") or - this.getName().matches("EVT_WDFDEVICE_WDM_POST_PO_FX_REGISTER_DEVICE") or - this.getName().matches("EVT_WDFDEVICE_WDM_PRE_PO_FX_UNREGISTER_DEVICE") or - this.getName().matches("EVT_WDF_DMA_ENABLER_FILL") or - this.getName().matches("EVT_WDF_DMA_ENABLER_FLUSH") or - this.getName().matches("EVT_WDF_DMA_ENABLER_ENABLE") or - this.getName().matches("EVT_WDF_DMA_ENABLER_DISABLE") or - this.getName().matches("EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_START") or - this.getName().matches("EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_STOP") or - this.getName().matches("EVT_WDF_PROGRAM_DMA") or - this.getName().matches("EVT_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL") or - this.getName().matches("EVT_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE") or - this.getName().matches("EVT_WDF_RESERVE_DMA") or - this.getName().matches("EVT_WDF_DPC") or - this.getName().matches("EVT_WDF_DRIVER_DEVICE_ADD") or - this.getName().matches("EVT_WDF_DRIVER_UNLOAD") or - this.getName().matches("EVT_WDF_TRACE_CALLBACK") or - this.getName().matches("EVT_WDF_DEVICE_FILTER_RESOURCE_REQUIREMENTS") or - this.getName().matches("EVT_WDF_DEVICE_REMOVE_ADDED_RESOURCES") or - this.getName().matches("EVT_WDF_INTERRUPT_ISR") or - this.getName().matches("EVT_WDF_INTERRUPT_SYNCHRONIZE") or - this.getName().matches("EVT_WDF_INTERRUPT_DPC") or - this.getName().matches("EVT_WDF_INTERRUPT_WORKITEM") or - this.getName().matches("EVT_WDF_INTERRUPT_ENABLE") or - this.getName().matches("EVT_WDF_INTERRUPT_DISABLE") or - this.getName().matches("EVT_WDF_IO_QUEUE_IO_DEFAULT") or - this.getName().matches("EVT_WDF_IO_QUEUE_IO_STOP") or - this.getName().matches("EVT_WDF_IO_QUEUE_IO_RESUME") or - this.getName().matches("EVT_WDF_IO_QUEUE_IO_READ") or - this.getName().matches("EVT_WDF_IO_QUEUE_IO_WRITE") or - this.getName().matches("EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL") or - this.getName().matches("EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL") or - this.getName().matches("EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE") or - this.getName().matches("EVT_WDF_IO_QUEUE_STATE") or - this.getName().matches("EVT_WDF_IO_ALLOCATE_RESOURCES_FOR_RESERVED_REQUEST") or - this.getName().matches("EVT_WDF_IO_ALLOCATE_REQUEST_RESOURCES") or - this.getName().matches("EVT_WDF_IO_WDM_IRP_FOR_FORWARD_PROGRESS") or - this.getName().matches("EVT_WDF_IO_TARGET_QUERY_REMOVE") or - this.getName().matches("EVT_WDF_IO_TARGET_REMOVE_CANCELED") or - this.getName().matches("EVT_WDF_IO_TARGET_REMOVE_COMPLETE") or - this.getName().matches("EVT_WDF_%_CONTEXT_CLEANUP%") or - this.getName().matches("EVT_WDF_%_CONTEXT_DESTROY%") or - this.getName().matches("EVT_WDF_DEVICE_RESOURCES_QUERY") or - this.getName().matches("EVT_WDF_DEVICE_RESOURCE_REQUIREMENTS_QUERY") or - this.getName().matches("EVT_WDF_DEVICE_EJECT") or - this.getName().matches("EVT_WDF_DEVICE_SET_LOCK") or - this.getName().matches("EVT_WDF_DEVICE_ENABLE_WAKE_AT_BUS") or - this.getName().matches("EVT_WDF_DEVICE_DISABLE_WAKE_AT_BUS") or - this.getName().matches("EVT_WDF_DEVICE_REPORTED_MISSING") or - this.getName().matches("EVT_WDF_DEVICE_PROCESS_QUERY_INTERFACE_REQUEST") or - this.getName().matches("EVT_WDF_REQUEST_CANCEL") or - this.getName().matches("EVT_WDF_REQUEST_COMPLETION_ROUTINE") or - this.getName().matches("EVT_WDF_TIMER") or - this.getName().matches("EVT_WDF_USB_READER_COMPLETION_ROUTINE") or - this.getName().matches("EVT_WDF_USB_READERS_FAILED") or - this.getName().matches("EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE") or - this.getName().matches("EVT_WDF_WMI_INSTANCE_SET_INSTANCE") or - this.getName().matches("EVT_WDF_WMI_INSTANCE_SET_ITEM") or - this.getName().matches("EVT_WDF_WMI_INSTANCE_EXECUTE_METHOD") or - this.getName().matches("EVT_WDF_WMI_PROVIDER_FUNCTION_CONTROL") or - this.getName().matches("EVT_WDF_WORKITEM") - - } -} - -class KmdfCallbackRoutineTypedef extends KmdfRoleTypeType { - KmdfCallbackRoutineTypedef() { this.getFile().getBaseName().matches("%wdf%.h") } -} - -/* Callbacks */ -class KmdfEVTWdfChildListCreateDevice extends KmdfCallbackRoutine { - KmdfEVTWdfChildListCreateDevice() { - callbackType.getName().matches("EVT_WDF_CHILD_LIST_CREATE_DEVICE") - } -} - -class KmdfEVTWdfChildListScanForChildren extends KmdfCallbackRoutine { - KmdfEVTWdfChildListScanForChildren() { - callbackType.getName().matches("EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN") - } -} - -class KmdfEVTWdfChildListIdentificationDescriptionCopy extends KmdfCallbackRoutine { - KmdfEVTWdfChildListIdentificationDescriptionCopy() { - callbackType.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COPY") - } -} - -class KmdfEVTWdfChildListIdentificationDescriptionDuplicate extends KmdfCallbackRoutine { - KmdfEVTWdfChildListIdentificationDescriptionDuplicate() { - callbackType.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE") - } -} - -class KmdfEVTWdfChildListIdentificationDescriptionCompare extends KmdfCallbackRoutine { - KmdfEVTWdfChildListIdentificationDescriptionCompare() { - callbackType.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE") - } -} - -class KmdfEVTWdfChildListIdentificationDescriptionCleanup extends KmdfCallbackRoutine { - KmdfEVTWdfChildListIdentificationDescriptionCleanup() { - callbackType.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_CLEANUP") - } -} - -class KmdfEVTWdfChildListAddressDescriptionCopy extends KmdfCallbackRoutine { - KmdfEVTWdfChildListAddressDescriptionCopy() { - callbackType.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_COPY") - } -} - -class KmdfEVTWdfChildListAddressDescriptionDuplicate extends KmdfCallbackRoutine { - KmdfEVTWdfChildListAddressDescriptionDuplicate() { - callbackType.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_DUPLICATE") - } -} - -class KmdfEVTWdfChildListAddressDescriptionCleanup extends KmdfCallbackRoutine { - KmdfEVTWdfChildListAddressDescriptionCleanup() { - callbackType.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_CLEANUP") - } -} - -class KmdfEVTWdfChildListDeviceReenumerated extends KmdfCallbackRoutine { - KmdfEVTWdfChildListDeviceReenumerated() { - callbackType.getName().matches("EVT_WDF_CHILD_LIST_DEVICE_REENUMERATED") - } -} - -class KmdfEVTWdfDeviceShutdownNotification extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceShutdownNotification() { - callbackType.getName().matches("EVT_WDF_DEVICE_SHUTDOWN_NOTIFICATION") - } -} - -class KmdfEVTWdfDeviceFileCreate extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceFileCreate() { callbackType.getName().matches("EVT_WDF_DEVICE_FILE_CREATE") } -} - -class KmdfEVTWdfFileClose extends KmdfCallbackRoutine { - KmdfEVTWdfFileClose() { callbackType.getName().matches("EVT_WDF_FILE_CLOSE") } -} - -class KmdfEVTWdfFileCleanup extends KmdfCallbackRoutine { - KmdfEVTWdfFileCleanup() { callbackType.getName().matches("EVT_WDF_FILE_CLEANUP") } -} - -class KmdfEVTWdfDevicePnpStateChangeNotification extends KmdfCallbackRoutine { - KmdfEVTWdfDevicePnpStateChangeNotification() { - callbackType.getName().matches("EVT_WDF_DEVICE_PNP_STATE_CHANGE_NOTIFICATION") - } -} - -class KmdfEVTWdfDevicePowerStateChangeNotification extends KmdfCallbackRoutine { - KmdfEVTWdfDevicePowerStateChangeNotification() { - callbackType.getName().matches("EVT_WDF_DEVICE_POWER_STATE_CHANGE_NOTIFICATION") - } -} - -class KmdfEVTWdfDevicePowerPolicyStateChangeNotification extends KmdfCallbackRoutine { - KmdfEVTWdfDevicePowerPolicyStateChangeNotification() { - callbackType.getName().matches("EVT_WDF_DEVICE_POWER_POLICY_STATE_CHANGE_NOTIFICATION") - } -} - -class KmdfEVTWdfDeviceD0Entry extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceD0Entry() { callbackType.getName().matches("EVT_WDF_DEVICE_D0_ENTRY") } -} - -class KmdfEVTWdfDeviceD0EntryPostInterruptsEnabled extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceD0EntryPostInterruptsEnabled() { - callbackType.getName().matches("EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED") - } -} - -class KmdfEVTWdfDeviceD0EntryPostHardwareEnabled extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceD0EntryPostHardwareEnabled() { - callbackType.getName().matches("EVT_WDF_DEVICE_D0_ENTRY_POST_HARDWARE_ENABLED") - } -} - -class KmdfEVTWdfDeviceD0Exit extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceD0Exit() { callbackType.getName().matches("EVT_WDF_DEVICE_D0_EXIT") } -} - -class KmdfEVTWdfDeviceD0ExitPreInterruptsDisabled extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceD0ExitPreInterruptsDisabled() { - callbackType.getName().matches("EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED") - } -} - -class KmdfEVTWdfDeviceD0ExitPreHardwareDisabled extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceD0ExitPreHardwareDisabled() { - callbackType.getName().matches("EVT_WDF_DEVICE_D0_EXIT_PRE_HARDWARE_DISABLED") - } -} - -class KmdfEVTWdfDevicePrepareHardware extends KmdfCallbackRoutine { - KmdfEVTWdfDevicePrepareHardware() { - callbackType.getName().matches("EVT_WDF_DEVICE_PREPARE_HARDWARE") - } -} - -class KmdfEVTWdfDeviceReleaseHardware extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceReleaseHardware() { - callbackType.getName().matches("EVT_WDF_DEVICE_RELEASE_HARDWARE") - } -} - -class KmdfEVTWdfDeviceSelfManagedIoCleanup extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceSelfManagedIoCleanup() { - callbackType.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP") - } -} - -class KmdfEVTWdfDeviceSelfManagedIoFlush extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceSelfManagedIoFlush() { - callbackType.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_FLUSH") - } -} - -class KmdfEVTWdfDeviceSelfManagedIoInit extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceSelfManagedIoInit() { - callbackType.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT") - } -} - -class KmdfEVTWdfDeviceSelfManagedIoSuspend extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceSelfManagedIoSuspend() { - callbackType.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_SUSPEND") - } -} - -class KmdfEVTWdfDeviceSelfManagedIoRestart extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceSelfManagedIoRestart() { - callbackType.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_RESTART") - } -} - -class KmdfEVTWdfDeviceQueryStop extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceQueryStop() { callbackType.getName().matches("EVT_WDF_DEVICE_QUERY_STOP") } -} - -class KmdfEVTWdfDeviceQueryRemove extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceQueryRemove() { callbackType.getName().matches("EVT_WDF_DEVICE_QUERY_REMOVE") } -} - -class KmdfEVTWdfDeviceSurpriseRemoval extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceSurpriseRemoval() { - callbackType.getName().matches("EVT_WDF_DEVICE_SURPRISE_REMOVAL") - } -} - -class KmdfEVTWdfDeviceUsageNotification extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceUsageNotification() { - callbackType.getName().matches("EVT_WDF_DEVICE_USAGE_NOTIFICATION") - } -} - -class KmdfEVTWdfDeviceUsageNotificationEx extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceUsageNotificationEx() { - callbackType.getName().matches("EVT_WDF_DEVICE_USAGE_NOTIFICATION_EX") - } -} - -class KmdfEVTWdfDeviceRelationsQuery extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceRelationsQuery() { - callbackType.getName().matches("EVT_WDF_DEVICE_RELATIONS_QUERY") - } -} - -class KmdfEVTWdfDeviceArmWakeFromS0 extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceArmWakeFromS0() { - callbackType.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_S0") - } -} - -class KmdfEVTWdfDeviceArmWakeFromSx extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceArmWakeFromSx() { - callbackType.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_SX") - } -} - -class KmdfEVTWdfDeviceArmWakeFromSxWithReason extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceArmWakeFromSxWithReason() { - callbackType.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_SX_WITH_REASON") - } -} - -class KmdfEVTWdfDeviceDisarmWakeFromS0 extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceDisarmWakeFromS0() { - callbackType.getName().matches("EVT_WDF_DEVICE_DISARM_WAKE_FROM_S0") - } -} - -class KmdfEVTWdfDeviceDisarmWakeFromSx extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceDisarmWakeFromSx() { - callbackType.getName().matches("EVT_WDF_DEVICE_DISARM_WAKE_FROM_SX") - } -} - -class KmdfEVTWdfDeviceWakeFromS0Triggered extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceWakeFromS0Triggered() { - callbackType.getName().matches("EVT_WDF_DEVICE_WAKE_FROM_S0_TRIGGERED") - } -} - -class KmdfEVTWdfDeviceWakeFromSxTriggered extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceWakeFromSxTriggered() { - callbackType.getName().matches("EVT_WDF_DEVICE_WAKE_FROM_SX_TRIGGERED") - } -} - -class KmdfEVTWdfdeviceWdmIrpPreprocess extends KmdfCallbackRoutine { - KmdfEVTWdfdeviceWdmIrpPreprocess() { - callbackType.getName().matches("EVT_WDFDEVICE_WDM_IRP_PREPROCESS") - } -} - -class KmdfEVTWdfdeviceWdmIrpDispatch extends KmdfCallbackRoutine { - KmdfEVTWdfdeviceWdmIrpDispatch() { - callbackType.getName().matches("EVT_WDFDEVICE_WDM_IRP_DISPATCH") - } -} - -class KmdfEVTWdfIoInCallerContext extends KmdfCallbackRoutine { - KmdfEVTWdfIoInCallerContext() { callbackType.getName().matches("EVT_WDF_IO_IN_CALLER_CONTEXT") } -} - -class KmdfEVTWdfdeviceWdmPostPoFxRegisterDevice extends KmdfCallbackRoutine { - KmdfEVTWdfdeviceWdmPostPoFxRegisterDevice() { - callbackType.getName().matches("EVT_WDFDEVICE_WDM_POST_PO_FX_REGISTER_DEVICE") - } -} - -class KmdfEVTWdfdeviceWdmPrePoFxUnregisterDevice extends KmdfCallbackRoutine { - KmdfEVTWdfdeviceWdmPrePoFxUnregisterDevice() { - callbackType.getName().matches("EVT_WDFDEVICE_WDM_PRE_PO_FX_UNREGISTER_DEVICE") - } -} - -class KmdfEVTWdfDmaEnablerFill extends KmdfCallbackRoutine { - KmdfEVTWdfDmaEnablerFill() { callbackType.getName().matches("EVT_WDF_DMA_ENABLER_FILL") } -} - -class KmdfEVTWdfDmaEnablerFlush extends KmdfCallbackRoutine { - KmdfEVTWdfDmaEnablerFlush() { callbackType.getName().matches("EVT_WDF_DMA_ENABLER_FLUSH") } -} - -class KmdfEVTWdfDmaEnablerEnable extends KmdfCallbackRoutine { - KmdfEVTWdfDmaEnablerEnable() { callbackType.getName().matches("EVT_WDF_DMA_ENABLER_ENABLE") } -} - -class KmdfEVTWdfDmaEnablerDisable extends KmdfCallbackRoutine { - KmdfEVTWdfDmaEnablerDisable() { callbackType.getName().matches("EVT_WDF_DMA_ENABLER_DISABLE") } -} - -class KmdfEVTWdfDmaEnablerSelfmanagedIoStart extends KmdfCallbackRoutine { - KmdfEVTWdfDmaEnablerSelfmanagedIoStart() { - callbackType.getName().matches("EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_START") - } -} - -class KmdfEVTWdfDmaEnablerSelfmanagedIoStop extends KmdfCallbackRoutine { - KmdfEVTWdfDmaEnablerSelfmanagedIoStop() { - callbackType.getName().matches("EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_STOP") - } -} - -class KmdfEVTWdfProgramDma extends KmdfCallbackRoutine { - KmdfEVTWdfProgramDma() { callbackType.getName().matches("EVT_WDF_PROGRAM_DMA") } -} - -class KmdfEVTWdfDmaTransactionConfigureDmaChannel extends KmdfCallbackRoutine { - KmdfEVTWdfDmaTransactionConfigureDmaChannel() { - callbackType.getName().matches("EVT_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL") - } -} - -class KmdfEVTWdfDmaTransactionDmaTransferComplete extends KmdfCallbackRoutine { - KmdfEVTWdfDmaTransactionDmaTransferComplete() { - callbackType.getName().matches("EVT_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE") - } -} - -class KmdfEVTWdfReserveDma extends KmdfCallbackRoutine { - KmdfEVTWdfReserveDma() { callbackType.getName().matches("EVT_WDF_RESERVE_DMA") } -} - -class KmdfEVTWdfDpc extends KmdfCallbackRoutine { - KmdfEVTWdfDpc() { callbackType.getName().matches("EVT_WDF_DPC") } -} - -class KmdfEVTWdfDriverDeviceAdd extends KmdfCallbackRoutine { - KmdfEVTWdfDriverDeviceAdd() { callbackType.getName().matches("EVT_WDF_DRIVER_DEVICE_ADD") } -} - -class KmdfEVTWdfDriverUnload extends KmdfCallbackRoutine { - KmdfEVTWdfDriverUnload() { callbackType.getName().matches("EVT_WDF_DRIVER_UNLOAD") } -} - -class KmdfEVTWdfTraceCallback extends KmdfCallbackRoutine { - KmdfEVTWdfTraceCallback() { callbackType.getName().matches("EVT_WDF_TRACE_CALLBACK") } -} - -class KmdfEVTWdfDeviceFilterResourceRequirements extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceFilterResourceRequirements() { - callbackType.getName().matches("EVT_WDF_DEVICE_FILTER_RESOURCE_REQUIREMENTS") - } -} - -class KmdfEVTWdfDeviceRemoveAddedResources extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceRemoveAddedResources() { - callbackType.getName().matches("EVT_WDF_DEVICE_REMOVE_ADDED_RESOURCES") - } -} - -class KmdfEVTWdfInterruptIsr extends KmdfCallbackRoutine { - KmdfEVTWdfInterruptIsr() { callbackType.getName().matches("EVT_WDF_INTERRUPT_ISR") } -} - -class KmdfEVTWdfInterruptSynchronize extends KmdfCallbackRoutine { - KmdfEVTWdfInterruptSynchronize() { - callbackType.getName().matches("EVT_WDF_INTERRUPT_SYNCHRONIZE") - } -} - -class KmdfEVTWdfInterruptDpc extends KmdfCallbackRoutine { - KmdfEVTWdfInterruptDpc() { callbackType.getName().matches("EVT_WDF_INTERRUPT_DPC") } -} - -class KmdfEVTWdfInterruptWorkitem extends KmdfCallbackRoutine { - KmdfEVTWdfInterruptWorkitem() { callbackType.getName().matches("EVT_WDF_INTERRUPT_WORKITEM") } -} - -class KmdfEVTWdfInterruptEnable extends KmdfCallbackRoutine { - KmdfEVTWdfInterruptEnable() { callbackType.getName().matches("EVT_WDF_INTERRUPT_ENABLE") } -} - -class KmdfEVTWdfInterruptDisable extends KmdfCallbackRoutine { - KmdfEVTWdfInterruptDisable() { callbackType.getName().matches("EVT_WDF_INTERRUPT_DISABLE") } -} - -class KmdfEVTWdfIoQueueIoDefault extends KmdfCallbackRoutine { - KmdfEVTWdfIoQueueIoDefault() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_DEFAULT") } -} - -class KmdfEVTWdfIoQueueIoStop extends KmdfCallbackRoutine { - KmdfEVTWdfIoQueueIoStop() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_STOP") } -} - -class KmdfEVTWdfIoQueueIoResume extends KmdfCallbackRoutine { - KmdfEVTWdfIoQueueIoResume() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_RESUME") } -} - -class KmdfEVTWdfIoQueueIoRead extends KmdfCallbackRoutine { - KmdfEVTWdfIoQueueIoRead() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_READ") } -} - -class KmdfEVTWdfIoQueueIoWrite extends KmdfCallbackRoutine { - KmdfEVTWdfIoQueueIoWrite() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_WRITE") } -} - -class KmdfEVTWdfIoQueueIoDeviceControl extends KmdfCallbackRoutine { - KmdfEVTWdfIoQueueIoDeviceControl() { - callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL") - } -} - -class KmdfEVTWdfIoQueueIoInternalDeviceControl extends KmdfCallbackRoutine { - KmdfEVTWdfIoQueueIoInternalDeviceControl() { - callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL") - } -} - -class KmdfEVTWdfIoQueueIoCanceledOnQueue extends KmdfCallbackRoutine { - KmdfEVTWdfIoQueueIoCanceledOnQueue() { - callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE") - } -} - -class KmdfEVTWdfIoQueueState extends KmdfCallbackRoutine { - KmdfEVTWdfIoQueueState() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_STATE") } -} - -class KmdfEVTWdfIoAllocateResourcesForReservedRequest extends KmdfCallbackRoutine { - KmdfEVTWdfIoAllocateResourcesForReservedRequest() { - callbackType.getName().matches("EVT_WDF_IO_ALLOCATE_RESOURCES_FOR_RESERVED_REQUEST") - } -} - -class KmdfEVTWdfIoAllocateRequestResources extends KmdfCallbackRoutine { - KmdfEVTWdfIoAllocateRequestResources() { - callbackType.getName().matches("EVT_WDF_IO_ALLOCATE_REQUEST_RESOURCES") - } -} - -class KmdfEVTWdfIoWdmIrpForForwardProgress extends KmdfCallbackRoutine { - KmdfEVTWdfIoWdmIrpForForwardProgress() { - callbackType.getName().matches("EVT_WDF_IO_WDM_IRP_FOR_FORWARD_PROGRESS") - } -} - -class KmdfEVTWdfIoTargetQueryRemove extends KmdfCallbackRoutine { - KmdfEVTWdfIoTargetQueryRemove() { - callbackType.getName().matches("EVT_WDF_IO_TARGET_QUERY_REMOVE") - } -} - -class KmdfEVTWdfIoTargetRemoveCanceled extends KmdfCallbackRoutine { - KmdfEVTWdfIoTargetRemoveCanceled() { - callbackType.getName().matches("EVT_WDF_IO_TARGET_REMOVE_CANCELED") - } -} - -class KmdfEVTWdfIoTargetRemoveComplete extends KmdfCallbackRoutine { - KmdfEVTWdfIoTargetRemoveComplete() { - callbackType.getName().matches("EVT_WDF_IO_TARGET_REMOVE_COMPLETE") - } -} - -class KmdfEVTWdfObjectContextCleanup extends KmdfCallbackRoutine { - KmdfEVTWdfObjectContextCleanup() { - callbackType.getName().matches("EVT_WDF_OBJECT_CONTEXT_CLEANUP") - } -} - -class KmdfEVTWdfObjectContextDestroy extends KmdfCallbackRoutine { - KmdfEVTWdfObjectContextDestroy() { - callbackType.getName().matches("EVT_WDF_OBJECT_CONTEXT_DESTROY") - } -} - -class KmdfEVTWdfDeviceResourcesQuery extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceResourcesQuery() { - callbackType.getName().matches("EVT_WDF_DEVICE_RESOURCES_QUERY") - } -} - -class KmdfEVTWdfDeviceResourceRequirementsQuery extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceResourceRequirementsQuery() { - callbackType.getName().matches("EVT_WDF_DEVICE_RESOURCE_REQUIREMENTS_QUERY") - } -} - -class KmdfEVTWdfDeviceEject extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceEject() { callbackType.getName().matches("EVT_WDF_DEVICE_EJECT") } -} - -class KmdfEVTWdfDeviceSetLock extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceSetLock() { callbackType.getName().matches("EVT_WDF_DEVICE_SET_LOCK") } -} - -class KmdfEVTWdfDeviceEnableWakeAtBus extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceEnableWakeAtBus() { - callbackType.getName().matches("EVT_WDF_DEVICE_ENABLE_WAKE_AT_BUS") - } -} - -class KmdfEVTWdfDeviceDisableWakeAtBus extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceDisableWakeAtBus() { - callbackType.getName().matches("EVT_WDF_DEVICE_DISABLE_WAKE_AT_BUS") - } -} - -class KmdfEVTWdfDeviceReportedMissing extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceReportedMissing() { - callbackType.getName().matches("EVT_WDF_DEVICE_REPORTED_MISSING") - } -} - -class KmdfEVTWdfDeviceProcessQueryInterfaceRequest extends KmdfCallbackRoutine { - KmdfEVTWdfDeviceProcessQueryInterfaceRequest() { - callbackType.getName().matches("EVT_WDF_DEVICE_PROCESS_QUERY_INTERFACE_REQUEST") - } -} - -class KmdfEVTWdfRequestCancel extends KmdfCallbackRoutine { - KmdfEVTWdfRequestCancel() { callbackType.getName().matches("EVT_WDF_REQUEST_CANCEL") } -} - -class KmdfEVTWdfRequestCompletionRoutine extends KmdfCallbackRoutine { - KmdfEVTWdfRequestCompletionRoutine() { - callbackType.getName().matches("EVT_WDF_REQUEST_COMPLETION_ROUTINE") - } -} - -class KmdfEVTWdfTimer extends KmdfCallbackRoutine { - KmdfEVTWdfTimer() { callbackType.getName().matches("EVT_WDF_TIMER") } -} - -class KmdfEVTWdfUsbReaderCompletionRoutine extends KmdfCallbackRoutine { - KmdfEVTWdfUsbReaderCompletionRoutine() { - callbackType.getName().matches("EVT_WDF_USB_READER_COMPLETION_ROUTINE") - } -} - -class KmdfEVTWdfUsbReadersFailed extends KmdfCallbackRoutine { - KmdfEVTWdfUsbReadersFailed() { callbackType.getName().matches("EVT_WDF_USB_READERS_FAILED") } -} - -class KmdfEVTWdfWmiInstanceQueryInstance extends KmdfCallbackRoutine { - KmdfEVTWdfWmiInstanceQueryInstance() { - callbackType.getName().matches("EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE") - } -} - -class KmdfEVTWdfWmiInstanceSetInstance extends KmdfCallbackRoutine { - KmdfEVTWdfWmiInstanceSetInstance() { - callbackType.getName().matches("EVT_WDF_WMI_INSTANCE_SET_INSTANCE") - } -} - -class KmdfEVTWdfWmiInstanceSetItem extends KmdfCallbackRoutine { - KmdfEVTWdfWmiInstanceSetItem() { callbackType.getName().matches("EVT_WDF_WMI_INSTANCE_SET_ITEM") } -} - -class KmdfEVTWdfWmiInstanceExecuteMethod extends KmdfCallbackRoutine { - KmdfEVTWdfWmiInstanceExecuteMethod() { - callbackType.getName().matches("EVT_WDF_WMI_INSTANCE_EXECUTE_METHOD") - } -} - -class KmdfEVTWdfWmiProviderFunctionControl extends KmdfCallbackRoutine { - KmdfEVTWdfWmiProviderFunctionControl() { - callbackType.getName().matches("EVT_WDF_WMI_PROVIDER_FUNCTION_CONTROL") - } -} - -class KmdfEVTWdfWorkitem extends KmdfCallbackRoutine { - KmdfEVTWdfWorkitem() { callbackType.getName().matches("EVT_WDF_WORKITEM") } -} - -/** - * A KMDF callback routine, defined by having a typedef in its definition - * that matches the standard KMDF callbacks. - */ -class KmdfCallbackRoutine extends Function { - /** The typedef representing what callback this is. */ - KmdfRoleTypeType callbackType; - - KmdfCallbackRoutine() { - exists(FunctionDeclarationEntry fde | - fde.getFunction() = this and - fde.getTypedefType() = callbackType and - fde.getFile().getAnIncludedFile().getBaseName().matches("%wdf.h") - ) - } -} - -/** The DeviceAdd callback. Its callback typedef is "EVT_WDF_DRIVER_DEVICE_ADD". */ -class KmdfEvtDriverDeviceAdd extends KmdfCallbackRoutine { - KmdfEvtDriverDeviceAdd() { callbackType.getName().matches("EVT_WDF_DRIVER_DEVICE_ADD") } -} - -/** - * A KMDF Function. This class is incomplete. It is used to represent a Function in the KMDF library. - */ -class KmdfFunc extends Function { - KmdfFunc() { this.getFile().getBaseName().matches("wdf%.h") } -} - -/** - * A KMDF Struct. This class is incomplete. It is used to represent a Struct in the KMDF library. - */ -class KmdfStruct extends Struct { - KmdfStruct() { this.getFile().getBaseName().matches("wdf%.h") } -} - -/* KMDF Structs */ -class KmdfWDFPowerRoutineTimedOutData extends KmdfStruct { - KmdfWDFPowerRoutineTimedOutData() { this.getName().matches("_WDF_POWER_ROUTINE_TIMED_OUT_DATA") } -} - -class KmdfWDFRequestFatalErrorInformationLengthMismatchData extends KmdfStruct { - KmdfWDFRequestFatalErrorInformationLengthMismatchData() { - this.getName().matches("_WDF_REQUEST_FATAL_ERROR_INFORMATION_LENGTH_MISMATCH_DATA") - } -} - -class KmdfWDFQueueFatalErrorData extends KmdfStruct { - KmdfWDFQueueFatalErrorData() { this.getName().matches("_WDF_QUEUE_FATAL_ERROR_DATA") } -} - -class KmdfWDFChildIdentificationDescriptionHeader extends KmdfStruct { - KmdfWDFChildIdentificationDescriptionHeader() { - this.getName().matches("_WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER") - } -} - -class KmdfWDFChildAddressDescriptionHeader extends KmdfStruct { - KmdfWDFChildAddressDescriptionHeader() { - this.getName().matches("_WDF_CHILD_ADDRESS_DESCRIPTION_HEADER") - } -} - -class KmdfWDFChildRetrieveInfo extends KmdfStruct { - KmdfWDFChildRetrieveInfo() { this.getName().matches("_WDF_CHILD_RETRIEVE_INFO") } -} - -class KmdfWDFChildListConfig extends KmdfStruct { - KmdfWDFChildListConfig() { this.getName().matches("_WDF_CHILD_LIST_CONFIG") } -} - -class KmdfWDFChildListIterator extends KmdfStruct { - KmdfWDFChildListIterator() { this.getName().matches("_WDF_CHILD_LIST_ITERATOR") } -} - -class KmdfWDFCommonBufferConfig extends KmdfStruct { - KmdfWDFCommonBufferConfig() { this.getName().matches("_WDF_COMMON_BUFFER_CONFIG") } -} - -class KmdfWDFTaskSendOptions extends KmdfStruct { - KmdfWDFTaskSendOptions() { this.getName().matches("_WDF_TASK_SEND_OPTIONS") } -} - -class KmdfWDFFileobjectConfig extends KmdfStruct { - KmdfWDFFileobjectConfig() { this.getName().matches("_WDF_FILEOBJECT_CONFIG") } -} - -class KmdfWDFDevicePnpNotificationData extends KmdfStruct { - KmdfWDFDevicePnpNotificationData() { this.getName().matches("_WDF_DEVICE_PNP_NOTIFICATION_DATA") } -} - -class KmdfWDFDevicePowerNotificationData extends KmdfStruct { - KmdfWDFDevicePowerNotificationData() { - this.getName().matches("_WDF_DEVICE_POWER_NOTIFICATION_DATA") - } -} - -class KmdfWDFDevicePowerPolicyNotificationData extends KmdfStruct { - KmdfWDFDevicePowerPolicyNotificationData() { - this.getName().matches("_WDF_DEVICE_POWER_POLICY_NOTIFICATION_DATA") - } -} - -class KmdfWDFPnppowerEventCallbacks extends KmdfStruct { - KmdfWDFPnppowerEventCallbacks() { this.getName().matches("_WDF_PNPPOWER_EVENT_CALLBACKS") } -} - -class KmdfWDFPowerPolicyEventCallbacks extends KmdfStruct { - KmdfWDFPowerPolicyEventCallbacks() { this.getName().matches("_WDF_POWER_POLICY_EVENT_CALLBACKS") } -} - -class KmdfWDFDevicePowerPolicyIdleSettings extends KmdfStruct { - KmdfWDFDevicePowerPolicyIdleSettings() { - this.getName().matches("_WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS") - } -} - -class KmdfWDFDevicePowerPolicyWakeSettings extends KmdfStruct { - KmdfWDFDevicePowerPolicyWakeSettings() { - this.getName().matches("_WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS") - } -} - -class KmdfWDFDeviceState extends KmdfStruct { - KmdfWDFDeviceState() { this.getName().matches("_WDF_DEVICE_STATE") } -} - -class KmdfWDFDevicePnpCapabilities extends KmdfStruct { - KmdfWDFDevicePnpCapabilities() { this.getName().matches("_WDF_DEVICE_PNP_CAPABILITIES") } -} - -class KmdfWDFDevicePowerCapabilities extends KmdfStruct { - KmdfWDFDevicePowerCapabilities() { this.getName().matches("_WDF_DEVICE_POWER_CAPABILITIES") } -} - -class KmdfWDFRemoveLockOptions extends KmdfStruct { - KmdfWDFRemoveLockOptions() { this.getName().matches("_WDF_REMOVE_LOCK_OPTIONS") } -} - -class KmdfWDFPowerFrameworkSettings extends KmdfStruct { - KmdfWDFPowerFrameworkSettings() { this.getName().matches("_WDF_POWER_FRAMEWORK_SETTINGS") } -} - -class KmdfWDFIoTypeConfig extends KmdfStruct { - KmdfWDFIoTypeConfig() { this.getName().matches("_WDF_IO_TYPE_CONFIG") } -} - -class KmdfWDFDevicePropertyData extends KmdfStruct { - KmdfWDFDevicePropertyData() { this.getName().matches("_WDF_DEVICE_PROPERTY_DATA") } -} - -class KmdfWDFDmaEnablerConfig extends KmdfStruct { - KmdfWDFDmaEnablerConfig() { this.getName().matches("_WDF_DMA_ENABLER_CONFIG") } -} - -class KmdfWDFDmaSystemProfileConfig extends KmdfStruct { - KmdfWDFDmaSystemProfileConfig() { this.getName().matches("_WDF_DMA_SYSTEM_PROFILE_CONFIG") } -} - -class KmdfWDFDpcConfig extends KmdfStruct { - KmdfWDFDpcConfig() { this.getName().matches("_WDF_DPC_CONFIG") } -} - -class KmdfWDFDriverConfig extends KmdfStruct { - KmdfWDFDriverConfig() { this.getName().matches("_WDF_DRIVER_CONFIG") } -} - -class KmdfWDFDriverVersionAvailableParams extends KmdfStruct { - KmdfWDFDriverVersionAvailableParams() { - this.getName().matches("_WDF_DRIVER_VERSION_AVAILABLE_PARAMS") - } -} - -class KmdfWDFFdoEventCallbacks extends KmdfStruct { - KmdfWDFFdoEventCallbacks() { this.getName().matches("_WDF_FDO_EVENT_CALLBACKS") } -} - -class KmdfWDFDriverGlobals extends KmdfStruct { - KmdfWDFDriverGlobals() { this.getName().matches("_WDF_DRIVER_GLOBALS") } -} - -class KmdfWDFCoinstallerInstallOptions extends KmdfStruct { - KmdfWDFCoinstallerInstallOptions() { this.getName().matches("_WDF_COINSTALLER_INSTALL_OPTIONS") } -} - -class KmdfWDFInterruptConfig extends KmdfStruct { - KmdfWDFInterruptConfig() { this.getName().matches("_WDF_INTERRUPT_CONFIG") } -} - -class KmdfWDFInterruptInfo extends KmdfStruct { - KmdfWDFInterruptInfo() { this.getName().matches("_WDF_INTERRUPT_INFO") } -} - -class KmdfWDFInterruptExtendedPolicy extends KmdfStruct { - KmdfWDFInterruptExtendedPolicy() { this.getName().matches("_WDF_INTERRUPT_EXTENDED_POLICY") } -} - -class KmdfWDFIoQueueConfig extends KmdfStruct { - KmdfWDFIoQueueConfig() { this.getName().matches("_WDF_IO_QUEUE_CONFIG") } -} - -class KmdfWDFIoQueueForwardProgressPolicy extends KmdfStruct { - KmdfWDFIoQueueForwardProgressPolicy() { - this.getName().matches("_WDF_IO_QUEUE_FORWARD_PROGRESS_POLICY") - } -} - -class KmdfWDFIoTargetOpenParams extends KmdfStruct { - KmdfWDFIoTargetOpenParams() { this.getName().matches("_WDF_IO_TARGET_OPEN_PARAMS") } -} - -class KmdfWDFMEMORYOffset extends KmdfStruct { - KmdfWDFMEMORYOffset() { this.getName().matches("_WDFMEMORY_OFFSET") } -} - -class KmdfWDFMemoryDescriptor extends KmdfStruct { - KmdfWDFMemoryDescriptor() { this.getName().matches("_WDF_MEMORY_DESCRIPTOR") } -} - -class KmdfWDFObjectAttributes extends KmdfStruct { - KmdfWDFObjectAttributes() { this.getName().matches("_WDF_OBJECT_ATTRIBUTES") } -} - -class KmdfWDFObjectContextTypeInfo extends KmdfStruct { - KmdfWDFObjectContextTypeInfo() { this.getName().matches("_WDF_OBJECT_CONTEXT_TYPE_INFO") } -} - -class KmdfWDFCustomTypeContext extends KmdfStruct { - KmdfWDFCustomTypeContext() { this.getName().matches("_WDF_CUSTOM_TYPE_CONTEXT") } -} - -class KmdfWDFPdoEventCallbacks extends KmdfStruct { - KmdfWDFPdoEventCallbacks() { this.getName().matches("_WDF_PDO_EVENT_CALLBACKS") } -} - -class KmdfWDFQueryInterfaceConfig extends KmdfStruct { - KmdfWDFQueryInterfaceConfig() { this.getName().matches("_WDF_QUERY_INTERFACE_CONFIG") } -} - -class KmdfWDFRequestParameters extends KmdfStruct { - KmdfWDFRequestParameters() { this.getName().matches("_WDF_REQUEST_PARAMETERS") } -} - -class KmdfWDFRequestCompletionParams extends KmdfStruct { - KmdfWDFRequestCompletionParams() { this.getName().matches("_WDF_REQUEST_COMPLETION_PARAMS") } -} - -class KmdfWDFRequestReuseParams extends KmdfStruct { - KmdfWDFRequestReuseParams() { this.getName().matches("_WDF_REQUEST_REUSE_PARAMS") } -} - -class KmdfWDFRequestSendOptions extends KmdfStruct { - KmdfWDFRequestSendOptions() { this.getName().matches("_WDF_REQUEST_SEND_OPTIONS") } -} - -class KmdfWDFRequestForwardOptions extends KmdfStruct { - KmdfWDFRequestForwardOptions() { this.getName().matches("_WDF_REQUEST_FORWARD_OPTIONS") } -} - -class KmdfWDFTimerConfig extends KmdfStruct { - KmdfWDFTimerConfig() { this.getName().matches("_WDF_TIMER_CONFIG") } -} - -class KmdfWDFUsbRequestCompletionParams extends KmdfStruct { - KmdfWDFUsbRequestCompletionParams() { - this.getName().matches("_WDF_USB_REQUEST_COMPLETION_PARAMS") - } -} - -class KmdfWDFUsbContinuousReaderConfig extends KmdfStruct { - KmdfWDFUsbContinuousReaderConfig() { this.getName().matches("_WDF_USB_CONTINUOUS_READER_CONFIG") } -} - -class KmdfWDFUsbDeviceInformation extends KmdfStruct { - KmdfWDFUsbDeviceInformation() { this.getName().matches("_WDF_USB_DEVICE_INFORMATION") } -} - -class KmdfWDFUsbInterfaceSettingPair extends KmdfStruct { - KmdfWDFUsbInterfaceSettingPair() { this.getName().matches("_WDF_USB_INTERFACE_SETTING_PAIR") } -} - -class KmdfWDFUsbDeviceSelectConfigParams extends KmdfStruct { - KmdfWDFUsbDeviceSelectConfigParams() { - this.getName().matches("_WDF_USB_DEVICE_SELECT_CONFIG_PARAMS") - } -} - -class KmdfWDFUsbInterfaceSelectSettingParams extends KmdfStruct { - KmdfWDFUsbInterfaceSelectSettingParams() { - this.getName().matches("_WDF_USB_INTERFACE_SELECT_SETTING_PARAMS") - } -} - -class KmdfWDFUsbPipeInformation extends KmdfStruct { - KmdfWDFUsbPipeInformation() { this.getName().matches("_WDF_USB_PIPE_INFORMATION") } -} - -class KmdfWDFUsbDeviceCreateConfig extends KmdfStruct { - KmdfWDFUsbDeviceCreateConfig() { this.getName().matches("_WDF_USB_DEVICE_CREATE_CONFIG") } -} - -class KmdfWDFWmiProviderConfig extends KmdfStruct { - KmdfWDFWmiProviderConfig() { this.getName().matches("_WDF_WMI_PROVIDER_CONFIG") } -} - -class KmdfWDFWmiInstanceConfig extends KmdfStruct { - KmdfWDFWmiInstanceConfig() { this.getName().matches("_WDF_WMI_INSTANCE_CONFIG") } -} - -class KmdfWDFWorkitemConfig extends KmdfStruct { - KmdfWDFWorkitemConfig() { this.getName().matches("_WDF_WORKITEM_CONFIG") } -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +import cpp + +/** + * A KMDF Typedef type. This class is incomplete. It is used to represent a TypedefType in the KMDF library. + */ +class KmdfRoleTypeType extends TypedefType { + /* Callbacks */ + KmdfRoleTypeType() { + + this.getName().matches("EVT_WDF_CHILD_LIST_CREATE_DEVICE") or + this.getName().matches("EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN") or + this.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COPY") or + this.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE") or + this.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE") or + this.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_CLEANUP") or + this.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_COPY") or + this.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_DUPLICATE") or + this.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_CLEANUP") or + this.getName().matches("EVT_WDF_CHILD_LIST_DEVICE_REENUMERATED") or + this.getName().matches("EVT_WDF_DEVICE_SHUTDOWN_NOTIFICATION") or + this.getName().matches("EVT_WDF_DEVICE_FILE_CREATE") or + this.getName().matches("EVT_WDF_FILE_CLOSE") or + this.getName().matches("EVT_WDF_FILE_CLEANUP") or + this.getName().matches("EVT_WDF_DEVICE_PNP_STATE_CHANGE_NOTIFICATION") or + this.getName().matches("EVT_WDF_DEVICE_POWER_STATE_CHANGE_NOTIFICATION") or + this.getName().matches("EVT_WDF_DEVICE_POWER_POLICY_STATE_CHANGE_NOTIFICATION") or + this.getName().matches("EVT_WDF_DEVICE_D0_ENTRY") or + this.getName().matches("EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED") or + this.getName().matches("EVT_WDF_DEVICE_D0_ENTRY_POST_HARDWARE_ENABLED") or + this.getName().matches("EVT_WDF_DEVICE_D0_EXIT") or + this.getName().matches("EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED") or + this.getName().matches("EVT_WDF_DEVICE_D0_EXIT_PRE_HARDWARE_DISABLED") or + this.getName().matches("EVT_WDF_DEVICE_PREPARE_HARDWARE") or + this.getName().matches("EVT_WDF_DEVICE_RELEASE_HARDWARE") or + this.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP") or + this.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_FLUSH") or + this.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT") or + this.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_SUSPEND") or + this.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_RESTART") or + this.getName().matches("EVT_WDF_DEVICE_QUERY_STOP") or + this.getName().matches("EVT_WDF_DEVICE_QUERY_REMOVE") or + this.getName().matches("EVT_WDF_DEVICE_SURPRISE_REMOVAL") or + this.getName().matches("EVT_WDF_DEVICE_USAGE_NOTIFICATION") or + this.getName().matches("EVT_WDF_DEVICE_USAGE_NOTIFICATION_EX") or + this.getName().matches("EVT_WDF_DEVICE_RELATIONS_QUERY") or + this.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_S0") or + this.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_SX") or + this.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_SX_WITH_REASON") or + this.getName().matches("EVT_WDF_DEVICE_DISARM_WAKE_FROM_S0") or + this.getName().matches("EVT_WDF_DEVICE_DISARM_WAKE_FROM_SX") or + this.getName().matches("EVT_WDF_DEVICE_WAKE_FROM_S0_TRIGGERED") or + this.getName().matches("EVT_WDF_DEVICE_WAKE_FROM_SX_TRIGGERED") or + this.getName().matches("EVT_WDFDEVICE_WDM_IRP_PREPROCESS") or + this.getName().matches("EVT_WDFDEVICE_WDM_IRP_DISPATCH") or + this.getName().matches("EVT_WDF_IO_IN_CALLER_CONTEXT") or + this.getName().matches("EVT_WDFDEVICE_WDM_POST_PO_FX_REGISTER_DEVICE") or + this.getName().matches("EVT_WDFDEVICE_WDM_PRE_PO_FX_UNREGISTER_DEVICE") or + this.getName().matches("EVT_WDF_DMA_ENABLER_FILL") or + this.getName().matches("EVT_WDF_DMA_ENABLER_FLUSH") or + this.getName().matches("EVT_WDF_DMA_ENABLER_ENABLE") or + this.getName().matches("EVT_WDF_DMA_ENABLER_DISABLE") or + this.getName().matches("EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_START") or + this.getName().matches("EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_STOP") or + this.getName().matches("EVT_WDF_PROGRAM_DMA") or + this.getName().matches("EVT_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL") or + this.getName().matches("EVT_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE") or + this.getName().matches("EVT_WDF_RESERVE_DMA") or + this.getName().matches("EVT_WDF_DPC") or + this.getName().matches("EVT_WDF_DRIVER_DEVICE_ADD") or + this.getName().matches("EVT_WDF_DRIVER_UNLOAD") or + this.getName().matches("EVT_WDF_TRACE_CALLBACK") or + this.getName().matches("EVT_WDF_DEVICE_FILTER_RESOURCE_REQUIREMENTS") or + this.getName().matches("EVT_WDF_DEVICE_REMOVE_ADDED_RESOURCES") or + this.getName().matches("EVT_WDF_INTERRUPT_ISR") or + this.getName().matches("EVT_WDF_INTERRUPT_SYNCHRONIZE") or + this.getName().matches("EVT_WDF_INTERRUPT_DPC") or + this.getName().matches("EVT_WDF_INTERRUPT_WORKITEM") or + this.getName().matches("EVT_WDF_INTERRUPT_ENABLE") or + this.getName().matches("EVT_WDF_INTERRUPT_DISABLE") or + this.getName().matches("EVT_WDF_IO_QUEUE_IO_DEFAULT") or + this.getName().matches("EVT_WDF_IO_QUEUE_IO_STOP") or + this.getName().matches("EVT_WDF_IO_QUEUE_IO_RESUME") or + this.getName().matches("EVT_WDF_IO_QUEUE_IO_READ") or + this.getName().matches("EVT_WDF_IO_QUEUE_IO_WRITE") or + this.getName().matches("EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL") or + this.getName().matches("EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL") or + this.getName().matches("EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE") or + this.getName().matches("EVT_WDF_IO_QUEUE_STATE") or + this.getName().matches("EVT_WDF_IO_ALLOCATE_RESOURCES_FOR_RESERVED_REQUEST") or + this.getName().matches("EVT_WDF_IO_ALLOCATE_REQUEST_RESOURCES") or + this.getName().matches("EVT_WDF_IO_WDM_IRP_FOR_FORWARD_PROGRESS") or + this.getName().matches("EVT_WDF_IO_TARGET_QUERY_REMOVE") or + this.getName().matches("EVT_WDF_IO_TARGET_REMOVE_CANCELED") or + this.getName().matches("EVT_WDF_IO_TARGET_REMOVE_COMPLETE") or + this.getName().matches("EVT_WDF_%_CONTEXT_CLEANUP%") or + this.getName().matches("EVT_WDF_%_CONTEXT_DESTROY%") or + this.getName().matches("EVT_WDF_DEVICE_RESOURCES_QUERY") or + this.getName().matches("EVT_WDF_DEVICE_RESOURCE_REQUIREMENTS_QUERY") or + this.getName().matches("EVT_WDF_DEVICE_EJECT") or + this.getName().matches("EVT_WDF_DEVICE_SET_LOCK") or + this.getName().matches("EVT_WDF_DEVICE_ENABLE_WAKE_AT_BUS") or + this.getName().matches("EVT_WDF_DEVICE_DISABLE_WAKE_AT_BUS") or + this.getName().matches("EVT_WDF_DEVICE_REPORTED_MISSING") or + this.getName().matches("EVT_WDF_DEVICE_PROCESS_QUERY_INTERFACE_REQUEST") or + this.getName().matches("EVT_WDF_REQUEST_CANCEL") or + this.getName().matches("EVT_WDF_REQUEST_COMPLETION_ROUTINE") or + this.getName().matches("EVT_WDF_TIMER") or + this.getName().matches("EVT_WDF_USB_READER_COMPLETION_ROUTINE") or + this.getName().matches("EVT_WDF_USB_READERS_FAILED") or + this.getName().matches("EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE") or + this.getName().matches("EVT_WDF_WMI_INSTANCE_SET_INSTANCE") or + this.getName().matches("EVT_WDF_WMI_INSTANCE_SET_ITEM") or + this.getName().matches("EVT_WDF_WMI_INSTANCE_EXECUTE_METHOD") or + this.getName().matches("EVT_WDF_WMI_PROVIDER_FUNCTION_CONTROL") or + this.getName().matches("EVT_WDF_WORKITEM") + + } +} + +class KmdfCallbackRoutineTypedef extends KmdfRoleTypeType { + KmdfCallbackRoutineTypedef() { this.getFile().getBaseName().matches("%wdf%.h") } +} + +/* Callbacks */ +class KmdfEVTWdfChildListCreateDevice extends KmdfCallbackRoutine { + KmdfEVTWdfChildListCreateDevice() { + callbackType.getName().matches("EVT_WDF_CHILD_LIST_CREATE_DEVICE") + } +} + +class KmdfEVTWdfChildListScanForChildren extends KmdfCallbackRoutine { + KmdfEVTWdfChildListScanForChildren() { + callbackType.getName().matches("EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN") + } +} + +class KmdfEVTWdfChildListIdentificationDescriptionCopy extends KmdfCallbackRoutine { + KmdfEVTWdfChildListIdentificationDescriptionCopy() { + callbackType.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COPY") + } +} + +class KmdfEVTWdfChildListIdentificationDescriptionDuplicate extends KmdfCallbackRoutine { + KmdfEVTWdfChildListIdentificationDescriptionDuplicate() { + callbackType.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE") + } +} + +class KmdfEVTWdfChildListIdentificationDescriptionCompare extends KmdfCallbackRoutine { + KmdfEVTWdfChildListIdentificationDescriptionCompare() { + callbackType.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE") + } +} + +class KmdfEVTWdfChildListIdentificationDescriptionCleanup extends KmdfCallbackRoutine { + KmdfEVTWdfChildListIdentificationDescriptionCleanup() { + callbackType.getName().matches("EVT_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_CLEANUP") + } +} + +class KmdfEVTWdfChildListAddressDescriptionCopy extends KmdfCallbackRoutine { + KmdfEVTWdfChildListAddressDescriptionCopy() { + callbackType.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_COPY") + } +} + +class KmdfEVTWdfChildListAddressDescriptionDuplicate extends KmdfCallbackRoutine { + KmdfEVTWdfChildListAddressDescriptionDuplicate() { + callbackType.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_DUPLICATE") + } +} + +class KmdfEVTWdfChildListAddressDescriptionCleanup extends KmdfCallbackRoutine { + KmdfEVTWdfChildListAddressDescriptionCleanup() { + callbackType.getName().matches("EVT_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_CLEANUP") + } +} + +class KmdfEVTWdfChildListDeviceReenumerated extends KmdfCallbackRoutine { + KmdfEVTWdfChildListDeviceReenumerated() { + callbackType.getName().matches("EVT_WDF_CHILD_LIST_DEVICE_REENUMERATED") + } +} + +class KmdfEVTWdfDeviceShutdownNotification extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceShutdownNotification() { + callbackType.getName().matches("EVT_WDF_DEVICE_SHUTDOWN_NOTIFICATION") + } +} + +class KmdfEVTWdfDeviceFileCreate extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceFileCreate() { callbackType.getName().matches("EVT_WDF_DEVICE_FILE_CREATE") } +} + +class KmdfEVTWdfFileClose extends KmdfCallbackRoutine { + KmdfEVTWdfFileClose() { callbackType.getName().matches("EVT_WDF_FILE_CLOSE") } +} + +class KmdfEVTWdfFileCleanup extends KmdfCallbackRoutine { + KmdfEVTWdfFileCleanup() { callbackType.getName().matches("EVT_WDF_FILE_CLEANUP") } +} + +class KmdfEVTWdfDevicePnpStateChangeNotification extends KmdfCallbackRoutine { + KmdfEVTWdfDevicePnpStateChangeNotification() { + callbackType.getName().matches("EVT_WDF_DEVICE_PNP_STATE_CHANGE_NOTIFICATION") + } +} + +class KmdfEVTWdfDevicePowerStateChangeNotification extends KmdfCallbackRoutine { + KmdfEVTWdfDevicePowerStateChangeNotification() { + callbackType.getName().matches("EVT_WDF_DEVICE_POWER_STATE_CHANGE_NOTIFICATION") + } +} + +class KmdfEVTWdfDevicePowerPolicyStateChangeNotification extends KmdfCallbackRoutine { + KmdfEVTWdfDevicePowerPolicyStateChangeNotification() { + callbackType.getName().matches("EVT_WDF_DEVICE_POWER_POLICY_STATE_CHANGE_NOTIFICATION") + } +} + +class KmdfEVTWdfDeviceD0Entry extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceD0Entry() { callbackType.getName().matches("EVT_WDF_DEVICE_D0_ENTRY") } +} + +class KmdfEVTWdfDeviceD0EntryPostInterruptsEnabled extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceD0EntryPostInterruptsEnabled() { + callbackType.getName().matches("EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED") + } +} + +class KmdfEVTWdfDeviceD0EntryPostHardwareEnabled extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceD0EntryPostHardwareEnabled() { + callbackType.getName().matches("EVT_WDF_DEVICE_D0_ENTRY_POST_HARDWARE_ENABLED") + } +} + +class KmdfEVTWdfDeviceD0Exit extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceD0Exit() { callbackType.getName().matches("EVT_WDF_DEVICE_D0_EXIT") } +} + +class KmdfEVTWdfDeviceD0ExitPreInterruptsDisabled extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceD0ExitPreInterruptsDisabled() { + callbackType.getName().matches("EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED") + } +} + +class KmdfEVTWdfDeviceD0ExitPreHardwareDisabled extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceD0ExitPreHardwareDisabled() { + callbackType.getName().matches("EVT_WDF_DEVICE_D0_EXIT_PRE_HARDWARE_DISABLED") + } +} + +class KmdfEVTWdfDevicePrepareHardware extends KmdfCallbackRoutine { + KmdfEVTWdfDevicePrepareHardware() { + callbackType.getName().matches("EVT_WDF_DEVICE_PREPARE_HARDWARE") + } +} + +class KmdfEVTWdfDeviceReleaseHardware extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceReleaseHardware() { + callbackType.getName().matches("EVT_WDF_DEVICE_RELEASE_HARDWARE") + } +} + +class KmdfEVTWdfDeviceSelfManagedIoCleanup extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceSelfManagedIoCleanup() { + callbackType.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP") + } +} + +class KmdfEVTWdfDeviceSelfManagedIoFlush extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceSelfManagedIoFlush() { + callbackType.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_FLUSH") + } +} + +class KmdfEVTWdfDeviceSelfManagedIoInit extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceSelfManagedIoInit() { + callbackType.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT") + } +} + +class KmdfEVTWdfDeviceSelfManagedIoSuspend extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceSelfManagedIoSuspend() { + callbackType.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_SUSPEND") + } +} + +class KmdfEVTWdfDeviceSelfManagedIoRestart extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceSelfManagedIoRestart() { + callbackType.getName().matches("EVT_WDF_DEVICE_SELF_MANAGED_IO_RESTART") + } +} + +class KmdfEVTWdfDeviceQueryStop extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceQueryStop() { callbackType.getName().matches("EVT_WDF_DEVICE_QUERY_STOP") } +} + +class KmdfEVTWdfDeviceQueryRemove extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceQueryRemove() { callbackType.getName().matches("EVT_WDF_DEVICE_QUERY_REMOVE") } +} + +class KmdfEVTWdfDeviceSurpriseRemoval extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceSurpriseRemoval() { + callbackType.getName().matches("EVT_WDF_DEVICE_SURPRISE_REMOVAL") + } +} + +class KmdfEVTWdfDeviceUsageNotification extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceUsageNotification() { + callbackType.getName().matches("EVT_WDF_DEVICE_USAGE_NOTIFICATION") + } +} + +class KmdfEVTWdfDeviceUsageNotificationEx extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceUsageNotificationEx() { + callbackType.getName().matches("EVT_WDF_DEVICE_USAGE_NOTIFICATION_EX") + } +} + +class KmdfEVTWdfDeviceRelationsQuery extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceRelationsQuery() { + callbackType.getName().matches("EVT_WDF_DEVICE_RELATIONS_QUERY") + } +} + +class KmdfEVTWdfDeviceArmWakeFromS0 extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceArmWakeFromS0() { + callbackType.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_S0") + } +} + +class KmdfEVTWdfDeviceArmWakeFromSx extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceArmWakeFromSx() { + callbackType.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_SX") + } +} + +class KmdfEVTWdfDeviceArmWakeFromSxWithReason extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceArmWakeFromSxWithReason() { + callbackType.getName().matches("EVT_WDF_DEVICE_ARM_WAKE_FROM_SX_WITH_REASON") + } +} + +class KmdfEVTWdfDeviceDisarmWakeFromS0 extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceDisarmWakeFromS0() { + callbackType.getName().matches("EVT_WDF_DEVICE_DISARM_WAKE_FROM_S0") + } +} + +class KmdfEVTWdfDeviceDisarmWakeFromSx extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceDisarmWakeFromSx() { + callbackType.getName().matches("EVT_WDF_DEVICE_DISARM_WAKE_FROM_SX") + } +} + +class KmdfEVTWdfDeviceWakeFromS0Triggered extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceWakeFromS0Triggered() { + callbackType.getName().matches("EVT_WDF_DEVICE_WAKE_FROM_S0_TRIGGERED") + } +} + +class KmdfEVTWdfDeviceWakeFromSxTriggered extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceWakeFromSxTriggered() { + callbackType.getName().matches("EVT_WDF_DEVICE_WAKE_FROM_SX_TRIGGERED") + } +} + +class KmdfEVTWdfdeviceWdmIrpPreprocess extends KmdfCallbackRoutine { + KmdfEVTWdfdeviceWdmIrpPreprocess() { + callbackType.getName().matches("EVT_WDFDEVICE_WDM_IRP_PREPROCESS") + } +} + +class KmdfEVTWdfdeviceWdmIrpDispatch extends KmdfCallbackRoutine { + KmdfEVTWdfdeviceWdmIrpDispatch() { + callbackType.getName().matches("EVT_WDFDEVICE_WDM_IRP_DISPATCH") + } +} + +class KmdfEVTWdfIoInCallerContext extends KmdfCallbackRoutine { + KmdfEVTWdfIoInCallerContext() { callbackType.getName().matches("EVT_WDF_IO_IN_CALLER_CONTEXT") } +} + +class KmdfEVTWdfdeviceWdmPostPoFxRegisterDevice extends KmdfCallbackRoutine { + KmdfEVTWdfdeviceWdmPostPoFxRegisterDevice() { + callbackType.getName().matches("EVT_WDFDEVICE_WDM_POST_PO_FX_REGISTER_DEVICE") + } +} + +class KmdfEVTWdfdeviceWdmPrePoFxUnregisterDevice extends KmdfCallbackRoutine { + KmdfEVTWdfdeviceWdmPrePoFxUnregisterDevice() { + callbackType.getName().matches("EVT_WDFDEVICE_WDM_PRE_PO_FX_UNREGISTER_DEVICE") + } +} + +class KmdfEVTWdfDmaEnablerFill extends KmdfCallbackRoutine { + KmdfEVTWdfDmaEnablerFill() { callbackType.getName().matches("EVT_WDF_DMA_ENABLER_FILL") } +} + +class KmdfEVTWdfDmaEnablerFlush extends KmdfCallbackRoutine { + KmdfEVTWdfDmaEnablerFlush() { callbackType.getName().matches("EVT_WDF_DMA_ENABLER_FLUSH") } +} + +class KmdfEVTWdfDmaEnablerEnable extends KmdfCallbackRoutine { + KmdfEVTWdfDmaEnablerEnable() { callbackType.getName().matches("EVT_WDF_DMA_ENABLER_ENABLE") } +} + +class KmdfEVTWdfDmaEnablerDisable extends KmdfCallbackRoutine { + KmdfEVTWdfDmaEnablerDisable() { callbackType.getName().matches("EVT_WDF_DMA_ENABLER_DISABLE") } +} + +class KmdfEVTWdfDmaEnablerSelfmanagedIoStart extends KmdfCallbackRoutine { + KmdfEVTWdfDmaEnablerSelfmanagedIoStart() { + callbackType.getName().matches("EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_START") + } +} + +class KmdfEVTWdfDmaEnablerSelfmanagedIoStop extends KmdfCallbackRoutine { + KmdfEVTWdfDmaEnablerSelfmanagedIoStop() { + callbackType.getName().matches("EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_STOP") + } +} + +class KmdfEVTWdfProgramDma extends KmdfCallbackRoutine { + KmdfEVTWdfProgramDma() { callbackType.getName().matches("EVT_WDF_PROGRAM_DMA") } +} + +class KmdfEVTWdfDmaTransactionConfigureDmaChannel extends KmdfCallbackRoutine { + KmdfEVTWdfDmaTransactionConfigureDmaChannel() { + callbackType.getName().matches("EVT_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL") + } +} + +class KmdfEVTWdfDmaTransactionDmaTransferComplete extends KmdfCallbackRoutine { + KmdfEVTWdfDmaTransactionDmaTransferComplete() { + callbackType.getName().matches("EVT_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE") + } +} + +class KmdfEVTWdfReserveDma extends KmdfCallbackRoutine { + KmdfEVTWdfReserveDma() { callbackType.getName().matches("EVT_WDF_RESERVE_DMA") } +} + +class KmdfEVTWdfDpc extends KmdfCallbackRoutine { + KmdfEVTWdfDpc() { callbackType.getName().matches("EVT_WDF_DPC") } +} + +class KmdfEVTWdfDriverDeviceAdd extends KmdfCallbackRoutine { + KmdfEVTWdfDriverDeviceAdd() { callbackType.getName().matches("EVT_WDF_DRIVER_DEVICE_ADD") } +} + +class KmdfEVTWdfDriverUnload extends KmdfCallbackRoutine { + KmdfEVTWdfDriverUnload() { callbackType.getName().matches("EVT_WDF_DRIVER_UNLOAD") } +} + +class KmdfEVTWdfTraceCallback extends KmdfCallbackRoutine { + KmdfEVTWdfTraceCallback() { callbackType.getName().matches("EVT_WDF_TRACE_CALLBACK") } +} + +class KmdfEVTWdfDeviceFilterResourceRequirements extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceFilterResourceRequirements() { + callbackType.getName().matches("EVT_WDF_DEVICE_FILTER_RESOURCE_REQUIREMENTS") + } +} + +class KmdfEVTWdfDeviceRemoveAddedResources extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceRemoveAddedResources() { + callbackType.getName().matches("EVT_WDF_DEVICE_REMOVE_ADDED_RESOURCES") + } +} + +class KmdfEVTWdfInterruptIsr extends KmdfCallbackRoutine { + KmdfEVTWdfInterruptIsr() { callbackType.getName().matches("EVT_WDF_INTERRUPT_ISR") } +} + +class KmdfEVTWdfInterruptSynchronize extends KmdfCallbackRoutine { + KmdfEVTWdfInterruptSynchronize() { + callbackType.getName().matches("EVT_WDF_INTERRUPT_SYNCHRONIZE") + } +} + +class KmdfEVTWdfInterruptDpc extends KmdfCallbackRoutine { + KmdfEVTWdfInterruptDpc() { callbackType.getName().matches("EVT_WDF_INTERRUPT_DPC") } +} + +class KmdfEVTWdfInterruptWorkitem extends KmdfCallbackRoutine { + KmdfEVTWdfInterruptWorkitem() { callbackType.getName().matches("EVT_WDF_INTERRUPT_WORKITEM") } +} + +class KmdfEVTWdfInterruptEnable extends KmdfCallbackRoutine { + KmdfEVTWdfInterruptEnable() { callbackType.getName().matches("EVT_WDF_INTERRUPT_ENABLE") } +} + +class KmdfEVTWdfInterruptDisable extends KmdfCallbackRoutine { + KmdfEVTWdfInterruptDisable() { callbackType.getName().matches("EVT_WDF_INTERRUPT_DISABLE") } +} + +class KmdfEVTWdfIoQueueIoDefault extends KmdfCallbackRoutine { + KmdfEVTWdfIoQueueIoDefault() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_DEFAULT") } +} + +class KmdfEVTWdfIoQueueIoStop extends KmdfCallbackRoutine { + KmdfEVTWdfIoQueueIoStop() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_STOP") } +} + +class KmdfEVTWdfIoQueueIoResume extends KmdfCallbackRoutine { + KmdfEVTWdfIoQueueIoResume() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_RESUME") } +} + +class KmdfEVTWdfIoQueueIoRead extends KmdfCallbackRoutine { + KmdfEVTWdfIoQueueIoRead() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_READ") } +} + +class KmdfEVTWdfIoQueueIoWrite extends KmdfCallbackRoutine { + KmdfEVTWdfIoQueueIoWrite() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_WRITE") } +} + +class KmdfEVTWdfIoQueueIoDeviceControl extends KmdfCallbackRoutine { + KmdfEVTWdfIoQueueIoDeviceControl() { + callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL") + } +} + +class KmdfEVTWdfIoQueueIoInternalDeviceControl extends KmdfCallbackRoutine { + KmdfEVTWdfIoQueueIoInternalDeviceControl() { + callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_INTERNAL_DEVICE_CONTROL") + } +} + +class KmdfEVTWdfIoQueueIoCanceledOnQueue extends KmdfCallbackRoutine { + KmdfEVTWdfIoQueueIoCanceledOnQueue() { + callbackType.getName().matches("EVT_WDF_IO_QUEUE_IO_CANCELED_ON_QUEUE") + } +} + +class KmdfEVTWdfIoQueueState extends KmdfCallbackRoutine { + KmdfEVTWdfIoQueueState() { callbackType.getName().matches("EVT_WDF_IO_QUEUE_STATE") } +} + +class KmdfEVTWdfIoAllocateResourcesForReservedRequest extends KmdfCallbackRoutine { + KmdfEVTWdfIoAllocateResourcesForReservedRequest() { + callbackType.getName().matches("EVT_WDF_IO_ALLOCATE_RESOURCES_FOR_RESERVED_REQUEST") + } +} + +class KmdfEVTWdfIoAllocateRequestResources extends KmdfCallbackRoutine { + KmdfEVTWdfIoAllocateRequestResources() { + callbackType.getName().matches("EVT_WDF_IO_ALLOCATE_REQUEST_RESOURCES") + } +} + +class KmdfEVTWdfIoWdmIrpForForwardProgress extends KmdfCallbackRoutine { + KmdfEVTWdfIoWdmIrpForForwardProgress() { + callbackType.getName().matches("EVT_WDF_IO_WDM_IRP_FOR_FORWARD_PROGRESS") + } +} + +class KmdfEVTWdfIoTargetQueryRemove extends KmdfCallbackRoutine { + KmdfEVTWdfIoTargetQueryRemove() { + callbackType.getName().matches("EVT_WDF_IO_TARGET_QUERY_REMOVE") + } +} + +class KmdfEVTWdfIoTargetRemoveCanceled extends KmdfCallbackRoutine { + KmdfEVTWdfIoTargetRemoveCanceled() { + callbackType.getName().matches("EVT_WDF_IO_TARGET_REMOVE_CANCELED") + } +} + +class KmdfEVTWdfIoTargetRemoveComplete extends KmdfCallbackRoutine { + KmdfEVTWdfIoTargetRemoveComplete() { + callbackType.getName().matches("EVT_WDF_IO_TARGET_REMOVE_COMPLETE") + } +} + +class KmdfEVTWdfObjectContextCleanup extends KmdfCallbackRoutine { + KmdfEVTWdfObjectContextCleanup() { + callbackType.getName().matches("EVT_WDF_OBJECT_CONTEXT_CLEANUP") + } +} + +class KmdfEVTWdfObjectContextDestroy extends KmdfCallbackRoutine { + KmdfEVTWdfObjectContextDestroy() { + callbackType.getName().matches("EVT_WDF_OBJECT_CONTEXT_DESTROY") + } +} + +class KmdfEVTWdfDeviceResourcesQuery extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceResourcesQuery() { + callbackType.getName().matches("EVT_WDF_DEVICE_RESOURCES_QUERY") + } +} + +class KmdfEVTWdfDeviceResourceRequirementsQuery extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceResourceRequirementsQuery() { + callbackType.getName().matches("EVT_WDF_DEVICE_RESOURCE_REQUIREMENTS_QUERY") + } +} + +class KmdfEVTWdfDeviceEject extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceEject() { callbackType.getName().matches("EVT_WDF_DEVICE_EJECT") } +} + +class KmdfEVTWdfDeviceSetLock extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceSetLock() { callbackType.getName().matches("EVT_WDF_DEVICE_SET_LOCK") } +} + +class KmdfEVTWdfDeviceEnableWakeAtBus extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceEnableWakeAtBus() { + callbackType.getName().matches("EVT_WDF_DEVICE_ENABLE_WAKE_AT_BUS") + } +} + +class KmdfEVTWdfDeviceDisableWakeAtBus extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceDisableWakeAtBus() { + callbackType.getName().matches("EVT_WDF_DEVICE_DISABLE_WAKE_AT_BUS") + } +} + +class KmdfEVTWdfDeviceReportedMissing extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceReportedMissing() { + callbackType.getName().matches("EVT_WDF_DEVICE_REPORTED_MISSING") + } +} + +class KmdfEVTWdfDeviceProcessQueryInterfaceRequest extends KmdfCallbackRoutine { + KmdfEVTWdfDeviceProcessQueryInterfaceRequest() { + callbackType.getName().matches("EVT_WDF_DEVICE_PROCESS_QUERY_INTERFACE_REQUEST") + } +} + +class KmdfEVTWdfRequestCancel extends KmdfCallbackRoutine { + KmdfEVTWdfRequestCancel() { callbackType.getName().matches("EVT_WDF_REQUEST_CANCEL") } +} + +class KmdfEVTWdfRequestCompletionRoutine extends KmdfCallbackRoutine { + KmdfEVTWdfRequestCompletionRoutine() { + callbackType.getName().matches("EVT_WDF_REQUEST_COMPLETION_ROUTINE") + } +} + +class KmdfEVTWdfTimer extends KmdfCallbackRoutine { + KmdfEVTWdfTimer() { callbackType.getName().matches("EVT_WDF_TIMER") } +} + +class KmdfEVTWdfUsbReaderCompletionRoutine extends KmdfCallbackRoutine { + KmdfEVTWdfUsbReaderCompletionRoutine() { + callbackType.getName().matches("EVT_WDF_USB_READER_COMPLETION_ROUTINE") + } +} + +class KmdfEVTWdfUsbReadersFailed extends KmdfCallbackRoutine { + KmdfEVTWdfUsbReadersFailed() { callbackType.getName().matches("EVT_WDF_USB_READERS_FAILED") } +} + +class KmdfEVTWdfWmiInstanceQueryInstance extends KmdfCallbackRoutine { + KmdfEVTWdfWmiInstanceQueryInstance() { + callbackType.getName().matches("EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE") + } +} + +class KmdfEVTWdfWmiInstanceSetInstance extends KmdfCallbackRoutine { + KmdfEVTWdfWmiInstanceSetInstance() { + callbackType.getName().matches("EVT_WDF_WMI_INSTANCE_SET_INSTANCE") + } +} + +class KmdfEVTWdfWmiInstanceSetItem extends KmdfCallbackRoutine { + KmdfEVTWdfWmiInstanceSetItem() { callbackType.getName().matches("EVT_WDF_WMI_INSTANCE_SET_ITEM") } +} + +class KmdfEVTWdfWmiInstanceExecuteMethod extends KmdfCallbackRoutine { + KmdfEVTWdfWmiInstanceExecuteMethod() { + callbackType.getName().matches("EVT_WDF_WMI_INSTANCE_EXECUTE_METHOD") + } +} + +class KmdfEVTWdfWmiProviderFunctionControl extends KmdfCallbackRoutine { + KmdfEVTWdfWmiProviderFunctionControl() { + callbackType.getName().matches("EVT_WDF_WMI_PROVIDER_FUNCTION_CONTROL") + } +} + +class KmdfEVTWdfWorkitem extends KmdfCallbackRoutine { + KmdfEVTWdfWorkitem() { callbackType.getName().matches("EVT_WDF_WORKITEM") } +} + +/** + * A KMDF callback routine, defined by having a typedef in its definition + * that matches the standard KMDF callbacks. + */ +class KmdfCallbackRoutine extends Function { + /** The typedef representing what callback this is. */ + KmdfRoleTypeType callbackType; + + KmdfCallbackRoutine() { + exists(FunctionDeclarationEntry fde | + fde.getFunction() = this and + fde.getTypedefType() = callbackType and + fde.getFile().getAnIncludedFile().getBaseName().matches("%wdf.h") + ) + } +} + +/** The DeviceAdd callback. Its callback typedef is "EVT_WDF_DRIVER_DEVICE_ADD". */ +class KmdfEvtDriverDeviceAdd extends KmdfCallbackRoutine { + KmdfEvtDriverDeviceAdd() { callbackType.getName().matches("EVT_WDF_DRIVER_DEVICE_ADD") } +} + +/** + * A KMDF Function. This class is incomplete. It is used to represent a Function in the KMDF library. + */ +class KmdfFunc extends Function { + KmdfFunc() { this.getFile().getBaseName().matches("wdf%.h") } +} + +/** + * A KMDF Struct. This class is incomplete. It is used to represent a Struct in the KMDF library. + */ +class KmdfStruct extends Struct { + KmdfStruct() { this.getFile().getBaseName().matches("wdf%.h") } +} + +/* KMDF Structs */ +class KmdfWDFPowerRoutineTimedOutData extends KmdfStruct { + KmdfWDFPowerRoutineTimedOutData() { this.getName().matches("_WDF_POWER_ROUTINE_TIMED_OUT_DATA") } +} + +class KmdfWDFRequestFatalErrorInformationLengthMismatchData extends KmdfStruct { + KmdfWDFRequestFatalErrorInformationLengthMismatchData() { + this.getName().matches("_WDF_REQUEST_FATAL_ERROR_INFORMATION_LENGTH_MISMATCH_DATA") + } +} + +class KmdfWDFQueueFatalErrorData extends KmdfStruct { + KmdfWDFQueueFatalErrorData() { this.getName().matches("_WDF_QUEUE_FATAL_ERROR_DATA") } +} + +class KmdfWDFChildIdentificationDescriptionHeader extends KmdfStruct { + KmdfWDFChildIdentificationDescriptionHeader() { + this.getName().matches("_WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER") + } +} + +class KmdfWDFChildAddressDescriptionHeader extends KmdfStruct { + KmdfWDFChildAddressDescriptionHeader() { + this.getName().matches("_WDF_CHILD_ADDRESS_DESCRIPTION_HEADER") + } +} + +class KmdfWDFChildRetrieveInfo extends KmdfStruct { + KmdfWDFChildRetrieveInfo() { this.getName().matches("_WDF_CHILD_RETRIEVE_INFO") } +} + +class KmdfWDFChildListConfig extends KmdfStruct { + KmdfWDFChildListConfig() { this.getName().matches("_WDF_CHILD_LIST_CONFIG") } +} + +class KmdfWDFChildListIterator extends KmdfStruct { + KmdfWDFChildListIterator() { this.getName().matches("_WDF_CHILD_LIST_ITERATOR") } +} + +class KmdfWDFCommonBufferConfig extends KmdfStruct { + KmdfWDFCommonBufferConfig() { this.getName().matches("_WDF_COMMON_BUFFER_CONFIG") } +} + +class KmdfWDFTaskSendOptions extends KmdfStruct { + KmdfWDFTaskSendOptions() { this.getName().matches("_WDF_TASK_SEND_OPTIONS") } +} + +class KmdfWDFFileobjectConfig extends KmdfStruct { + KmdfWDFFileobjectConfig() { this.getName().matches("_WDF_FILEOBJECT_CONFIG") } +} + +class KmdfWDFDevicePnpNotificationData extends KmdfStruct { + KmdfWDFDevicePnpNotificationData() { this.getName().matches("_WDF_DEVICE_PNP_NOTIFICATION_DATA") } +} + +class KmdfWDFDevicePowerNotificationData extends KmdfStruct { + KmdfWDFDevicePowerNotificationData() { + this.getName().matches("_WDF_DEVICE_POWER_NOTIFICATION_DATA") + } +} + +class KmdfWDFDevicePowerPolicyNotificationData extends KmdfStruct { + KmdfWDFDevicePowerPolicyNotificationData() { + this.getName().matches("_WDF_DEVICE_POWER_POLICY_NOTIFICATION_DATA") + } +} + +class KmdfWDFPnppowerEventCallbacks extends KmdfStruct { + KmdfWDFPnppowerEventCallbacks() { this.getName().matches("_WDF_PNPPOWER_EVENT_CALLBACKS") } +} + +class KmdfWDFPowerPolicyEventCallbacks extends KmdfStruct { + KmdfWDFPowerPolicyEventCallbacks() { this.getName().matches("_WDF_POWER_POLICY_EVENT_CALLBACKS") } +} + +class KmdfWDFDevicePowerPolicyIdleSettings extends KmdfStruct { + KmdfWDFDevicePowerPolicyIdleSettings() { + this.getName().matches("_WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS") + } +} + +class KmdfWDFDevicePowerPolicyWakeSettings extends KmdfStruct { + KmdfWDFDevicePowerPolicyWakeSettings() { + this.getName().matches("_WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS") + } +} + +class KmdfWDFDeviceState extends KmdfStruct { + KmdfWDFDeviceState() { this.getName().matches("_WDF_DEVICE_STATE") } +} + +class KmdfWDFDevicePnpCapabilities extends KmdfStruct { + KmdfWDFDevicePnpCapabilities() { this.getName().matches("_WDF_DEVICE_PNP_CAPABILITIES") } +} + +class KmdfWDFDevicePowerCapabilities extends KmdfStruct { + KmdfWDFDevicePowerCapabilities() { this.getName().matches("_WDF_DEVICE_POWER_CAPABILITIES") } +} + +class KmdfWDFRemoveLockOptions extends KmdfStruct { + KmdfWDFRemoveLockOptions() { this.getName().matches("_WDF_REMOVE_LOCK_OPTIONS") } +} + +class KmdfWDFPowerFrameworkSettings extends KmdfStruct { + KmdfWDFPowerFrameworkSettings() { this.getName().matches("_WDF_POWER_FRAMEWORK_SETTINGS") } +} + +class KmdfWDFIoTypeConfig extends KmdfStruct { + KmdfWDFIoTypeConfig() { this.getName().matches("_WDF_IO_TYPE_CONFIG") } +} + +class KmdfWDFDevicePropertyData extends KmdfStruct { + KmdfWDFDevicePropertyData() { this.getName().matches("_WDF_DEVICE_PROPERTY_DATA") } +} + +class KmdfWDFDmaEnablerConfig extends KmdfStruct { + KmdfWDFDmaEnablerConfig() { this.getName().matches("_WDF_DMA_ENABLER_CONFIG") } +} + +class KmdfWDFDmaSystemProfileConfig extends KmdfStruct { + KmdfWDFDmaSystemProfileConfig() { this.getName().matches("_WDF_DMA_SYSTEM_PROFILE_CONFIG") } +} + +class KmdfWDFDpcConfig extends KmdfStruct { + KmdfWDFDpcConfig() { this.getName().matches("_WDF_DPC_CONFIG") } +} + +class KmdfWDFDriverConfig extends KmdfStruct { + KmdfWDFDriverConfig() { this.getName().matches("_WDF_DRIVER_CONFIG") } +} + +class KmdfWDFDriverVersionAvailableParams extends KmdfStruct { + KmdfWDFDriverVersionAvailableParams() { + this.getName().matches("_WDF_DRIVER_VERSION_AVAILABLE_PARAMS") + } +} + +class KmdfWDFFdoEventCallbacks extends KmdfStruct { + KmdfWDFFdoEventCallbacks() { this.getName().matches("_WDF_FDO_EVENT_CALLBACKS") } +} + +class KmdfWDFDriverGlobals extends KmdfStruct { + KmdfWDFDriverGlobals() { this.getName().matches("_WDF_DRIVER_GLOBALS") } +} + +class KmdfWDFCoinstallerInstallOptions extends KmdfStruct { + KmdfWDFCoinstallerInstallOptions() { this.getName().matches("_WDF_COINSTALLER_INSTALL_OPTIONS") } +} + +class KmdfWDFInterruptConfig extends KmdfStruct { + KmdfWDFInterruptConfig() { this.getName().matches("_WDF_INTERRUPT_CONFIG") } +} + +class KmdfWDFInterruptInfo extends KmdfStruct { + KmdfWDFInterruptInfo() { this.getName().matches("_WDF_INTERRUPT_INFO") } +} + +class KmdfWDFInterruptExtendedPolicy extends KmdfStruct { + KmdfWDFInterruptExtendedPolicy() { this.getName().matches("_WDF_INTERRUPT_EXTENDED_POLICY") } +} + +class KmdfWDFIoQueueConfig extends KmdfStruct { + KmdfWDFIoQueueConfig() { this.getName().matches("_WDF_IO_QUEUE_CONFIG") } +} + +class KmdfWDFIoQueueForwardProgressPolicy extends KmdfStruct { + KmdfWDFIoQueueForwardProgressPolicy() { + this.getName().matches("_WDF_IO_QUEUE_FORWARD_PROGRESS_POLICY") + } +} + +class KmdfWDFIoTargetOpenParams extends KmdfStruct { + KmdfWDFIoTargetOpenParams() { this.getName().matches("_WDF_IO_TARGET_OPEN_PARAMS") } +} + +class KmdfWDFMEMORYOffset extends KmdfStruct { + KmdfWDFMEMORYOffset() { this.getName().matches("_WDFMEMORY_OFFSET") } +} + +class KmdfWDFMemoryDescriptor extends KmdfStruct { + KmdfWDFMemoryDescriptor() { this.getName().matches("_WDF_MEMORY_DESCRIPTOR") } +} + +class KmdfWDFObjectAttributes extends KmdfStruct { + KmdfWDFObjectAttributes() { this.getName().matches("_WDF_OBJECT_ATTRIBUTES") } +} + +class KmdfWDFObjectContextTypeInfo extends KmdfStruct { + KmdfWDFObjectContextTypeInfo() { this.getName().matches("_WDF_OBJECT_CONTEXT_TYPE_INFO") } +} + +class KmdfWDFCustomTypeContext extends KmdfStruct { + KmdfWDFCustomTypeContext() { this.getName().matches("_WDF_CUSTOM_TYPE_CONTEXT") } +} + +class KmdfWDFPdoEventCallbacks extends KmdfStruct { + KmdfWDFPdoEventCallbacks() { this.getName().matches("_WDF_PDO_EVENT_CALLBACKS") } +} + +class KmdfWDFQueryInterfaceConfig extends KmdfStruct { + KmdfWDFQueryInterfaceConfig() { this.getName().matches("_WDF_QUERY_INTERFACE_CONFIG") } +} + +class KmdfWDFRequestParameters extends KmdfStruct { + KmdfWDFRequestParameters() { this.getName().matches("_WDF_REQUEST_PARAMETERS") } +} + +class KmdfWDFRequestCompletionParams extends KmdfStruct { + KmdfWDFRequestCompletionParams() { this.getName().matches("_WDF_REQUEST_COMPLETION_PARAMS") } +} + +class KmdfWDFRequestReuseParams extends KmdfStruct { + KmdfWDFRequestReuseParams() { this.getName().matches("_WDF_REQUEST_REUSE_PARAMS") } +} + +class KmdfWDFRequestSendOptions extends KmdfStruct { + KmdfWDFRequestSendOptions() { this.getName().matches("_WDF_REQUEST_SEND_OPTIONS") } +} + +class KmdfWDFRequestForwardOptions extends KmdfStruct { + KmdfWDFRequestForwardOptions() { this.getName().matches("_WDF_REQUEST_FORWARD_OPTIONS") } +} + +class KmdfWDFTimerConfig extends KmdfStruct { + KmdfWDFTimerConfig() { this.getName().matches("_WDF_TIMER_CONFIG") } +} + +class KmdfWDFUsbRequestCompletionParams extends KmdfStruct { + KmdfWDFUsbRequestCompletionParams() { + this.getName().matches("_WDF_USB_REQUEST_COMPLETION_PARAMS") + } +} + +class KmdfWDFUsbContinuousReaderConfig extends KmdfStruct { + KmdfWDFUsbContinuousReaderConfig() { this.getName().matches("_WDF_USB_CONTINUOUS_READER_CONFIG") } +} + +class KmdfWDFUsbDeviceInformation extends KmdfStruct { + KmdfWDFUsbDeviceInformation() { this.getName().matches("_WDF_USB_DEVICE_INFORMATION") } +} + +class KmdfWDFUsbInterfaceSettingPair extends KmdfStruct { + KmdfWDFUsbInterfaceSettingPair() { this.getName().matches("_WDF_USB_INTERFACE_SETTING_PAIR") } +} + +class KmdfWDFUsbDeviceSelectConfigParams extends KmdfStruct { + KmdfWDFUsbDeviceSelectConfigParams() { + this.getName().matches("_WDF_USB_DEVICE_SELECT_CONFIG_PARAMS") + } +} + +class KmdfWDFUsbInterfaceSelectSettingParams extends KmdfStruct { + KmdfWDFUsbInterfaceSelectSettingParams() { + this.getName().matches("_WDF_USB_INTERFACE_SELECT_SETTING_PARAMS") + } +} + +class KmdfWDFUsbPipeInformation extends KmdfStruct { + KmdfWDFUsbPipeInformation() { this.getName().matches("_WDF_USB_PIPE_INFORMATION") } +} + +class KmdfWDFUsbDeviceCreateConfig extends KmdfStruct { + KmdfWDFUsbDeviceCreateConfig() { this.getName().matches("_WDF_USB_DEVICE_CREATE_CONFIG") } +} + +class KmdfWDFWmiProviderConfig extends KmdfStruct { + KmdfWDFWmiProviderConfig() { this.getName().matches("_WDF_WMI_PROVIDER_CONFIG") } +} + +class KmdfWDFWmiInstanceConfig extends KmdfStruct { + KmdfWDFWmiInstanceConfig() { this.getName().matches("_WDF_WMI_INSTANCE_CONFIG") } +} + +class KmdfWDFWorkitemConfig extends KmdfStruct { + KmdfWDFWorkitemConfig() { this.getName().matches("_WDF_WORKITEM_CONFIG") } +} diff --git a/src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.qhelp b/codeql/src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.qhelp similarity index 100% rename from src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.qhelp rename to codeql/src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.qhelp diff --git a/src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.ql b/codeql/src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.ql similarity index 100% rename from src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.ql rename to codeql/src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.ql diff --git a/src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.sarif b/codeql/src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.sarif similarity index 100% rename from src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.sarif rename to codeql/src/drivers/kmdf/queries/FloatSafeExit/FloatSafeExit.sarif diff --git a/src/drivers/kmdf/queries/FloatSafeExit/driver_snippet.c b/codeql/src/drivers/kmdf/queries/FloatSafeExit/driver_snippet.c similarity index 100% rename from src/drivers/kmdf/queries/FloatSafeExit/driver_snippet.c rename to codeql/src/drivers/kmdf/queries/FloatSafeExit/driver_snippet.c diff --git a/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.qhelp b/codeql/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.qhelp similarity index 100% rename from src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.qhelp rename to codeql/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.qhelp diff --git a/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.ql b/codeql/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.ql similarity index 100% rename from src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.ql rename to codeql/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.ql diff --git a/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.sarif b/codeql/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.sarif similarity index 100% rename from src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.sarif rename to codeql/src/drivers/kmdf/queries/FloatUnsafeExit/FloatUnsafeExit.sarif diff --git a/src/drivers/kmdf/queries/FloatUnsafeExit/driver_snippet.c b/codeql/src/drivers/kmdf/queries/FloatUnsafeExit/driver_snippet.c similarity index 100% rename from src/drivers/kmdf/queries/FloatUnsafeExit/driver_snippet.c rename to codeql/src/drivers/kmdf/queries/FloatUnsafeExit/driver_snippet.c diff --git a/src/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.ql b/codeql/src/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.ql similarity index 100% rename from src/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.ql rename to codeql/src/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.ql diff --git a/src/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.sarif b/codeql/src/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.sarif similarity index 100% rename from src/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.sarif rename to codeql/src/drivers/kmdf/queries/experimental/DeviceInitApi/DeviceInitApi.sarif diff --git a/src/drivers/kmdf/queries/experimental/DeviceInitApi/__test_device_init_api.c b/codeql/src/drivers/kmdf/queries/experimental/DeviceInitApi/__test_device_init_api.c similarity index 100% rename from src/drivers/kmdf/queries/experimental/DeviceInitApi/__test_device_init_api.c rename to codeql/src/drivers/kmdf/queries/experimental/DeviceInitApi/__test_device_init_api.c diff --git a/src/drivers/kmdf/queries/experimental/DeviceInitApi/driver_snippet.c b/codeql/src/drivers/kmdf/queries/experimental/DeviceInitApi/driver_snippet.c similarity index 100% rename from src/drivers/kmdf/queries/experimental/DeviceInitApi/driver_snippet.c rename to codeql/src/drivers/kmdf/queries/experimental/DeviceInitApi/driver_snippet.c diff --git a/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectHandleCreation.qlhelp b/codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectHandleCreation.qlhelp similarity index 100% rename from src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectHandleCreation.qlhelp rename to codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectHandleCreation.qlhelp diff --git a/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectHandleCreation.sarif b/codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectHandleCreation.sarif similarity index 100% rename from src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectHandleCreation.sarif rename to codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectHandleCreation.sarif diff --git a/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectMultipleCallsHandleCreation.ql b/codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectMultipleCallsHandleCreation.ql similarity index 100% rename from src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectMultipleCallsHandleCreation.ql rename to codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/ConnectRedirectMultipleCallsHandleCreation.ql diff --git a/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/driver_snippet.c b/codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/driver_snippet.c similarity index 100% rename from src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/driver_snippet.c rename to codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectHandleCreation/driver_snippet.c diff --git a/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.ql b/codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.ql similarity index 100% rename from src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.ql rename to codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.ql diff --git a/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.qlhelp b/codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.qlhelp similarity index 100% rename from src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.qlhelp rename to codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.qlhelp diff --git a/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.sarif b/codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.sarif similarity index 100% rename from src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.sarif rename to codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/ConnectRedirectPendClassify.sarif diff --git a/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/driver_snippet.c b/codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/driver_snippet.c similarity index 100% rename from src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/driver_snippet.c rename to codeql/src/drivers/kmdf/queries/wfp/ConnectRedirectPendClassify/driver_snippet.c diff --git a/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.ql b/codeql/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.ql similarity index 100% rename from src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.ql rename to codeql/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.ql diff --git a/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.qlhelp b/codeql/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.qlhelp similarity index 100% rename from src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.qlhelp rename to codeql/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.qlhelp diff --git a/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.sarif b/codeql/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.sarif similarity index 100% rename from src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.sarif rename to codeql/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/FlowLayerCalloutReturnsBlock.sarif diff --git a/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/driver_snippet.c b/codeql/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/driver_snippet.c similarity index 100% rename from src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/driver_snippet.c rename to codeql/src/drivers/kmdf/queries/wfp/FlowLayerCalloutReturnsBlock/driver_snippet.c diff --git a/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.ql b/codeql/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.ql similarity index 100% rename from src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.ql rename to codeql/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.ql diff --git a/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.qlhelp b/codeql/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.qlhelp similarity index 100% rename from src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.qlhelp rename to codeql/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.qlhelp diff --git a/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.sarif b/codeql/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.sarif similarity index 100% rename from src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.sarif rename to codeql/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/InlineConnectRedirectCalloutShouldNotSetReauthorize.sarif diff --git a/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/driver_snippet.c b/codeql/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/driver_snippet.c similarity index 100% rename from src/drivers/kmdf/queries/wfp/InlineConnectRedirect/driver_snippet.c rename to codeql/src/drivers/kmdf/queries/wfp/InlineConnectRedirect/driver_snippet.c diff --git a/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.ql b/codeql/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.ql similarity index 100% rename from src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.ql rename to codeql/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.ql diff --git a/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.qlhelp b/codeql/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.qlhelp similarity index 100% rename from src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.qlhelp rename to codeql/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.qlhelp diff --git a/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.sarif b/codeql/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.sarif similarity index 100% rename from src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.sarif rename to codeql/src/drivers/kmdf/queries/wfp/OobStreamInjection/OobStreamInjectionReturnsBlock.sarif diff --git a/src/drivers/kmdf/queries/wfp/OobStreamInjection/driver_snippet.c b/codeql/src/drivers/kmdf/queries/wfp/OobStreamInjection/driver_snippet.c similarity index 100% rename from src/drivers/kmdf/queries/wfp/OobStreamInjection/driver_snippet.c rename to codeql/src/drivers/kmdf/queries/wfp/OobStreamInjection/driver_snippet.c diff --git a/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutSetActionType.qlhelp b/codeql/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutSetActionType.qlhelp similarity index 100% rename from src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutSetActionType.qlhelp rename to codeql/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutSetActionType.qlhelp diff --git a/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutSetActionType.sarif b/codeql/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutSetActionType.sarif similarity index 100% rename from src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutSetActionType.sarif rename to codeql/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutSetActionType.sarif diff --git a/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutsSetActionType.ql b/codeql/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutsSetActionType.ql similarity index 100% rename from src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutsSetActionType.ql rename to codeql/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/StreamCalloutsSetActionType.ql diff --git a/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/driver_snippet.c b/codeql/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/driver_snippet.c similarity index 100% rename from src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/driver_snippet.c rename to codeql/src/drivers/kmdf/queries/wfp/StreamCalloutsSetActionType/driver_snippet.c diff --git a/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.ql b/codeql/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.ql similarity index 100% rename from src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.ql rename to codeql/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.ql diff --git a/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.qlhelp b/codeql/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.qlhelp similarity index 100% rename from src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.qlhelp rename to codeql/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.qlhelp diff --git a/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.sarif b/codeql/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.sarif similarity index 100% rename from src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.sarif rename to codeql/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/StreamInspectionFunctionCallViolation.sarif diff --git a/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/driver_snippet.c b/codeql/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/driver_snippet.c similarity index 100% rename from src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/driver_snippet.c rename to codeql/src/drivers/kmdf/queries/wfp/StreamInspectionCallViolation/driver_snippet.c diff --git a/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.ql b/codeql/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.ql similarity index 100% rename from src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.ql rename to codeql/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.ql diff --git a/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.qlhelp b/codeql/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.qlhelp similarity index 100% rename from src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.qlhelp rename to codeql/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringClassify.qlhelp diff --git a/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringclassify.sarif b/codeql/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringclassify.sarif similarity index 100% rename from src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringclassify.sarif rename to codeql/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/TransportLayerCannotInjectCloneDuringclassify.sarif diff --git a/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/driver_snippet.c b/codeql/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/driver_snippet.c similarity index 100% rename from src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/driver_snippet.c rename to codeql/src/drivers/kmdf/queries/wfp/TransportLayerCannotInjectCloneDuringClassify/driver_snippet.c diff --git a/src/drivers/libraries/DriverIsolation.qll b/codeql/src/drivers/libraries/DriverIsolation.qll similarity index 100% rename from src/drivers/libraries/DriverIsolation.qll rename to codeql/src/drivers/libraries/DriverIsolation.qll diff --git a/src/drivers/libraries/Irql.qll b/codeql/src/drivers/libraries/Irql.qll similarity index 97% rename from src/drivers/libraries/Irql.qll rename to codeql/src/drivers/libraries/Irql.qll index 19907787..45b3e630 100644 --- a/src/drivers/libraries/Irql.qll +++ b/codeql/src/drivers/libraries/Irql.qll @@ -1,886 +1,886 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -/** - * Provides classes related to calculating and estimating the IRQL in a Windows device driver. - * - * For best results, this library expects to be used in tandem with IRQL annotations. A limited - * amount of functionality is still present even when no annotations are present, primarily around - * measuring direct calls to KeRaiseIrql and KeLowerIrql. - * - * Much of this library's analysis is intraprocedural or limited interprocedural, using a simple - * analysis based on call sites to a given function. Full interprocedural analysis that relies on the - * implicit behaviors of the WDM driver model, etc. is not yet supported. - */ - - import cpp - import drivers.libraries.SAL - import drivers.wdm.libraries.WdmDrivers - import drivers.libraries.IrqlDataFlow - import drivers.libraries.Page - import drivers.libraries.RoleTypes - - - - - /** - * A macro in wdm.h that represents an IRQL level, - * such as PASSIVE_LEVEL, DISPATCH_LEVEL, etc. - */ - - class IrqlMacro extends Macro { - int irqlLevelAsInt; - - - IrqlMacro() { - this.getName().matches("%_LEVEL") and - this.getFile().getBaseName() = "wdm.h" and - this.getBody().toInt() = irqlLevelAsInt and - irqlLevelAsInt >= 0 and - irqlLevelAsInt <= 31 - } - - /** Returns the integer value of this IRQL level. */ - - int getIrqlLevel() { result = irqlLevelAsInt } - } - - /** - * Returns the highest IRQL in wdm.h across this database. - * May cause incorrect results if database contains both 32-bit - * and 64-bit builds. - */ - - int getGlobalMaxIrqlLevel() { - result = - any(int i | - exists(IrqlMacro im | - i = im.getIrqlLevel() and - not exists(IrqlMacro im2 | im2 != im and im2.getIrqlLevel() > im.getIrqlLevel()) - ) - ) - } - - /** - * Represents a real (not -1) Irql level, between 0 and the max for the architecture this - * database was built to target. - */ - class IrqlValue extends int { - IrqlValue() { this = [0 .. getGlobalMaxIrqlLevel()] } - } - - /** An \_IRQL\_saves\_global\_(parameter, kind) annotation. */ - - class IrqlSavesGlobalAnnotation extends SALAnnotation { - MacroInvocation irqlMacroInvocation; - - - IrqlSavesGlobalAnnotation() { - // Needs to include other function and parameter annotations too - this.getMacroName() = ["__drv_savesIRQLGlobal", "_IRQL_saves_global_"] and - irqlMacroInvocation.getParentInvocation() = this - } - } - - /** An \_IRQL\_restores\_global\_(parameter, kind) annotation. */ - - class IrqlRestoresGlobalAnnotation extends SALAnnotation { - MacroInvocation irqlMacroInvocation; - - - IrqlRestoresGlobalAnnotation() { - // Needs to include other function and parameter annotations too - this.getMacroName() = ["__drv_restoresIRQLGlobal", "_IRQL_restores_global_"] and - irqlMacroInvocation.getParentInvocation() = this - } - } - - /** - * Standard IRQL annotations which apply to entire functions and manipulate or constrain the IRQL. - */ - - class IrqlFunctionAnnotation extends SALAnnotation { - string irqlLevel; - string irqlAnnotationName; - string innerAnnotationName; - string fullInnerAnnotationString; - - - IrqlFunctionAnnotation() { - ( - this.getMacroName() = - [ - "__drv_requiresIRQL", "_IRQL_requires_", "_drv_minIRQL", "_IRQL_requires_min_", - "_drv_maxIRQL", "_IRQL_requires_max_", "__drv_raisesIRQL", "_IRQL_raises_", - "__drv_maxFunctionIRQL", "_IRQL_always_function_max_", "__drv_minFunctionIRQL", - "_IRQL_always_function_min_" - ] and - irqlLevel = this.getUnexpandedArgument(0) and - innerAnnotationName = this.getMacroName() and - fullInnerAnnotationString = this.getMacroName() + "(" + irqlLevel + ")" - or - // Special case: _IRQL_saves_ annotations can apply to a whole function, - // but do not have an associated IRQL value. - this.getMacroName() = ["__drv_savesIRQL", "_IRQL_saves_"] and - irqlLevel = "NA_IRQL_SAVES" and - innerAnnotationName = this.getMacroName() and - fullInnerAnnotationString = this.getMacroName() + "(" + irqlLevel + ")" - or - // // Conditional IRQL annotations within a _When_ annotation - this.getMacroName() = ["_When_"] and - fullInnerAnnotationString = this.getUnexpandedArgument(1).toString() and - ( - fullInnerAnnotationString.matches("__drv_requiresIRQL%") and - innerAnnotationName = "__drv_requiresIRQL" - or - fullInnerAnnotationString.matches("_IRQL_requires_%") and - innerAnnotationName = "_IRQL_requires_" - or - fullInnerAnnotationString.matches("_drv_minIRQL%") and - innerAnnotationName = "_drv_minIRQL" - or - fullInnerAnnotationString.matches("_drv_maxIRQL%") and - innerAnnotationName = "_drv_maxIRQL" - or - fullInnerAnnotationString.matches("_IRQL_requires_max_%") and - innerAnnotationName = "_IRQL_requires_max_" - or - fullInnerAnnotationString.matches("_IRQL_raises_%") and - innerAnnotationName = "_IRQL_raises_" - or - fullInnerAnnotationString.matches("__drv_maxFunctionIRQL%") and - innerAnnotationName = "__drv_maxFunctionIRQL" - or - fullInnerAnnotationString.matches("_IRQL_always_function_max_%") and - innerAnnotationName = "_IRQL_always_function_max_" - or - fullInnerAnnotationString.matches("__drv_minFunctionIRQL%") and - innerAnnotationName = "__drv_minFunctionIRQL" - or - fullInnerAnnotationString.matches("_IRQL_always_function_min_%") and - innerAnnotationName = "_IRQL_always_function_min_" - ) and - irqlLevel = - fullInnerAnnotationString - .substring(fullInnerAnnotationString.indexOf(innerAnnotationName + "(") + 1 + - innerAnnotationName.length(), - fullInnerAnnotationString - .indexOf(")", 0, - fullInnerAnnotationString.indexOf(innerAnnotationName + "(") + 1 + - innerAnnotationName.length())) - ) and - irqlAnnotationName = this.getMacroName() - } - - /** Returns the text of this annotation (i.e. \_IRQL\_requires\_, etc.) */ - - string getIrqlMacroName() { - if this.getMacroName() = ["_When_"] - then result = innerAnnotationName - else result = irqlAnnotationName - } - - - string getIrqlLevelString() { result = irqlLevel } - - /** - * Evaluate the IRQL specified in this annotation, if possible. - * - * This will return -1 if the IRQL specified is anything other than a standard - * IRQL level (i.e. PASSIVE_LEVEL). This includes statements like "DPC_LEVEL - 1". - */ - - int getIrqlLevel() { - // Special case for DPC_LEVEL, which is not defined normally - if this.getIrqlLevelString() = "DPC_LEVEL" - then result = 2 - else - if exists(IrqlMacro im | im.getHead().matches(this.getIrqlLevelString())) - then - result = - any(int i | - exists(IrqlMacro im | - im.getIrqlLevel() = i and - im.getHead().matches(this.getIrqlLevelString()) - ) - ) - else - if exists(int i | i = this.getIrqlLevelString().toInt()) - then result = this.getIrqlLevelString().toInt() - else result = -1 - } - } - - /** Represents an "\_IRQL\_requires\_same\_" annotation. */ - class IrqlSameAnnotation extends SALAnnotation { - string irqlAnnotationName; - - IrqlSameAnnotation() { - this.getMacroName() = ["__drv_sameIRQL", "_IRQL_requires_same_"] and - irqlAnnotationName = this.getMacroName() - } - - string getIrqlMacroName() { result = irqlAnnotationName } - } - - /** An "\_IRQL\_requires\_max\_" annotation. */ - class IrqlMaxAnnotation extends IrqlFunctionAnnotation { - IrqlMaxAnnotation() { this.getIrqlMacroName() = ["_drv_maxIRQL", "_IRQL_requires_max_"] } - } - - /** An "\_IRQL\_raises\_" annotation. */ - class IrqlRaisesAnnotation extends IrqlFunctionAnnotation { - IrqlRaisesAnnotation() { this.getIrqlMacroName() = ["__drv_raisesIRQL", "_IRQL_raises_"] } - } - - /** An "\_IRQL\_requires\_min\_" annotation. */ - class IrqlMinAnnotation extends IrqlFunctionAnnotation { - IrqlMinAnnotation() { this.getIrqlMacroName() = ["_drv_minIRQL", "_IRQL_requires_min_"] } - } - - /** An "\_IRQL\_requires\_" annotation. */ - class IrqlRequiresAnnotation extends IrqlFunctionAnnotation { - IrqlRequiresAnnotation() { this.getIrqlMacroName() = ["__drv_requiresIRQL", "_IRQL_requires_"] } - } - - /** An "\_IRQL\_always\_function\_max\_" annotation. */ - class IrqlAlwaysMaxAnnotation extends IrqlFunctionAnnotation { - IrqlAlwaysMaxAnnotation() { - this.getIrqlMacroName() = ["__drv_maxFunctionIRQL", "_IRQL_always_function_max_"] - } - } - - /** An "\_IRQL\_always\_function\_min\_" annotation. */ - class IrqlAlwaysMinAnnotation extends IrqlFunctionAnnotation { - IrqlAlwaysMinAnnotation() { - this.getIrqlMacroName() = ["__drv_minFunctionIRQL", "_IRQL_always_function_min_"] - } - } - - /** - * A SAL annotation indicating that the parameter in - * question is used to store or restore the IRQL. - */ - class IrqlParameterAnnotation extends SALAnnotation { - string irqlAnnotationName; - - IrqlParameterAnnotation() { - this.getMacroName() = - ["__drv_restoresIRQL", "_IRQL_restores_", "__drv_savesIRQL", "_IRQL_saves_"] and - irqlAnnotationName = this.getMacroName() and - exists(MacroInvocation mi | mi.getParentInvocation() = this) - } - - /** Get the text of the annotation. */ - string getIrqlMacroName() { result = irqlAnnotationName } - } - - /** - * A SAL annotation indicating that the parameter in - * question contains an IRQL value that the system will be set to. - */ - class IrqlRestoreAnnotation extends IrqlParameterAnnotation { - IrqlRestoreAnnotation() { this.getMacroName() = ["__drv_restoresIRQL", "_IRQL_restores_"] } - } - - /** - * A SAL annotation indicating that can be used in two ways: - * - If applied to a function, the function returns the previous IRQL or otherwise saves the IRQL. - * - If applied to a parameter, the function saves the IRQL to the parameter. - */ - class IrqlSaveAnnotation extends IrqlFunctionAnnotation { - IrqlSaveAnnotation() { this.getIrqlMacroName() = ["__drv_savesIRQL", "_IRQL_saves_"] } - } - - /** A parameter that is annotated with "\_IRQL\_restores\_". */ - class IrqlRestoreParameter extends Parameter { - IrqlRestoreParameter() { exists(IrqlRestoreAnnotation ira | ira.getDeclaration() = this) } - } - - /** A parameter that is annotated with "\_IRQL\_saves\_". */ - class IrqlSaveParameter extends Parameter { - IrqlSaveParameter() { exists(IrqlSaveAnnotation isa | isa.getDeclaration() = this) } - } - - /** A typedef that has IRQL annotations applied to it. */ - class IrqlAnnotatedTypedef extends TypedefType { - IrqlFunctionAnnotation irqlAnnotation; - - IrqlAnnotatedTypedef() { irqlAnnotation.getTypedefDeclarations() = this } - - IrqlFunctionAnnotation getIrqlAnnotation() { result = irqlAnnotation } - } - - /** - * A function that is annotated in such a way that - * either its entry or exit IRQL is restricted, either by having a min/max value, - * a required value, or by raising the IRQL to a known value. - */ - - class IrqlRestrictsFunction extends Function { - IrqlFunctionAnnotation irqlAnnotation; - - - IrqlRestrictsFunction() { - exists(FunctionDeclarationEntry fde | - fde = this.getADeclarationEntry() and - irqlAnnotation.getDeclarationEntry() = fde - ) - or - exists(FunctionDeclarationEntry fde | - fde.getFunction() = this and - fde.getTypedefType().(IrqlAnnotatedTypedef).getIrqlAnnotation() = irqlAnnotation - ) - or - exists(ImplicitRoleTypeFunction irtf | - irtf = this and - irtf.getExpectedRoleTypeType().(IrqlAnnotatedTypedef).getIrqlAnnotation() = irqlAnnotation - ) - } - - - IrqlFunctionAnnotation getFuncIrqlAnnotation() { result = irqlAnnotation } - } - - /** A function that changes the IRQL. */ - abstract class IrqlChangesFunction extends Function { } - - /** A function that is explicitly annotated to enter and exit at the same IRQL. */ - class IrqlRequiresSameAnnotatedFunction extends Function { - IrqlSameAnnotation irqlAnnotation; - - IrqlRequiresSameAnnotatedFunction() { - exists(FunctionDeclarationEntry fde | - fde = this.getADeclarationEntry() and - irqlAnnotation.getDeclarationEntry() = fde - ) - } - } - - /** A function that is annotated to run at a specific IRQL. */ - class IrqlRequiresAnnotatedFunction extends IrqlRestrictsFunction { - IrqlRequiresAnnotatedFunction() { irqlAnnotation instanceof IrqlRequiresAnnotation } - - int getIrqlLevel() { result = irqlAnnotation.(IrqlRequiresAnnotation).getIrqlLevel() } - } - - /** A function that is annotated to enter at or below a given IRQL. */ - class IrqlMaxAnnotatedFunction extends IrqlRestrictsFunction { - IrqlMaxAnnotatedFunction() { irqlAnnotation instanceof IrqlMaxAnnotation } - - int getIrqlLevel() { result = irqlAnnotation.(IrqlMaxAnnotation).getIrqlLevel() } - } - - /** A function that is annotated to enter at or above a given IRQL. */ - class IrqlMinAnnotatedFunction extends IrqlRestrictsFunction { - IrqlMinAnnotatedFunction() { irqlAnnotation instanceof IrqlMinAnnotation } - - int getIrqlLevel() { result = irqlAnnotation.(IrqlMinAnnotation).getIrqlLevel() } - } - - /** A function that is annotated to raise the IRQL to a given value. */ - class IrqlRaisesAnnotatedFunction extends IrqlRestrictsFunction, IrqlChangesFunction { - IrqlRaisesAnnotatedFunction() { irqlAnnotation instanceof IrqlRaisesAnnotation } - - int getIrqlLevel() { result = irqlAnnotation.(IrqlRaisesAnnotation).getIrqlLevel() } - } - - /** A function that is never allowed to run with the IRQL above a given value. */ - class IrqlAlwaysMaxFunction extends IrqlRestrictsFunction { - IrqlAlwaysMaxFunction() { irqlAnnotation instanceof IrqlAlwaysMaxAnnotation } - - int getIrqlLevel() { result = irqlAnnotation.(IrqlAlwaysMaxAnnotation).getIrqlLevel() } - } - - /** A function that is never allowed to run with the IRQL above a given value. */ - class IrqlAlwaysMinFunction extends IrqlRestrictsFunction { - IrqlAlwaysMinFunction() { irqlAnnotation instanceof IrqlAlwaysMinAnnotation } - - int getIrqlLevel() { result = irqlAnnotation.(IrqlAlwaysMinAnnotation).getIrqlLevel() } - } - - /** A function annotated to save the IRQL at the specified location upon entry. */ - class IrqlSavesGlobalAnnotatedFunction extends IrqlChangesFunction { - IrqlSavesGlobalAnnotation irqlAnnotation; - string irqlKind; - int irqlParamIndex; - - IrqlSavesGlobalAnnotatedFunction() { - exists(FunctionDeclarationEntry fde | - fde = this.getADeclarationEntry() and - irqlAnnotation.getDeclarationEntry() = fde - ) and - irqlKind = irqlAnnotation.getExpandedArgument(0) and - this.getParameter(irqlParamIndex).getName().matches(irqlAnnotation.getExpandedArgument(1)) - } - - string getIrqlKind() { result = irqlKind } - - int getIrqlParameterSlot() { result = irqlParamIndex } - } - - /** A function annotated to restore the IRQL from the specified location upon exit. */ - class IrqlRestoresGlobalAnnotatedFunction extends IrqlChangesFunction { - IrqlRestoresGlobalAnnotation irqlAnnotation; - string irqlKind; - int irqlParamIndex; - - IrqlRestoresGlobalAnnotatedFunction() { - exists(FunctionDeclarationEntry fde | - fde = this.getADeclarationEntry() and - irqlAnnotation.getDeclarationEntry() = fde - ) and - irqlKind = irqlAnnotation.getExpandedArgument(0) and - this.getParameter(irqlParamIndex).getName().matches(irqlAnnotation.getExpandedArgument(1)) - } - - string getIrqlKind() { result = irqlKind } - - int getIrqlParameterSlot() { result = irqlParamIndex } - } - - /** - * An abstract class for functions that use the \_IRQL\_saves\_ annotation, - * either on the function definition or on a specific parameter. - */ - abstract class IrqlSavesFunction extends Function { } - - /** A function that has a parameter annotated \_IRQL\_saves\_. */ - class IrqlSavesToParameterFunction extends IrqlSavesFunction { - IrqlSaveParameter saveParameter; - int irqlParamIndex; - - IrqlSavesToParameterFunction() { this.getParameter(irqlParamIndex) = saveParameter } - - int getIrqlParameterSlot() { result = irqlParamIndex } - } - - /** A function that saves the IRQL as a return value. */ - class IrqlSavesViaReturnFunction extends IrqlSavesFunction { - IrqlSaveAnnotation irqlAnnotation; - - IrqlSavesViaReturnFunction() { - exists(FunctionDeclarationEntry fde | - fde = this.getADeclarationEntry() and - irqlAnnotation.getDeclarationEntry() = fde - ) - } - } - - /** A function that has a parameter annotated \_IRQL\_restores\_. */ - class IrqlRestoreAnnotatedFunction extends Function { - IrqlRestoreParameter restoreParameter; - int irqlParamIndex; - - IrqlRestoreAnnotatedFunction() { this.getParameter(irqlParamIndex) = restoreParameter } - - int getIrqlParameterSlot() { result = irqlParamIndex } - } - - /** A call to a function that has a parameter annotated \_IRQL\_restores\_. */ - class IrqlRestoreCall extends FunctionCall { - IrqlRestoreCall() { this.getTarget() instanceof IrqlRestoreAnnotatedFunction } - - /** - * A heuristic evaluation of the IRQL that the system is changing to. This is defined as - * "the IRQL before the corresponding save global call." - */ - int getIrqlLevel() { - result = any(getPotentialExitIrqlAtCfn(this.getMostRecentRaise().getAPredecessor())) - } - - int getIrqlLevelExplicit() { - result = any(getExplicitExitIrqlAtCfn(this.getMostRecentRaise().getAPredecessor())) - } - - /** Returns the matching call to a function that saved the IRQL. */ - IrqlSaveCall getMostRecentRaise() { - result = - any(IrqlSaveCall sgic | - this.getAPredecessor*() = sgic and - matchingSaveCall(sgic) and - not exists(SavesGlobalIrqlCall sgic2 | - sgic2 != sgic and sgic2.getAPredecessor*() = sgic and matchingSaveCall(sgic2) - ) - ) - } - - /** - * Holds if a given call to an \_IRQL\_saves\_global\_ annotated function is using the same IRQL location as this. - */ - private predicate matchingSaveCall(IrqlSaveCall sgic) { - // Attempting to match all expr children leads to an explosion in runtime, so for now just compare - // the expr itself and the first child of each argument. This covers the common &variable case. - exists(int i, int j | - i = this.getTarget().(IrqlRestoreAnnotatedFunction).getIrqlParameterSlot() and - j = sgic.getTarget().(IrqlSavesToParameterFunction).getIrqlParameterSlot() and - exprsMatchText(this.getArgument(i), sgic.getArgument(j)) - ) - or - exists(int i | - i = this.getTarget().(IrqlRestoreAnnotatedFunction).getIrqlParameterSlot() and - sgic.getTarget() instanceof IrqlSavesViaReturnFunction and - exprsMatchText(this.getArgument(i), sgic.getSavedValue()) - ) and - this.getControlFlowScope() = sgic.getControlFlowScope() - } - } - - /** A call to a function that has is annotated \_IRQL\_saves\_. */ - class IrqlSaveCall extends FunctionCall { - IrqlSaveCall() { this.getTarget() instanceof IrqlSavesFunction } - - Expr getSavedValue() { - result = - any(Expr e | - exists(AssignExpr ae | - ae.getLValue() = e and - ae.getRValue() = this and - this.getTarget() instanceof IrqlSavesViaReturnFunction - ) - ) - } - } - - /** A call to a KeRaiseIRQL API that directly raises the IRQL. */ - class KeRaiseIrqlCall extends FunctionCall { - KeRaiseIrqlCall() { - this.getTarget().getName() = - ["KeRaiseIrql", "KfRaiseIrql", "KeRaiseIrqlToDPCLevel", "KfRaiseIrqlToDPCLevel"] - } - - int getIrqlLevel() { - if this.getTarget().getName() = ["KeRaiseIrqlToDPCLevel", "KfRaiseIrqlToDPCLevel"] - then result = 2 - else result = this.getArgument(0).(Literal).getValue().toInt() - } - } - - /** A direct call to a function that lowers the IRQL. */ - class KeLowerIrqlCall extends FunctionCall { - KeLowerIrqlCall() { this.getTarget().getName() = ["KeLowerIrql", "KfLowerIrql"] } - - /** - * A heuristic evaluation of the IRQL that the system is lowering to. This is defined as - * "the IRQL before the most recent KeRaiseIrql call". - */ - int getIrqlLevel() { - result = - any(getPotentialExitIrqlAtCfn(this.getMostRecentRaiseInterprocedural().getAPredecessor())) - } - - int getIrqlLevelExplicit() { - result = - any(getExplicitExitIrqlAtCfn(this.getMostRecentRaiseInterprocedural().getAPredecessor())) - } - - /** - * Get the most recent KeRaiseIrql call before this call. - * - * This performs a local (intraprocedural) analysis only. It is unused in the library today, - * but can be inserted in place of the interprocedural analysis by modifying the getIrqlLevel() - * function above. - */ - KeRaiseIrqlCall getMostRecentRaise() { - result = - any(KeRaiseIrqlCall sgic | - this.getAPredecessor*() = sgic and - not exists(KeRaiseIrqlCall kric2 | kric2 != sgic and kric2.getAPredecessor*() = sgic) - ) - } - - - /** - * Get the corresponding KeRaiseIrql call that preceded this KeLowerIrql call. - * - * This performs an interprocedural analysis using CodeQL's DataFlow classes. - */ - KeRaiseIrqlCall getMostRecentRaiseInterprocedural() { - result = - any(KeRaiseIrqlCall kric | - IrqlRaiseLowerFlow::flow(DataFlow::exprNode(kric), DataFlow::exprNode(this.getAnArgument())) - ) - } - } - - /** A call to a function that restores the IRQL from a specified state. */ - class SavesGlobalIrqlCall extends FunctionCall { - SavesGlobalIrqlCall() { this.getTarget() instanceof IrqlSavesGlobalAnnotatedFunction } - } - - /** A call to a function that restores the IRQL from a specified state. */ - class RestoresGlobalIrqlCall extends FunctionCall { - RestoresGlobalIrqlCall() { this.getTarget() instanceof IrqlRestoresGlobalAnnotatedFunction } - - /** - * A heuristic evaluation of the IRQL that the system is changing to. This is defined as - * "the IRQL before the corresponding save global call." - */ - int getIrqlLevel() { - result = any(getPotentialExitIrqlAtCfn(this.getMostRecentRaise().getAPredecessor())) - } - - int getIrqlLevelExplicit() { - result = any(getExplicitExitIrqlAtCfn(this.getMostRecentRaise().getAPredecessor())) - } - - /** - * Returns the matching call to a function that saved the IRQL to a global state. - * - * This is a strictly intraprocedural analysis. - */ - SavesGlobalIrqlCall getMostRecentRaise() { - result = - any(SavesGlobalIrqlCall sgic | - this.getAPredecessor*() = sgic and - matchingSaveCall(sgic) and - not exists(SavesGlobalIrqlCall sgic2 | - sgic2 != sgic and sgic2.getAPredecessor*() = sgic and matchingSaveCall(sgic2) - ) - ) - } - - /** - * Holds if a given call to an _IRQL_saves_global_ annotated function is using the same IRQL location as this. - */ - private predicate matchingSaveCall(SavesGlobalIrqlCall sgic) { - // Attempting to match all expr children leads to an explosion in runtime, so for now just compare - // the expr itself and the first child of each argument. This covers the common &variable case. - exists(int i, int j | - i = this.getTarget().(IrqlRestoresGlobalAnnotatedFunction).getIrqlParameterSlot() and - j = sgic.getTarget().(IrqlSavesGlobalAnnotatedFunction).getIrqlParameterSlot() and - exprsMatchText(this.getArgument(i), sgic.getArgument(j)) - ) and - this.getTarget().(IrqlRestoresGlobalAnnotatedFunction).getIrqlKind() = - sgic.getTarget().(IrqlSavesGlobalAnnotatedFunction).getIrqlKind() - } - } - - /** - * A utility function to determine if two exprs are (textually) the same. - * Because checking all children of the expression causes an explosion in evaluation time, we just - * check the first child. - * - * This function is obviously _not_ a guarantee that two expressions refer to the same thing. - * Use this locally and with caution. - * - * TODO: Compare with global value numbering (both accuracy and performance) - */ - pragma[inline] - private predicate exprsMatchText(Expr e1, Expr e2) { - e1.toString().matches(e2.toString()) and - exists(Expr child | - child = e1.getAChild() and - e1.getChild(0).toString().matches(e2.getChild(0).toString()) - ) - or - not exists(Expr child | child = e1.getAChild() or child = e2.getAChild()) - } - - /** - * Attempt to provide the IRQL **once this control flow node exits**, based on annotations and direct calls to raising/lowering functions. - * This predicate functions as follows: - * - If calling a "Raise IRQL" function, then it returns the value of the argument passed in (the target IRQL). - * - If calling a "Lower IRQL" function, then it returns the value of the argument passed in (the target IRQL). - * - If calling a function annotated to restore the IRQL from a previously saved spot, then the result is the IRQL before that save call. - * - If calling a function annotated to raise the IRQL, then it returns the annotated value (the target IRQL). - * - If calling a function annotated to maintain the same IRQL, then the result is the IRQL at the previous CFN. - * - If this node is calling a function with no annotations, the result is the IRQL that function exits at. - * - If there is a prior CFN in the CFG, the result is the result for that prior CFN. - * - If there is no prior CFN, then the result is whatever the IRQL was at a statement prior to a function call to this function (a lazy interprocedural analysis.) - * - If there are no prior CFNs and no calls to this function, then the IRQL is determined by annotations applied to this function. - * - Failing all this, we set the IRQL to 0. - * - * Not implemented: _IRQL_limited_to_ - */ - - int getPotentialExitIrqlAtCfn(ControlFlowNode cfn) { - if cfn instanceof KeRaiseIrqlCall - then result = cfn.(KeRaiseIrqlCall).getIrqlLevel() - else - if cfn instanceof KeLowerIrqlCall - then result = cfn.(KeLowerIrqlCall).getIrqlLevel() - else - if cfn instanceof RestoresGlobalIrqlCall - then result = cfn.(RestoresGlobalIrqlCall).getIrqlLevel() - else - if cfn instanceof IrqlRestoreCall - then result = cfn.(IrqlRestoreCall).getIrqlLevel() - else - if - cfn instanceof FunctionCall and - cfn.(FunctionCall).getTarget() instanceof IrqlRaisesAnnotatedFunction - then result = cfn.(FunctionCall).getTarget().(IrqlRaisesAnnotatedFunction).getIrqlLevel() - else - if - cfn instanceof FunctionCall and - cfn.(FunctionCall).getTarget() instanceof IrqlRequiresSameAnnotatedFunction - then result = any(getPotentialExitIrqlAtCfn(cfn.getAPredecessor())) - else - if cfn instanceof FunctionCall - then - result = - any(getPotentialExitIrqlAtCfn(getExitPointsOfFunction(cfn.(FunctionCall) - .getTarget())) - ) - else - if exists(ControlFlowNode cfn2 | cfn2 = cfn.getAPredecessor()) - then result = any(getPotentialExitIrqlAtCfn(cfn.getAPredecessor())) - else - if - exists(FunctionCall fc, ControlFlowNode cfn2 | - fc.getTarget() = cfn.getControlFlowScope() and - cfn2.getASuccessor() = fc - ) - then - // TODO: Check that this node is actually a function entry point and not just - // an isolated part of the CFN. Sometimes we get nodes that are "in" a function's - // CFN, but have no predecessors, but are not function entry. (Why?) - result = - any(getPotentialExitIrqlAtCfn(any(ControlFlowNode cfn2 | - cfn2.getASuccessor().(FunctionCall).getTarget() = - cfn.getControlFlowScope() - )) - ) - else - if - cfn.getControlFlowScope() instanceof IrqlRestrictsFunction and - getAllowableIrqlLevel(cfn.getControlFlowScope()) != -1 - then result = getAllowableIrqlLevel(cfn.getControlFlowScope()) - else result = 0 - } - - - /* - * Similar to above, but only exit points where the Irql is explicit - */ - - - int getExplicitExitIrqlAtCfn(ControlFlowNode cfn) { - if cfn instanceof KeRaiseIrqlCall - then result = cfn.(KeRaiseIrqlCall).getIrqlLevel() - else - if cfn instanceof KeLowerIrqlCall - then result = cfn.(KeLowerIrqlCall).getIrqlLevelExplicit() - else - if cfn instanceof RestoresGlobalIrqlCall - then result = cfn.(RestoresGlobalIrqlCall).getIrqlLevelExplicit() - else - if cfn instanceof IrqlRestoreCall - then result = cfn.(IrqlRestoreCall).getIrqlLevelExplicit() - else - if - cfn instanceof FunctionCall and - cfn.(FunctionCall).getTarget() instanceof IrqlRaisesAnnotatedFunction - then result = cfn.(FunctionCall).getTarget().(IrqlRaisesAnnotatedFunction).getIrqlLevel() - else - if - cfn instanceof FunctionCall and - cfn.(FunctionCall).getTarget() instanceof IrqlRequiresSameAnnotatedFunction - then result = any(getExplicitExitIrqlAtCfn(cfn.getAPredecessor())) - else ( - if exists(ControlFlowNode cfn2 | cfn2 = cfn.getAPredecessor()) - then result = any(getExplicitExitIrqlAtCfn(cfn.getAPredecessor())) - else - result = - any(getExplicitExitIrqlAtCfn(any(ControlFlowNode cfn2 | - cfn2.getASuccessor().(FunctionCall).getTarget() = - cfn.getControlFlowScope() - )) - ) - ) - } - - import semmle.code.cpp.controlflow.Dominance - - /** Utility function to get exit points of a function. */ - private ControlFlowNode getExitPointsOfFunction(Function f) { - result = - any(ControlFlowNode cfn | - cfn.getControlFlowScope() = f and - functionExit(cfn) - ) - } - - /** - * Attempt to find the range of valid IRQL values when **entering** a given IRQL-annotated function. - * This is used as a heuristic when no other IRQL information is available (i.e. we are at the top - * of a call stack.) - * - * Note: we implicitly apply DISPATCH_LEVEL as the max when a max is not specified but a minimum is, - * and the global max if the minimum is > DISPATCH_LEVEL. - */ - - int getAllowableIrqlLevel(Function func) { - exists(IrqlValue lowerBound, IrqlValue upperBound | - hasLowerBound(func, lowerBound) and hasUpperBound(func, upperBound) - ) and - result = - [any(IrqlValue lowerBound | hasLowerBound(func, lowerBound)) .. any(IrqlValue upperBound | - hasUpperBound(func, upperBound) - )] - or - exists(IrqlValue upperBound | hasUpperBound(func, upperBound)) and - not exists(IrqlValue lowerBound | hasLowerBound(func, lowerBound)) and - result = [0 .. any(IrqlValue upperBound | hasUpperBound(func, upperBound))] - or - not exists(IrqlValue upperBound | hasUpperBound(func, upperBound)) and - exists(IrqlValue lowerBound | hasLowerBound(func, lowerBound) and lowerBound > 2) and - result = [any(IrqlValue lowerBound | hasLowerBound(func, lowerBound)) .. getGlobalMaxIrqlLevel()] - or - not exists(IrqlValue upperBound | hasUpperBound(func, upperBound)) and - exists(IrqlValue lowerBound | hasLowerBound(func, lowerBound) and lowerBound <= 2) and - result = [any(IrqlValue lowerBound | hasLowerBound(func, lowerBound)) .. 2] - } - - /** Attempts to find an upper bound on the expected entry IRQL for a function. */ - private predicate hasUpperBound(Function func, IrqlValue upperBound) { - // The instanceof checks may seem redundant, but in fact they let us - // implement a "priority" if there are multiple, possibly conflicting annotations. - ( - func.(IrqlMaxAnnotatedFunction).getIrqlLevel() = upperBound - or - not func instanceof IrqlMaxAnnotatedFunction and - func.(IrqlAlwaysMaxFunction).getIrqlLevel() = upperBound - or - ( - not func instanceof IrqlMaxAnnotatedFunction and - not func instanceof IrqlAlwaysMaxFunction - ) and - func.(IrqlRequiresAnnotatedFunction).getIrqlLevel() = upperBound - or - ( - not func instanceof IrqlMaxAnnotatedFunction and - not func instanceof IrqlAlwaysMaxFunction and - not func instanceof IrqlRequiresAnnotatedFunction - ) and - func instanceof PagedFunctionDeclaration and - upperBound = 1 - ) - } - - /** Attempts to find a lower bound on the expected entry IRQL for a function. */ - private predicate hasLowerBound(Function func, IrqlValue lowerBound) { - // The instanceof checks may seem redundant, but in fact they let us - // implement a "priority" if there are multiple, possibly conflicting annotations. - ( - func.(IrqlMinAnnotatedFunction).getIrqlLevel() = lowerBound - or - not func instanceof IrqlMinAnnotatedFunction and - func.(IrqlAlwaysMinFunction).getIrqlLevel() = lowerBound - or - ( - not func instanceof IrqlMinAnnotatedFunction and - not func instanceof IrqlAlwaysMinFunction - ) and - func.(IrqlRequiresAnnotatedFunction).getIrqlLevel() = lowerBound - or - ( - not func instanceof IrqlMinAnnotatedFunction and - not func instanceof IrqlAlwaysMinFunction and - not func instanceof IrqlRequiresAnnotatedFunction - ) and - func instanceof PagedFunctionDeclaration and - lowerBound = 0 - ) - } +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +/** + * Provides classes related to calculating and estimating the IRQL in a Windows device driver. + * + * For best results, this library expects to be used in tandem with IRQL annotations. A limited + * amount of functionality is still present even when no annotations are present, primarily around + * measuring direct calls to KeRaiseIrql and KeLowerIrql. + * + * Much of this library's analysis is intraprocedural or limited interprocedural, using a simple + * analysis based on call sites to a given function. Full interprocedural analysis that relies on the + * implicit behaviors of the WDM driver model, etc. is not yet supported. + */ + + import cpp + import drivers.libraries.SAL + import drivers.wdm.libraries.WdmDrivers + import drivers.libraries.IrqlDataFlow + import drivers.libraries.Page + import drivers.libraries.RoleTypes + + + + + /** + * A macro in wdm.h that represents an IRQL level, + * such as PASSIVE_LEVEL, DISPATCH_LEVEL, etc. + */ + + class IrqlMacro extends Macro { + int irqlLevelAsInt; + + + IrqlMacro() { + this.getName().matches("%_LEVEL") and + this.getFile().getBaseName() = "wdm.h" and + this.getBody().toInt() = irqlLevelAsInt and + irqlLevelAsInt >= 0 and + irqlLevelAsInt <= 31 + } + + /** Returns the integer value of this IRQL level. */ + + int getIrqlLevel() { result = irqlLevelAsInt } + } + + /** + * Returns the highest IRQL in wdm.h across this database. + * May cause incorrect results if database contains both 32-bit + * and 64-bit builds. + */ + + int getGlobalMaxIrqlLevel() { + result = + any(int i | + exists(IrqlMacro im | + i = im.getIrqlLevel() and + not exists(IrqlMacro im2 | im2 != im and im2.getIrqlLevel() > im.getIrqlLevel()) + ) + ) + } + + /** + * Represents a real (not -1) Irql level, between 0 and the max for the architecture this + * database was built to target. + */ + class IrqlValue extends int { + IrqlValue() { this = [0 .. getGlobalMaxIrqlLevel()] } + } + + /** An \_IRQL\_saves\_global\_(parameter, kind) annotation. */ + + class IrqlSavesGlobalAnnotation extends SALAnnotation { + MacroInvocation irqlMacroInvocation; + + + IrqlSavesGlobalAnnotation() { + // Needs to include other function and parameter annotations too + this.getMacroName() = ["__drv_savesIRQLGlobal", "_IRQL_saves_global_"] and + irqlMacroInvocation.getParentInvocation() = this + } + } + + /** An \_IRQL\_restores\_global\_(parameter, kind) annotation. */ + + class IrqlRestoresGlobalAnnotation extends SALAnnotation { + MacroInvocation irqlMacroInvocation; + + + IrqlRestoresGlobalAnnotation() { + // Needs to include other function and parameter annotations too + this.getMacroName() = ["__drv_restoresIRQLGlobal", "_IRQL_restores_global_"] and + irqlMacroInvocation.getParentInvocation() = this + } + } + + /** + * Standard IRQL annotations which apply to entire functions and manipulate or constrain the IRQL. + */ + + class IrqlFunctionAnnotation extends SALAnnotation { + string irqlLevel; + string irqlAnnotationName; + string innerAnnotationName; + string fullInnerAnnotationString; + + + IrqlFunctionAnnotation() { + ( + this.getMacroName() = + [ + "__drv_requiresIRQL", "_IRQL_requires_", "_drv_minIRQL", "_IRQL_requires_min_", + "_drv_maxIRQL", "_IRQL_requires_max_", "__drv_raisesIRQL", "_IRQL_raises_", + "__drv_maxFunctionIRQL", "_IRQL_always_function_max_", "__drv_minFunctionIRQL", + "_IRQL_always_function_min_" + ] and + irqlLevel = this.getUnexpandedArgument(0) and + innerAnnotationName = this.getMacroName() and + fullInnerAnnotationString = this.getMacroName() + "(" + irqlLevel + ")" + or + // Special case: _IRQL_saves_ annotations can apply to a whole function, + // but do not have an associated IRQL value. + this.getMacroName() = ["__drv_savesIRQL", "_IRQL_saves_"] and + irqlLevel = "NA_IRQL_SAVES" and + innerAnnotationName = this.getMacroName() and + fullInnerAnnotationString = this.getMacroName() + "(" + irqlLevel + ")" + or + // // Conditional IRQL annotations within a _When_ annotation + this.getMacroName() = ["_When_"] and + fullInnerAnnotationString = this.getUnexpandedArgument(1).toString() and + ( + fullInnerAnnotationString.matches("__drv_requiresIRQL%") and + innerAnnotationName = "__drv_requiresIRQL" + or + fullInnerAnnotationString.matches("_IRQL_requires_%") and + innerAnnotationName = "_IRQL_requires_" + or + fullInnerAnnotationString.matches("_drv_minIRQL%") and + innerAnnotationName = "_drv_minIRQL" + or + fullInnerAnnotationString.matches("_drv_maxIRQL%") and + innerAnnotationName = "_drv_maxIRQL" + or + fullInnerAnnotationString.matches("_IRQL_requires_max_%") and + innerAnnotationName = "_IRQL_requires_max_" + or + fullInnerAnnotationString.matches("_IRQL_raises_%") and + innerAnnotationName = "_IRQL_raises_" + or + fullInnerAnnotationString.matches("__drv_maxFunctionIRQL%") and + innerAnnotationName = "__drv_maxFunctionIRQL" + or + fullInnerAnnotationString.matches("_IRQL_always_function_max_%") and + innerAnnotationName = "_IRQL_always_function_max_" + or + fullInnerAnnotationString.matches("__drv_minFunctionIRQL%") and + innerAnnotationName = "__drv_minFunctionIRQL" + or + fullInnerAnnotationString.matches("_IRQL_always_function_min_%") and + innerAnnotationName = "_IRQL_always_function_min_" + ) and + irqlLevel = + fullInnerAnnotationString + .substring(fullInnerAnnotationString.indexOf(innerAnnotationName + "(") + 1 + + innerAnnotationName.length(), + fullInnerAnnotationString + .indexOf(")", 0, + fullInnerAnnotationString.indexOf(innerAnnotationName + "(") + 1 + + innerAnnotationName.length())) + ) and + irqlAnnotationName = this.getMacroName() + } + + /** Returns the text of this annotation (i.e. \_IRQL\_requires\_, etc.) */ + + string getIrqlMacroName() { + if this.getMacroName() = ["_When_"] + then result = innerAnnotationName + else result = irqlAnnotationName + } + + + string getIrqlLevelString() { result = irqlLevel } + + /** + * Evaluate the IRQL specified in this annotation, if possible. + * + * This will return -1 if the IRQL specified is anything other than a standard + * IRQL level (i.e. PASSIVE_LEVEL). This includes statements like "DPC_LEVEL - 1". + */ + + int getIrqlLevel() { + // Special case for DPC_LEVEL, which is not defined normally + if this.getIrqlLevelString() = "DPC_LEVEL" + then result = 2 + else + if exists(IrqlMacro im | im.getHead().matches(this.getIrqlLevelString())) + then + result = + any(int i | + exists(IrqlMacro im | + im.getIrqlLevel() = i and + im.getHead().matches(this.getIrqlLevelString()) + ) + ) + else + if exists(int i | i = this.getIrqlLevelString().toInt()) + then result = this.getIrqlLevelString().toInt() + else result = -1 + } + } + + /** Represents an "\_IRQL\_requires\_same\_" annotation. */ + class IrqlSameAnnotation extends SALAnnotation { + string irqlAnnotationName; + + IrqlSameAnnotation() { + this.getMacroName() = ["__drv_sameIRQL", "_IRQL_requires_same_"] and + irqlAnnotationName = this.getMacroName() + } + + string getIrqlMacroName() { result = irqlAnnotationName } + } + + /** An "\_IRQL\_requires\_max\_" annotation. */ + class IrqlMaxAnnotation extends IrqlFunctionAnnotation { + IrqlMaxAnnotation() { this.getIrqlMacroName() = ["_drv_maxIRQL", "_IRQL_requires_max_"] } + } + + /** An "\_IRQL\_raises\_" annotation. */ + class IrqlRaisesAnnotation extends IrqlFunctionAnnotation { + IrqlRaisesAnnotation() { this.getIrqlMacroName() = ["__drv_raisesIRQL", "_IRQL_raises_"] } + } + + /** An "\_IRQL\_requires\_min\_" annotation. */ + class IrqlMinAnnotation extends IrqlFunctionAnnotation { + IrqlMinAnnotation() { this.getIrqlMacroName() = ["_drv_minIRQL", "_IRQL_requires_min_"] } + } + + /** An "\_IRQL\_requires\_" annotation. */ + class IrqlRequiresAnnotation extends IrqlFunctionAnnotation { + IrqlRequiresAnnotation() { this.getIrqlMacroName() = ["__drv_requiresIRQL", "_IRQL_requires_"] } + } + + /** An "\_IRQL\_always\_function\_max\_" annotation. */ + class IrqlAlwaysMaxAnnotation extends IrqlFunctionAnnotation { + IrqlAlwaysMaxAnnotation() { + this.getIrqlMacroName() = ["__drv_maxFunctionIRQL", "_IRQL_always_function_max_"] + } + } + + /** An "\_IRQL\_always\_function\_min\_" annotation. */ + class IrqlAlwaysMinAnnotation extends IrqlFunctionAnnotation { + IrqlAlwaysMinAnnotation() { + this.getIrqlMacroName() = ["__drv_minFunctionIRQL", "_IRQL_always_function_min_"] + } + } + + /** + * A SAL annotation indicating that the parameter in + * question is used to store or restore the IRQL. + */ + class IrqlParameterAnnotation extends SALAnnotation { + string irqlAnnotationName; + + IrqlParameterAnnotation() { + this.getMacroName() = + ["__drv_restoresIRQL", "_IRQL_restores_", "__drv_savesIRQL", "_IRQL_saves_"] and + irqlAnnotationName = this.getMacroName() and + exists(MacroInvocation mi | mi.getParentInvocation() = this) + } + + /** Get the text of the annotation. */ + string getIrqlMacroName() { result = irqlAnnotationName } + } + + /** + * A SAL annotation indicating that the parameter in + * question contains an IRQL value that the system will be set to. + */ + class IrqlRestoreAnnotation extends IrqlParameterAnnotation { + IrqlRestoreAnnotation() { this.getMacroName() = ["__drv_restoresIRQL", "_IRQL_restores_"] } + } + + /** + * A SAL annotation indicating that can be used in two ways: + * - If applied to a function, the function returns the previous IRQL or otherwise saves the IRQL. + * - If applied to a parameter, the function saves the IRQL to the parameter. + */ + class IrqlSaveAnnotation extends IrqlFunctionAnnotation { + IrqlSaveAnnotation() { this.getIrqlMacroName() = ["__drv_savesIRQL", "_IRQL_saves_"] } + } + + /** A parameter that is annotated with "\_IRQL\_restores\_". */ + class IrqlRestoreParameter extends Parameter { + IrqlRestoreParameter() { exists(IrqlRestoreAnnotation ira | ira.getDeclaration() = this) } + } + + /** A parameter that is annotated with "\_IRQL\_saves\_". */ + class IrqlSaveParameter extends Parameter { + IrqlSaveParameter() { exists(IrqlSaveAnnotation isa | isa.getDeclaration() = this) } + } + + /** A typedef that has IRQL annotations applied to it. */ + class IrqlAnnotatedTypedef extends TypedefType { + IrqlFunctionAnnotation irqlAnnotation; + + IrqlAnnotatedTypedef() { irqlAnnotation.getTypedefDeclarations() = this } + + IrqlFunctionAnnotation getIrqlAnnotation() { result = irqlAnnotation } + } + + /** + * A function that is annotated in such a way that + * either its entry or exit IRQL is restricted, either by having a min/max value, + * a required value, or by raising the IRQL to a known value. + */ + + class IrqlRestrictsFunction extends Function { + IrqlFunctionAnnotation irqlAnnotation; + + + IrqlRestrictsFunction() { + exists(FunctionDeclarationEntry fde | + fde = this.getADeclarationEntry() and + irqlAnnotation.getDeclarationEntry() = fde + ) + or + exists(FunctionDeclarationEntry fde | + fde.getFunction() = this and + fde.getTypedefType().(IrqlAnnotatedTypedef).getIrqlAnnotation() = irqlAnnotation + ) + or + exists(ImplicitRoleTypeFunction irtf | + irtf = this and + irtf.getExpectedRoleTypeType().(IrqlAnnotatedTypedef).getIrqlAnnotation() = irqlAnnotation + ) + } + + + IrqlFunctionAnnotation getFuncIrqlAnnotation() { result = irqlAnnotation } + } + + /** A function that changes the IRQL. */ + abstract class IrqlChangesFunction extends Function { } + + /** A function that is explicitly annotated to enter and exit at the same IRQL. */ + class IrqlRequiresSameAnnotatedFunction extends Function { + IrqlSameAnnotation irqlAnnotation; + + IrqlRequiresSameAnnotatedFunction() { + exists(FunctionDeclarationEntry fde | + fde = this.getADeclarationEntry() and + irqlAnnotation.getDeclarationEntry() = fde + ) + } + } + + /** A function that is annotated to run at a specific IRQL. */ + class IrqlRequiresAnnotatedFunction extends IrqlRestrictsFunction { + IrqlRequiresAnnotatedFunction() { irqlAnnotation instanceof IrqlRequiresAnnotation } + + int getIrqlLevel() { result = irqlAnnotation.(IrqlRequiresAnnotation).getIrqlLevel() } + } + + /** A function that is annotated to enter at or below a given IRQL. */ + class IrqlMaxAnnotatedFunction extends IrqlRestrictsFunction { + IrqlMaxAnnotatedFunction() { irqlAnnotation instanceof IrqlMaxAnnotation } + + int getIrqlLevel() { result = irqlAnnotation.(IrqlMaxAnnotation).getIrqlLevel() } + } + + /** A function that is annotated to enter at or above a given IRQL. */ + class IrqlMinAnnotatedFunction extends IrqlRestrictsFunction { + IrqlMinAnnotatedFunction() { irqlAnnotation instanceof IrqlMinAnnotation } + + int getIrqlLevel() { result = irqlAnnotation.(IrqlMinAnnotation).getIrqlLevel() } + } + + /** A function that is annotated to raise the IRQL to a given value. */ + class IrqlRaisesAnnotatedFunction extends IrqlRestrictsFunction, IrqlChangesFunction { + IrqlRaisesAnnotatedFunction() { irqlAnnotation instanceof IrqlRaisesAnnotation } + + int getIrqlLevel() { result = irqlAnnotation.(IrqlRaisesAnnotation).getIrqlLevel() } + } + + /** A function that is never allowed to run with the IRQL above a given value. */ + class IrqlAlwaysMaxFunction extends IrqlRestrictsFunction { + IrqlAlwaysMaxFunction() { irqlAnnotation instanceof IrqlAlwaysMaxAnnotation } + + int getIrqlLevel() { result = irqlAnnotation.(IrqlAlwaysMaxAnnotation).getIrqlLevel() } + } + + /** A function that is never allowed to run with the IRQL above a given value. */ + class IrqlAlwaysMinFunction extends IrqlRestrictsFunction { + IrqlAlwaysMinFunction() { irqlAnnotation instanceof IrqlAlwaysMinAnnotation } + + int getIrqlLevel() { result = irqlAnnotation.(IrqlAlwaysMinAnnotation).getIrqlLevel() } + } + + /** A function annotated to save the IRQL at the specified location upon entry. */ + class IrqlSavesGlobalAnnotatedFunction extends IrqlChangesFunction { + IrqlSavesGlobalAnnotation irqlAnnotation; + string irqlKind; + int irqlParamIndex; + + IrqlSavesGlobalAnnotatedFunction() { + exists(FunctionDeclarationEntry fde | + fde = this.getADeclarationEntry() and + irqlAnnotation.getDeclarationEntry() = fde + ) and + irqlKind = irqlAnnotation.getExpandedArgument(0) and + this.getParameter(irqlParamIndex).getName().matches(irqlAnnotation.getExpandedArgument(1)) + } + + string getIrqlKind() { result = irqlKind } + + int getIrqlParameterSlot() { result = irqlParamIndex } + } + + /** A function annotated to restore the IRQL from the specified location upon exit. */ + class IrqlRestoresGlobalAnnotatedFunction extends IrqlChangesFunction { + IrqlRestoresGlobalAnnotation irqlAnnotation; + string irqlKind; + int irqlParamIndex; + + IrqlRestoresGlobalAnnotatedFunction() { + exists(FunctionDeclarationEntry fde | + fde = this.getADeclarationEntry() and + irqlAnnotation.getDeclarationEntry() = fde + ) and + irqlKind = irqlAnnotation.getExpandedArgument(0) and + this.getParameter(irqlParamIndex).getName().matches(irqlAnnotation.getExpandedArgument(1)) + } + + string getIrqlKind() { result = irqlKind } + + int getIrqlParameterSlot() { result = irqlParamIndex } + } + + /** + * An abstract class for functions that use the \_IRQL\_saves\_ annotation, + * either on the function definition or on a specific parameter. + */ + abstract class IrqlSavesFunction extends Function { } + + /** A function that has a parameter annotated \_IRQL\_saves\_. */ + class IrqlSavesToParameterFunction extends IrqlSavesFunction { + IrqlSaveParameter saveParameter; + int irqlParamIndex; + + IrqlSavesToParameterFunction() { this.getParameter(irqlParamIndex) = saveParameter } + + int getIrqlParameterSlot() { result = irqlParamIndex } + } + + /** A function that saves the IRQL as a return value. */ + class IrqlSavesViaReturnFunction extends IrqlSavesFunction { + IrqlSaveAnnotation irqlAnnotation; + + IrqlSavesViaReturnFunction() { + exists(FunctionDeclarationEntry fde | + fde = this.getADeclarationEntry() and + irqlAnnotation.getDeclarationEntry() = fde + ) + } + } + + /** A function that has a parameter annotated \_IRQL\_restores\_. */ + class IrqlRestoreAnnotatedFunction extends Function { + IrqlRestoreParameter restoreParameter; + int irqlParamIndex; + + IrqlRestoreAnnotatedFunction() { this.getParameter(irqlParamIndex) = restoreParameter } + + int getIrqlParameterSlot() { result = irqlParamIndex } + } + + /** A call to a function that has a parameter annotated \_IRQL\_restores\_. */ + class IrqlRestoreCall extends FunctionCall { + IrqlRestoreCall() { this.getTarget() instanceof IrqlRestoreAnnotatedFunction } + + /** + * A heuristic evaluation of the IRQL that the system is changing to. This is defined as + * "the IRQL before the corresponding save global call." + */ + int getIrqlLevel() { + result = any(getPotentialExitIrqlAtCfn(this.getMostRecentRaise().getAPredecessor())) + } + + int getIrqlLevelExplicit() { + result = any(getExplicitExitIrqlAtCfn(this.getMostRecentRaise().getAPredecessor())) + } + + /** Returns the matching call to a function that saved the IRQL. */ + IrqlSaveCall getMostRecentRaise() { + result = + any(IrqlSaveCall sgic | + this.getAPredecessor*() = sgic and + matchingSaveCall(sgic) and + not exists(SavesGlobalIrqlCall sgic2 | + sgic2 != sgic and sgic2.getAPredecessor*() = sgic and matchingSaveCall(sgic2) + ) + ) + } + + /** + * Holds if a given call to an \_IRQL\_saves\_global\_ annotated function is using the same IRQL location as this. + */ + private predicate matchingSaveCall(IrqlSaveCall sgic) { + // Attempting to match all expr children leads to an explosion in runtime, so for now just compare + // the expr itself and the first child of each argument. This covers the common &variable case. + exists(int i, int j | + i = this.getTarget().(IrqlRestoreAnnotatedFunction).getIrqlParameterSlot() and + j = sgic.getTarget().(IrqlSavesToParameterFunction).getIrqlParameterSlot() and + exprsMatchText(this.getArgument(i), sgic.getArgument(j)) + ) + or + exists(int i | + i = this.getTarget().(IrqlRestoreAnnotatedFunction).getIrqlParameterSlot() and + sgic.getTarget() instanceof IrqlSavesViaReturnFunction and + exprsMatchText(this.getArgument(i), sgic.getSavedValue()) + ) and + this.getControlFlowScope() = sgic.getControlFlowScope() + } + } + + /** A call to a function that has is annotated \_IRQL\_saves\_. */ + class IrqlSaveCall extends FunctionCall { + IrqlSaveCall() { this.getTarget() instanceof IrqlSavesFunction } + + Expr getSavedValue() { + result = + any(Expr e | + exists(AssignExpr ae | + ae.getLValue() = e and + ae.getRValue() = this and + this.getTarget() instanceof IrqlSavesViaReturnFunction + ) + ) + } + } + + /** A call to a KeRaiseIRQL API that directly raises the IRQL. */ + class KeRaiseIrqlCall extends FunctionCall { + KeRaiseIrqlCall() { + this.getTarget().getName() = + ["KeRaiseIrql", "KfRaiseIrql", "KeRaiseIrqlToDPCLevel", "KfRaiseIrqlToDPCLevel"] + } + + int getIrqlLevel() { + if this.getTarget().getName() = ["KeRaiseIrqlToDPCLevel", "KfRaiseIrqlToDPCLevel"] + then result = 2 + else result = this.getArgument(0).(Literal).getValue().toInt() + } + } + + /** A direct call to a function that lowers the IRQL. */ + class KeLowerIrqlCall extends FunctionCall { + KeLowerIrqlCall() { this.getTarget().getName() = ["KeLowerIrql", "KfLowerIrql"] } + + /** + * A heuristic evaluation of the IRQL that the system is lowering to. This is defined as + * "the IRQL before the most recent KeRaiseIrql call". + */ + int getIrqlLevel() { + result = + any(getPotentialExitIrqlAtCfn(this.getMostRecentRaiseInterprocedural().getAPredecessor())) + } + + int getIrqlLevelExplicit() { + result = + any(getExplicitExitIrqlAtCfn(this.getMostRecentRaiseInterprocedural().getAPredecessor())) + } + + /** + * Get the most recent KeRaiseIrql call before this call. + * + * This performs a local (intraprocedural) analysis only. It is unused in the library today, + * but can be inserted in place of the interprocedural analysis by modifying the getIrqlLevel() + * function above. + */ + KeRaiseIrqlCall getMostRecentRaise() { + result = + any(KeRaiseIrqlCall sgic | + this.getAPredecessor*() = sgic and + not exists(KeRaiseIrqlCall kric2 | kric2 != sgic and kric2.getAPredecessor*() = sgic) + ) + } + + + /** + * Get the corresponding KeRaiseIrql call that preceded this KeLowerIrql call. + * + * This performs an interprocedural analysis using CodeQL's DataFlow classes. + */ + KeRaiseIrqlCall getMostRecentRaiseInterprocedural() { + result = + any(KeRaiseIrqlCall kric | + IrqlRaiseLowerFlow::flow(DataFlow::exprNode(kric), DataFlow::exprNode(this.getAnArgument())) + ) + } + } + + /** A call to a function that restores the IRQL from a specified state. */ + class SavesGlobalIrqlCall extends FunctionCall { + SavesGlobalIrqlCall() { this.getTarget() instanceof IrqlSavesGlobalAnnotatedFunction } + } + + /** A call to a function that restores the IRQL from a specified state. */ + class RestoresGlobalIrqlCall extends FunctionCall { + RestoresGlobalIrqlCall() { this.getTarget() instanceof IrqlRestoresGlobalAnnotatedFunction } + + /** + * A heuristic evaluation of the IRQL that the system is changing to. This is defined as + * "the IRQL before the corresponding save global call." + */ + int getIrqlLevel() { + result = any(getPotentialExitIrqlAtCfn(this.getMostRecentRaise().getAPredecessor())) + } + + int getIrqlLevelExplicit() { + result = any(getExplicitExitIrqlAtCfn(this.getMostRecentRaise().getAPredecessor())) + } + + /** + * Returns the matching call to a function that saved the IRQL to a global state. + * + * This is a strictly intraprocedural analysis. + */ + SavesGlobalIrqlCall getMostRecentRaise() { + result = + any(SavesGlobalIrqlCall sgic | + this.getAPredecessor*() = sgic and + matchingSaveCall(sgic) and + not exists(SavesGlobalIrqlCall sgic2 | + sgic2 != sgic and sgic2.getAPredecessor*() = sgic and matchingSaveCall(sgic2) + ) + ) + } + + /** + * Holds if a given call to an _IRQL_saves_global_ annotated function is using the same IRQL location as this. + */ + private predicate matchingSaveCall(SavesGlobalIrqlCall sgic) { + // Attempting to match all expr children leads to an explosion in runtime, so for now just compare + // the expr itself and the first child of each argument. This covers the common &variable case. + exists(int i, int j | + i = this.getTarget().(IrqlRestoresGlobalAnnotatedFunction).getIrqlParameterSlot() and + j = sgic.getTarget().(IrqlSavesGlobalAnnotatedFunction).getIrqlParameterSlot() and + exprsMatchText(this.getArgument(i), sgic.getArgument(j)) + ) and + this.getTarget().(IrqlRestoresGlobalAnnotatedFunction).getIrqlKind() = + sgic.getTarget().(IrqlSavesGlobalAnnotatedFunction).getIrqlKind() + } + } + + /** + * A utility function to determine if two exprs are (textually) the same. + * Because checking all children of the expression causes an explosion in evaluation time, we just + * check the first child. + * + * This function is obviously _not_ a guarantee that two expressions refer to the same thing. + * Use this locally and with caution. + * + * TODO: Compare with global value numbering (both accuracy and performance) + */ + pragma[inline] + private predicate exprsMatchText(Expr e1, Expr e2) { + e1.toString().matches(e2.toString()) and + exists(Expr child | + child = e1.getAChild() and + e1.getChild(0).toString().matches(e2.getChild(0).toString()) + ) + or + not exists(Expr child | child = e1.getAChild() or child = e2.getAChild()) + } + + /** + * Attempt to provide the IRQL **once this control flow node exits**, based on annotations and direct calls to raising/lowering functions. + * This predicate functions as follows: + * - If calling a "Raise IRQL" function, then it returns the value of the argument passed in (the target IRQL). + * - If calling a "Lower IRQL" function, then it returns the value of the argument passed in (the target IRQL). + * - If calling a function annotated to restore the IRQL from a previously saved spot, then the result is the IRQL before that save call. + * - If calling a function annotated to raise the IRQL, then it returns the annotated value (the target IRQL). + * - If calling a function annotated to maintain the same IRQL, then the result is the IRQL at the previous CFN. + * - If this node is calling a function with no annotations, the result is the IRQL that function exits at. + * - If there is a prior CFN in the CFG, the result is the result for that prior CFN. + * - If there is no prior CFN, then the result is whatever the IRQL was at a statement prior to a function call to this function (a lazy interprocedural analysis.) + * - If there are no prior CFNs and no calls to this function, then the IRQL is determined by annotations applied to this function. + * - Failing all this, we set the IRQL to 0. + * + * Not implemented: _IRQL_limited_to_ + */ + + int getPotentialExitIrqlAtCfn(ControlFlowNode cfn) { + if cfn instanceof KeRaiseIrqlCall + then result = cfn.(KeRaiseIrqlCall).getIrqlLevel() + else + if cfn instanceof KeLowerIrqlCall + then result = cfn.(KeLowerIrqlCall).getIrqlLevel() + else + if cfn instanceof RestoresGlobalIrqlCall + then result = cfn.(RestoresGlobalIrqlCall).getIrqlLevel() + else + if cfn instanceof IrqlRestoreCall + then result = cfn.(IrqlRestoreCall).getIrqlLevel() + else + if + cfn instanceof FunctionCall and + cfn.(FunctionCall).getTarget() instanceof IrqlRaisesAnnotatedFunction + then result = cfn.(FunctionCall).getTarget().(IrqlRaisesAnnotatedFunction).getIrqlLevel() + else + if + cfn instanceof FunctionCall and + cfn.(FunctionCall).getTarget() instanceof IrqlRequiresSameAnnotatedFunction + then result = any(getPotentialExitIrqlAtCfn(cfn.getAPredecessor())) + else + if cfn instanceof FunctionCall + then + result = + any(getPotentialExitIrqlAtCfn(getExitPointsOfFunction(cfn.(FunctionCall) + .getTarget())) + ) + else + if exists(ControlFlowNode cfn2 | cfn2 = cfn.getAPredecessor()) + then result = any(getPotentialExitIrqlAtCfn(cfn.getAPredecessor())) + else + if + exists(FunctionCall fc, ControlFlowNode cfn2 | + fc.getTarget() = cfn.getControlFlowScope() and + cfn2.getASuccessor() = fc + ) + then + // TODO: Check that this node is actually a function entry point and not just + // an isolated part of the CFN. Sometimes we get nodes that are "in" a function's + // CFN, but have no predecessors, but are not function entry. (Why?) + result = + any(getPotentialExitIrqlAtCfn(any(ControlFlowNode cfn2 | + cfn2.getASuccessor().(FunctionCall).getTarget() = + cfn.getControlFlowScope() + )) + ) + else + if + cfn.getControlFlowScope() instanceof IrqlRestrictsFunction and + getAllowableIrqlLevel(cfn.getControlFlowScope()) != -1 + then result = getAllowableIrqlLevel(cfn.getControlFlowScope()) + else result = 0 + } + + + /* + * Similar to above, but only exit points where the Irql is explicit + */ + + + int getExplicitExitIrqlAtCfn(ControlFlowNode cfn) { + if cfn instanceof KeRaiseIrqlCall + then result = cfn.(KeRaiseIrqlCall).getIrqlLevel() + else + if cfn instanceof KeLowerIrqlCall + then result = cfn.(KeLowerIrqlCall).getIrqlLevelExplicit() + else + if cfn instanceof RestoresGlobalIrqlCall + then result = cfn.(RestoresGlobalIrqlCall).getIrqlLevelExplicit() + else + if cfn instanceof IrqlRestoreCall + then result = cfn.(IrqlRestoreCall).getIrqlLevelExplicit() + else + if + cfn instanceof FunctionCall and + cfn.(FunctionCall).getTarget() instanceof IrqlRaisesAnnotatedFunction + then result = cfn.(FunctionCall).getTarget().(IrqlRaisesAnnotatedFunction).getIrqlLevel() + else + if + cfn instanceof FunctionCall and + cfn.(FunctionCall).getTarget() instanceof IrqlRequiresSameAnnotatedFunction + then result = any(getExplicitExitIrqlAtCfn(cfn.getAPredecessor())) + else ( + if exists(ControlFlowNode cfn2 | cfn2 = cfn.getAPredecessor()) + then result = any(getExplicitExitIrqlAtCfn(cfn.getAPredecessor())) + else + result = + any(getExplicitExitIrqlAtCfn(any(ControlFlowNode cfn2 | + cfn2.getASuccessor().(FunctionCall).getTarget() = + cfn.getControlFlowScope() + )) + ) + ) + } + + import semmle.code.cpp.controlflow.Dominance + + /** Utility function to get exit points of a function. */ + private ControlFlowNode getExitPointsOfFunction(Function f) { + result = + any(ControlFlowNode cfn | + cfn.getControlFlowScope() = f and + functionExit(cfn) + ) + } + + /** + * Attempt to find the range of valid IRQL values when **entering** a given IRQL-annotated function. + * This is used as a heuristic when no other IRQL information is available (i.e. we are at the top + * of a call stack.) + * + * Note: we implicitly apply DISPATCH_LEVEL as the max when a max is not specified but a minimum is, + * and the global max if the minimum is > DISPATCH_LEVEL. + */ + + int getAllowableIrqlLevel(Function func) { + exists(IrqlValue lowerBound, IrqlValue upperBound | + hasLowerBound(func, lowerBound) and hasUpperBound(func, upperBound) + ) and + result = + [any(IrqlValue lowerBound | hasLowerBound(func, lowerBound)) .. any(IrqlValue upperBound | + hasUpperBound(func, upperBound) + )] + or + exists(IrqlValue upperBound | hasUpperBound(func, upperBound)) and + not exists(IrqlValue lowerBound | hasLowerBound(func, lowerBound)) and + result = [0 .. any(IrqlValue upperBound | hasUpperBound(func, upperBound))] + or + not exists(IrqlValue upperBound | hasUpperBound(func, upperBound)) and + exists(IrqlValue lowerBound | hasLowerBound(func, lowerBound) and lowerBound > 2) and + result = [any(IrqlValue lowerBound | hasLowerBound(func, lowerBound)) .. getGlobalMaxIrqlLevel()] + or + not exists(IrqlValue upperBound | hasUpperBound(func, upperBound)) and + exists(IrqlValue lowerBound | hasLowerBound(func, lowerBound) and lowerBound <= 2) and + result = [any(IrqlValue lowerBound | hasLowerBound(func, lowerBound)) .. 2] + } + + /** Attempts to find an upper bound on the expected entry IRQL for a function. */ + private predicate hasUpperBound(Function func, IrqlValue upperBound) { + // The instanceof checks may seem redundant, but in fact they let us + // implement a "priority" if there are multiple, possibly conflicting annotations. + ( + func.(IrqlMaxAnnotatedFunction).getIrqlLevel() = upperBound + or + not func instanceof IrqlMaxAnnotatedFunction and + func.(IrqlAlwaysMaxFunction).getIrqlLevel() = upperBound + or + ( + not func instanceof IrqlMaxAnnotatedFunction and + not func instanceof IrqlAlwaysMaxFunction + ) and + func.(IrqlRequiresAnnotatedFunction).getIrqlLevel() = upperBound + or + ( + not func instanceof IrqlMaxAnnotatedFunction and + not func instanceof IrqlAlwaysMaxFunction and + not func instanceof IrqlRequiresAnnotatedFunction + ) and + func instanceof PagedFunctionDeclaration and + upperBound = 1 + ) + } + + /** Attempts to find a lower bound on the expected entry IRQL for a function. */ + private predicate hasLowerBound(Function func, IrqlValue lowerBound) { + // The instanceof checks may seem redundant, but in fact they let us + // implement a "priority" if there are multiple, possibly conflicting annotations. + ( + func.(IrqlMinAnnotatedFunction).getIrqlLevel() = lowerBound + or + not func instanceof IrqlMinAnnotatedFunction and + func.(IrqlAlwaysMinFunction).getIrqlLevel() = lowerBound + or + ( + not func instanceof IrqlMinAnnotatedFunction and + not func instanceof IrqlAlwaysMinFunction + ) and + func.(IrqlRequiresAnnotatedFunction).getIrqlLevel() = lowerBound + or + ( + not func instanceof IrqlMinAnnotatedFunction and + not func instanceof IrqlAlwaysMinFunction and + not func instanceof IrqlRequiresAnnotatedFunction + ) and + func instanceof PagedFunctionDeclaration and + lowerBound = 0 + ) + } \ No newline at end of file diff --git a/src/drivers/libraries/IrqlDataFlow.qll b/codeql/src/drivers/libraries/IrqlDataFlow.qll similarity index 100% rename from src/drivers/libraries/IrqlDataFlow.qll rename to codeql/src/drivers/libraries/IrqlDataFlow.qll diff --git a/src/drivers/libraries/IrqlDebug.qll b/codeql/src/drivers/libraries/IrqlDebug.qll similarity index 100% rename from src/drivers/libraries/IrqlDebug.qll rename to codeql/src/drivers/libraries/IrqlDebug.qll diff --git a/src/drivers/libraries/Page.qll b/codeql/src/drivers/libraries/Page.qll similarity index 96% rename from src/drivers/libraries/Page.qll rename to codeql/src/drivers/libraries/Page.qll index 5584e2d4..fa9b79bb 100644 --- a/src/drivers/libraries/Page.qll +++ b/codeql/src/drivers/libraries/Page.qll @@ -1,106 +1,106 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -import cpp - -//Represents functions where a function has either PAGED_CODE or PAGED_CODE_LOCKED macro invocations - -class PagedFunc extends Function { - - PagedFunc() { - exists(MacroInvocation mi | - mi.getEnclosingFunction() = this and - mi.getMacroName() = ["PAGED_CODE", "PAGED_CODE_LOCKED"] - ) - } -} - -//Represents code_seg("PAGE") pragma -class CodeSegPragma extends PreprocessorPragma { - CodeSegPragma() { this.getHead().matches("code\\_seg%(%\"PAGE\")") } -} - -//Represents a code_seg() pragma -class DefaultCodeSegPragma extends PreprocessorPragma { - DefaultCodeSegPragma() { - this.getHead().matches("code\\_seg()") - or - this.getHead().matches("code\\_seg(\"INIT\")") - } -} - -//Represents alloc_text pragma -class AllocSegPragma extends PreprocessorPragma { - AllocSegPragma() { - this.getHead().matches("alloc\\_text%(%PAGE%") or - this.getHead().matches("NDIS\\_PAGEABLE\\_FUNCTION%") or - this.getHead().matches("NDIS\\_PAGABLE\\_FUNCTION%") - } -} - -//Evaluates to true if a PagedFunc was placed in a PAGE section using alloc_text pragma -predicate isAllocUsedToLocatePagedFunc(Function pf) { - exists(AllocSegPragma asp | - asp.getHead().matches("%" + pf.getName() + [" )", ")"]) and - asp.getFile() = pf.getFile() - ) -} - -//Evaluates to true if there is Macro Invocation above PagedFunc which expands to code_seg("PAGE") -predicate isPagedSegSetWithMacroAbove(Function f) { - exists(MacroInvocation ma | - ma.getMacro().getBody().matches("%code\\_seg(\"PAGE\")%") and - ma.getLocation().getStartLine() <= f.getLocation().getStartLine() and - f.getAnAttribute().getName() = "code_seg" and - ma.getFile() = f.getFile() - ) -} - -//Represents functions for whom code_seg() is set - -class FunctionWithPageReset extends Function { - DefaultCodeSegPragma dcs; - - - FunctionWithPageReset() { - exists(CodeSegPragma csp, DefaultCodeSegPragma dcsp | - this.getLocation().getStartLine() > csp.getLocation().getStartLine() and - dcsp.getFile() = csp.getFile() and - this.getFile() = csp.getFile() and - dcsp.getLocation().getStartLine() < this.getLocation().getStartLine() and - dcs = dcsp - ) - } - - - DefaultCodeSegPragma getCodeSeg() { result = dcs } -} - -//Represents functions for whom code_seg("PAGE") is set - -class FunctionWithPageSet extends Function { - - FunctionWithPageSet() { - exists(CodeSegPragma csp | - this.getLocation().getStartLine() > csp.getLocation().getStartLine() and - this.getFile() = csp.getFile() and - not exists(FunctionWithPageReset rf | - rf.getFile() = csp.getFile() and - rf = this and - rf.getCodeSeg().getLocation().getStartLine() > csp.getLocation().getStartLine() - ) - ) - } -} - -//Represents a paged section - -class PagedFunctionDeclaration extends Function { - - PagedFunctionDeclaration() { - isPagedSegSetWithMacroAbove(this) - or - this instanceof FunctionWithPageSet - or - isAllocUsedToLocatePagedFunc(this) - } -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +import cpp + +//Represents functions where a function has either PAGED_CODE or PAGED_CODE_LOCKED macro invocations + +class PagedFunc extends Function { + + PagedFunc() { + exists(MacroInvocation mi | + mi.getEnclosingFunction() = this and + mi.getMacroName() = ["PAGED_CODE", "PAGED_CODE_LOCKED"] + ) + } +} + +//Represents code_seg("PAGE") pragma +class CodeSegPragma extends PreprocessorPragma { + CodeSegPragma() { this.getHead().matches("code\\_seg%(%\"PAGE\")") } +} + +//Represents a code_seg() pragma +class DefaultCodeSegPragma extends PreprocessorPragma { + DefaultCodeSegPragma() { + this.getHead().matches("code\\_seg()") + or + this.getHead().matches("code\\_seg(\"INIT\")") + } +} + +//Represents alloc_text pragma +class AllocSegPragma extends PreprocessorPragma { + AllocSegPragma() { + this.getHead().matches("alloc\\_text%(%PAGE%") or + this.getHead().matches("NDIS\\_PAGEABLE\\_FUNCTION%") or + this.getHead().matches("NDIS\\_PAGABLE\\_FUNCTION%") + } +} + +//Evaluates to true if a PagedFunc was placed in a PAGE section using alloc_text pragma +predicate isAllocUsedToLocatePagedFunc(Function pf) { + exists(AllocSegPragma asp | + asp.getHead().matches("%" + pf.getName() + [" )", ")"]) and + asp.getFile() = pf.getFile() + ) +} + +//Evaluates to true if there is Macro Invocation above PagedFunc which expands to code_seg("PAGE") +predicate isPagedSegSetWithMacroAbove(Function f) { + exists(MacroInvocation ma | + ma.getMacro().getBody().matches("%code\\_seg(\"PAGE\")%") and + ma.getLocation().getStartLine() <= f.getLocation().getStartLine() and + f.getAnAttribute().getName() = "code_seg" and + ma.getFile() = f.getFile() + ) +} + +//Represents functions for whom code_seg() is set + +class FunctionWithPageReset extends Function { + DefaultCodeSegPragma dcs; + + + FunctionWithPageReset() { + exists(CodeSegPragma csp, DefaultCodeSegPragma dcsp | + this.getLocation().getStartLine() > csp.getLocation().getStartLine() and + dcsp.getFile() = csp.getFile() and + this.getFile() = csp.getFile() and + dcsp.getLocation().getStartLine() < this.getLocation().getStartLine() and + dcs = dcsp + ) + } + + + DefaultCodeSegPragma getCodeSeg() { result = dcs } +} + +//Represents functions for whom code_seg("PAGE") is set + +class FunctionWithPageSet extends Function { + + FunctionWithPageSet() { + exists(CodeSegPragma csp | + this.getLocation().getStartLine() > csp.getLocation().getStartLine() and + this.getFile() = csp.getFile() and + not exists(FunctionWithPageReset rf | + rf.getFile() = csp.getFile() and + rf = this and + rf.getCodeSeg().getLocation().getStartLine() > csp.getLocation().getStartLine() + ) + ) + } +} + +//Represents a paged section + +class PagedFunctionDeclaration extends Function { + + PagedFunctionDeclaration() { + isPagedSegSetWithMacroAbove(this) + or + this instanceof FunctionWithPageSet + or + isAllocUsedToLocatePagedFunc(this) + } +} diff --git a/src/drivers/libraries/RoleTypes.qll b/codeql/src/drivers/libraries/RoleTypes.qll similarity index 96% rename from src/drivers/libraries/RoleTypes.qll rename to codeql/src/drivers/libraries/RoleTypes.qll index 4f8fb9ed..0c879841 100644 --- a/src/drivers/libraries/RoleTypes.qll +++ b/codeql/src/drivers/libraries/RoleTypes.qll @@ -1,351 +1,351 @@ -import cpp -import drivers.libraries.SAL -// import drivers.libraries.Irql // TODO: add this back in -import drivers.wdm.libraries.WdmDrivers -import drivers.kmdf.libraries.KmdfDrivers -import drivers.ndis.libraries.NdisDrivers -import drivers.storport.libraries.StorportDrivers - -/** - * Special case to check for RoleType equality for role types in wdfroletypes.h - */ -bindingset[rtt1, rtt2] -predicate isEqualRoleTypes(string rtt1, string rtt2) { - rtt1.matches("EVT_WDF_%_CONTEXT_DESTROY%") and - rtt2.matches("EVT_WDF_%_CONTEXT_DESTROY%") - or - rtt1.matches("EVT_WDF_%_CONTEXT_CLEANUP%") and - rtt2.matches("EVT_WDF_%_CONTEXT_CLEANUP%") - or - rtt1 = rtt2 -} - -/** - * Generic role type for WDM,KMDF, and others - */ -class RoleTypeType extends TypedefType { - RoleTypeType() { - this instanceof WdmRoleTypeType or - this instanceof KmdfRoleTypeType or - this instanceof NdisRoleTypeType or - this instanceof StorportRoleTypeType - } -} - -/** - * Role Type annotations which apply to entire functions - */ -class RoleTypeFunctionAnnotation extends SALAnnotation { - string roleTypeString; - string roleTypeName; - - RoleTypeFunctionAnnotation() { - ( - this.getMacroName().matches(["_Function_class_"]) and - roleTypeString = this.getUnexpandedArgument(0) - ) and - roleTypeName = this.getMacroName() - } - - /** - * Returns the raw text of the role type value used in this annotation. - */ - string getRoleTypeString() { result = roleTypeString } - - /** - * Returns the text of this annotation - */ - string getRoleTypeMacroName() { result = roleTypeName } -} - -/** - * A typedef that has Role Type annotations applied to it. - */ -class RoleTypeAnnotatedTypedef extends TypedefType { - RoleTypeFunctionAnnotation roleTypeAnnotation; - - RoleTypeAnnotatedTypedef() { roleTypeAnnotation.getTypedefDeclarations() = this } - - RoleTypeFunctionAnnotation getRoleTypeAnnotation() { result = roleTypeAnnotation } -} - -/** - * A function that is annotated to specify role type - */ -class RoleTypeAnnotatedFunction extends Function { - RoleTypeFunctionAnnotation roleTypeAnnotation; - - RoleTypeAnnotatedFunction() { - ( - this.hasCLinkage() and - exists( - FunctionDeclarationEntry fde // actual function declarations - | - fde = this.getADeclarationEntry() and - roleTypeAnnotation.getDeclarationEntry() = fde - ) - or - exists( - FunctionDeclarationEntry fde // typedefs - | - fde.getFunction() = this and - fde.getTypedefType().(RoleTypeAnnotatedTypedef).getRoleTypeAnnotation() = roleTypeAnnotation - ) - ) - } - - string getFuncRoleTypeAnnotation() { result = roleTypeAnnotation.getRoleTypeMacroName() } - - RoleTypeFunctionAnnotation getRoleTypeAnnotation() { result = roleTypeAnnotation } -} - -/** - * A function that is annotated or declared to specify role type - */ -class RoleTypeFunction extends Function { - RoleTypeType roleType; - - //int irqlLevel; // TODO: add this back in - RoleTypeFunction() { - this.hasCLinkage() and - ( - exists(FunctionDeclarationEntry fde | - ( - fde.getFunction() = this and - fde.getTypedefType() = roleType - ) - ) - or - this instanceof RoleTypeAnnotatedFunction and - roleType.getName() = - this.(RoleTypeAnnotatedFunction).getRoleTypeAnnotation().getRoleTypeString() - ) - // TODO: add this back in - // and - // if this instanceof IrqlRestrictsFunction - // then irqlLevel = getAllowableIrqlLevel(this) - // else irqlLevel = -1 - } - - // TODO: add this back in - // int getExpectedIrqlLevelString() { result = irqlLevel } - string getRoleTypeString() { result = roleType.getName() } - - RoleTypeType getRoleTypeType() { result = roleType } -} - -/** - */ -class DriverObjectFunctionAccess extends FunctionAccess { - RoleTypeType rttExpected; - - DriverObjectFunctionAccess() { - exists(VariableAccess driverObjectAccess, AssignExpr driverObjectAssign | - driverObjectAccess.getTarget().getType().getName().matches("PDRIVER_OBJECT") and - this = driverObjectAssign.getRValue() and - rttExpected = driverObjectAssign.getLValue().getUnderlyingType().(PointerType).getBaseType() - ) - } - - RoleTypeType getExpectedRoleTypeType() { result = rttExpected } -} - -/** - * Declared functions that are used as if they have a role type, wether or not they do - */ -class ImplicitRoleTypeFunction extends Function { - RoleTypeType rttExpected; - FunctionAccess funcUse; - - ImplicitRoleTypeFunction() { - ( - exists(FunctionCall fc, int n | fc.getArgument(n) instanceof FunctionAccess | - this = fc.getArgument(n).(FunctionAccess).getTarget() and - rttExpected = fc.getTarget().getParameter(n).getUnderlyingType().(PointerType).getBaseType() and - funcUse = fc.getArgument(n) - ) - or - exists(DriverObjectFunctionAccess funcAssign | - funcAssign.getTarget() = this and - rttExpected = funcAssign.getExpectedRoleTypeType() and - funcUse = funcAssign - ) - ) and - this.hasCLinkage() - } - - string getExpectedRoleTypeString() { result = rttExpected.getName() } - - RoleTypeType getExpectedRoleTypeType() { result = rttExpected } - - string getActualRoleTypeString() { - if not this instanceof RoleTypeFunction - then result = "" - else result = this.(RoleTypeFunction).getRoleTypeType().toString() - } - - // TODO: add this back in - // int getExpectedIrqlLevel() { - // if rttExpected instanceof IrqlAnnotatedTypedef - // then result = getAlloweableIrqlLevel(rttExpected) - // else result = -1 - // } - // int getFoundIrqlLevel() { - // if this instanceof IrqlRestrictsFunction - // then result = getAllowableIrqlLevel(this) - // else result = -1 - // } - FunctionAccess getFunctionUse() { result = funcUse } -} - -/** Predicates */ -predicate roleTypeAssignment(AssignExpr ae) { - exists(FunctionAccess fa | - ae.getRValue() = fa and - fa.getTarget() instanceof WdmDispatchRoutine - ) - or - ae.getRValue() instanceof AssignExpr and - roleTypeAssignment(ae.getRValue().(AssignExpr)) -} - -class ImplicitWdmRoutine extends Function { - ImplicitWdmRoutine(){ - this instanceof ImplicitRoleTypeFunction - } -} -/** A WDM DriverEntry callback routine. */ -class ImplicitWdmDriverEntry extends ImplicitWdmRoutine { - ImplicitWdmDriverEntry() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_INITIALIZE") } - - string getExpectedMaxIrqlLevelString() { result = "PASSIVE_LEVEL" } - - string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } -} - -/** A WDM DrierStartIo callback routine */ -class ImplicitWdmDriverStartIo extends ImplicitWdmRoutine { - ImplicitWdmDriverStartIo() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_STARTIO") } - - string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } - - string getExpectedMinIrqlLevelString() { result = "DRIVER_STARTIO" } -} - -/** - * A WDM DriverUnload callback routine. - */ -class ImplicitWdmDriverUnload extends ImplicitWdmRoutine { - ImplicitWdmDriverUnload() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_UNLOAD") } - - string getExpectedMaxIrqlLevelString() { result = "PASSIVE_LEVEL" } - - string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } -} - -// NOTE duplicate for backward compatibility with other query. Remove when other query is updated. -/** A WDM AddDevice callback routine. */ -class ImplicitWdmAddDevice extends ImplicitWdmRoutine { - ImplicitWdmAddDevice() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_ADD_DEVICE") } -} - -/** - * A WDM DriverAddDevice callback routine. - */ -class ImplicitWdmDriverAddDevice extends ImplicitWdmRoutine { - ImplicitWdmDriverAddDevice() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_ADD_DEVICE") } - - string getExpectedMaxIrqlLevelString() { result = "PASSIVE_LEVEL" } - - string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } -} - -/** - * A WDM DriverDispatch callback routine. - */ -class ImplicitWdmDriverDispatch extends ImplicitWdmRoutine { - ImplicitWdmDriverDispatch() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_DISPATCH") } - - string getExpectedMaxIrqlLevelString() { result = "PASSIVE_LEVEL" } - - string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } -} - -/** - * A WDM IO completion routine. - */ -class ImplicitWdmDriverCompletionRoutine extends ImplicitWdmRoutine { - ImplicitWdmDriverCompletionRoutine() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("IO_COMPLETION_ROUTINE") } - - string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } - - string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } -} - -/** - * A WDM DriverCancel callback routine. - */ -class ImplicitWdmDriverCancel extends ImplicitWdmRoutine { - ImplicitWdmDriverCancel() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_CANCEL") } - - string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } - string getExpectedMinIrqlLevelString() { result = "DISPATCH_LEVEL" } - -} - -/** - * A WDM DriverDpcRoutine callback routine. - */ -class ImplicitWdmDriverDpcRoutine extends ImplicitWdmRoutine { - ImplicitWdmDriverDpcRoutine() { - this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("IO_DPC_ROUTINE") - } - - string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } - - string getExpectedMinIrqlLevelString() { result = "DISPATCH_LEVEL" } -} - -/** - * A WDM DriverDeferredRoutine callback routine. - */ -class ImplicitWdmDriverDeferredRoutine extends ImplicitWdmRoutine { - ImplicitWdmDriverDeferredRoutine() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("KDEFERRED_ROUTINE") } - - string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } - - string getExpectedMinIrqlLevelString() { result = "DISPATCH_LEVEL" } -} - -/** - * A WDM DriverServiceRoutine callback routine. - */ -class ImplicitWdmDriverServiceRoutine extends ImplicitWdmRoutine { - ImplicitWdmDriverServiceRoutine() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("KSERVICE_ROUTINE") } - - string getExpectedMaxIrqlLevelString() { result = "DIRQL" } - - string getExpectedMinIrqlLevelString() { result = "DIRQL" } -} - -/** - * A WDM DriverPowerComplete callback routine. - */ -class ImplicitWdmDriverPowerComplete extends ImplicitWdmRoutine { - ImplicitWdmDriverPowerComplete() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("REQUEST_POWER_COMPLETE") } - - string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } - - string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } -} - -/** - * A WDM DriverWorkerThreadRoutine callback routine. - */ -class ImplicitWdmDriverWorkerThreadRoutine extends ImplicitWdmRoutine { - ImplicitWdmDriverWorkerThreadRoutine() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("WORKER_THREAD_ROUTINE") } - - string getExpectedMaxIrqlLevelString() { result = "PASSIVE_LEVEL" } - - string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } +import cpp +import drivers.libraries.SAL +// import drivers.libraries.Irql // TODO: add this back in +import drivers.wdm.libraries.WdmDrivers +import drivers.kmdf.libraries.KmdfDrivers +import drivers.ndis.libraries.NdisDrivers +import drivers.storport.libraries.StorportDrivers + +/** + * Special case to check for RoleType equality for role types in wdfroletypes.h + */ +bindingset[rtt1, rtt2] +predicate isEqualRoleTypes(string rtt1, string rtt2) { + rtt1.matches("EVT_WDF_%_CONTEXT_DESTROY%") and + rtt2.matches("EVT_WDF_%_CONTEXT_DESTROY%") + or + rtt1.matches("EVT_WDF_%_CONTEXT_CLEANUP%") and + rtt2.matches("EVT_WDF_%_CONTEXT_CLEANUP%") + or + rtt1 = rtt2 +} + +/** + * Generic role type for WDM,KMDF, and others + */ +class RoleTypeType extends TypedefType { + RoleTypeType() { + this instanceof WdmRoleTypeType or + this instanceof KmdfRoleTypeType or + this instanceof NdisRoleTypeType or + this instanceof StorportRoleTypeType + } +} + +/** + * Role Type annotations which apply to entire functions + */ +class RoleTypeFunctionAnnotation extends SALAnnotation { + string roleTypeString; + string roleTypeName; + + RoleTypeFunctionAnnotation() { + ( + this.getMacroName().matches(["_Function_class_"]) and + roleTypeString = this.getUnexpandedArgument(0) + ) and + roleTypeName = this.getMacroName() + } + + /** + * Returns the raw text of the role type value used in this annotation. + */ + string getRoleTypeString() { result = roleTypeString } + + /** + * Returns the text of this annotation + */ + string getRoleTypeMacroName() { result = roleTypeName } +} + +/** + * A typedef that has Role Type annotations applied to it. + */ +class RoleTypeAnnotatedTypedef extends TypedefType { + RoleTypeFunctionAnnotation roleTypeAnnotation; + + RoleTypeAnnotatedTypedef() { roleTypeAnnotation.getTypedefDeclarations() = this } + + RoleTypeFunctionAnnotation getRoleTypeAnnotation() { result = roleTypeAnnotation } +} + +/** + * A function that is annotated to specify role type + */ +class RoleTypeAnnotatedFunction extends Function { + RoleTypeFunctionAnnotation roleTypeAnnotation; + + RoleTypeAnnotatedFunction() { + ( + this.hasCLinkage() and + exists( + FunctionDeclarationEntry fde // actual function declarations + | + fde = this.getADeclarationEntry() and + roleTypeAnnotation.getDeclarationEntry() = fde + ) + or + exists( + FunctionDeclarationEntry fde // typedefs + | + fde.getFunction() = this and + fde.getTypedefType().(RoleTypeAnnotatedTypedef).getRoleTypeAnnotation() = roleTypeAnnotation + ) + ) + } + + string getFuncRoleTypeAnnotation() { result = roleTypeAnnotation.getRoleTypeMacroName() } + + RoleTypeFunctionAnnotation getRoleTypeAnnotation() { result = roleTypeAnnotation } +} + +/** + * A function that is annotated or declared to specify role type + */ +class RoleTypeFunction extends Function { + RoleTypeType roleType; + + //int irqlLevel; // TODO: add this back in + RoleTypeFunction() { + this.hasCLinkage() and + ( + exists(FunctionDeclarationEntry fde | + ( + fde.getFunction() = this and + fde.getTypedefType() = roleType + ) + ) + or + this instanceof RoleTypeAnnotatedFunction and + roleType.getName() = + this.(RoleTypeAnnotatedFunction).getRoleTypeAnnotation().getRoleTypeString() + ) + // TODO: add this back in + // and + // if this instanceof IrqlRestrictsFunction + // then irqlLevel = getAllowableIrqlLevel(this) + // else irqlLevel = -1 + } + + // TODO: add this back in + // int getExpectedIrqlLevelString() { result = irqlLevel } + string getRoleTypeString() { result = roleType.getName() } + + RoleTypeType getRoleTypeType() { result = roleType } +} + +/** + */ +class DriverObjectFunctionAccess extends FunctionAccess { + RoleTypeType rttExpected; + + DriverObjectFunctionAccess() { + exists(VariableAccess driverObjectAccess, AssignExpr driverObjectAssign | + driverObjectAccess.getTarget().getType().getName().matches("PDRIVER_OBJECT") and + this = driverObjectAssign.getRValue() and + rttExpected = driverObjectAssign.getLValue().getUnderlyingType().(PointerType).getBaseType() + ) + } + + RoleTypeType getExpectedRoleTypeType() { result = rttExpected } +} + +/** + * Declared functions that are used as if they have a role type, wether or not they do + */ +class ImplicitRoleTypeFunction extends Function { + RoleTypeType rttExpected; + FunctionAccess funcUse; + + ImplicitRoleTypeFunction() { + ( + exists(FunctionCall fc, int n | fc.getArgument(n) instanceof FunctionAccess | + this = fc.getArgument(n).(FunctionAccess).getTarget() and + rttExpected = fc.getTarget().getParameter(n).getUnderlyingType().(PointerType).getBaseType() and + funcUse = fc.getArgument(n) + ) + or + exists(DriverObjectFunctionAccess funcAssign | + funcAssign.getTarget() = this and + rttExpected = funcAssign.getExpectedRoleTypeType() and + funcUse = funcAssign + ) + ) and + this.hasCLinkage() + } + + string getExpectedRoleTypeString() { result = rttExpected.getName() } + + RoleTypeType getExpectedRoleTypeType() { result = rttExpected } + + string getActualRoleTypeString() { + if not this instanceof RoleTypeFunction + then result = "" + else result = this.(RoleTypeFunction).getRoleTypeType().toString() + } + + // TODO: add this back in + // int getExpectedIrqlLevel() { + // if rttExpected instanceof IrqlAnnotatedTypedef + // then result = getAlloweableIrqlLevel(rttExpected) + // else result = -1 + // } + // int getFoundIrqlLevel() { + // if this instanceof IrqlRestrictsFunction + // then result = getAllowableIrqlLevel(this) + // else result = -1 + // } + FunctionAccess getFunctionUse() { result = funcUse } +} + +/** Predicates */ +predicate roleTypeAssignment(AssignExpr ae) { + exists(FunctionAccess fa | + ae.getRValue() = fa and + fa.getTarget() instanceof WdmDispatchRoutine + ) + or + ae.getRValue() instanceof AssignExpr and + roleTypeAssignment(ae.getRValue().(AssignExpr)) +} + +class ImplicitWdmRoutine extends Function { + ImplicitWdmRoutine(){ + this instanceof ImplicitRoleTypeFunction + } +} +/** A WDM DriverEntry callback routine. */ +class ImplicitWdmDriverEntry extends ImplicitWdmRoutine { + ImplicitWdmDriverEntry() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_INITIALIZE") } + + string getExpectedMaxIrqlLevelString() { result = "PASSIVE_LEVEL" } + + string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } +} + +/** A WDM DrierStartIo callback routine */ +class ImplicitWdmDriverStartIo extends ImplicitWdmRoutine { + ImplicitWdmDriverStartIo() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_STARTIO") } + + string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } + + string getExpectedMinIrqlLevelString() { result = "DRIVER_STARTIO" } +} + +/** + * A WDM DriverUnload callback routine. + */ +class ImplicitWdmDriverUnload extends ImplicitWdmRoutine { + ImplicitWdmDriverUnload() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_UNLOAD") } + + string getExpectedMaxIrqlLevelString() { result = "PASSIVE_LEVEL" } + + string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } +} + +// NOTE duplicate for backward compatibility with other query. Remove when other query is updated. +/** A WDM AddDevice callback routine. */ +class ImplicitWdmAddDevice extends ImplicitWdmRoutine { + ImplicitWdmAddDevice() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_ADD_DEVICE") } +} + +/** + * A WDM DriverAddDevice callback routine. + */ +class ImplicitWdmDriverAddDevice extends ImplicitWdmRoutine { + ImplicitWdmDriverAddDevice() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_ADD_DEVICE") } + + string getExpectedMaxIrqlLevelString() { result = "PASSIVE_LEVEL" } + + string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } +} + +/** + * A WDM DriverDispatch callback routine. + */ +class ImplicitWdmDriverDispatch extends ImplicitWdmRoutine { + ImplicitWdmDriverDispatch() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_DISPATCH") } + + string getExpectedMaxIrqlLevelString() { result = "PASSIVE_LEVEL" } + + string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } +} + +/** + * A WDM IO completion routine. + */ +class ImplicitWdmDriverCompletionRoutine extends ImplicitWdmRoutine { + ImplicitWdmDriverCompletionRoutine() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("IO_COMPLETION_ROUTINE") } + + string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } + + string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } +} + +/** + * A WDM DriverCancel callback routine. + */ +class ImplicitWdmDriverCancel extends ImplicitWdmRoutine { + ImplicitWdmDriverCancel() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("DRIVER_CANCEL") } + + string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } + string getExpectedMinIrqlLevelString() { result = "DISPATCH_LEVEL" } + +} + +/** + * A WDM DriverDpcRoutine callback routine. + */ +class ImplicitWdmDriverDpcRoutine extends ImplicitWdmRoutine { + ImplicitWdmDriverDpcRoutine() { + this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("IO_DPC_ROUTINE") + } + + string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } + + string getExpectedMinIrqlLevelString() { result = "DISPATCH_LEVEL" } +} + +/** + * A WDM DriverDeferredRoutine callback routine. + */ +class ImplicitWdmDriverDeferredRoutine extends ImplicitWdmRoutine { + ImplicitWdmDriverDeferredRoutine() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("KDEFERRED_ROUTINE") } + + string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } + + string getExpectedMinIrqlLevelString() { result = "DISPATCH_LEVEL" } +} + +/** + * A WDM DriverServiceRoutine callback routine. + */ +class ImplicitWdmDriverServiceRoutine extends ImplicitWdmRoutine { + ImplicitWdmDriverServiceRoutine() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("KSERVICE_ROUTINE") } + + string getExpectedMaxIrqlLevelString() { result = "DIRQL" } + + string getExpectedMinIrqlLevelString() { result = "DIRQL" } +} + +/** + * A WDM DriverPowerComplete callback routine. + */ +class ImplicitWdmDriverPowerComplete extends ImplicitWdmRoutine { + ImplicitWdmDriverPowerComplete() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("REQUEST_POWER_COMPLETE") } + + string getExpectedMaxIrqlLevelString() { result = "DISPATCH_LEVEL" } + + string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } +} + +/** + * A WDM DriverWorkerThreadRoutine callback routine. + */ +class ImplicitWdmDriverWorkerThreadRoutine extends ImplicitWdmRoutine { + ImplicitWdmDriverWorkerThreadRoutine() { this.(ImplicitRoleTypeFunction).getExpectedRoleTypeString().matches("WORKER_THREAD_ROUTINE") } + + string getExpectedMaxIrqlLevelString() { result = "PASSIVE_LEVEL" } + + string getExpectedMinIrqlLevelString() { result = "PASSIVE_LEVEL" } } \ No newline at end of file diff --git a/src/drivers/libraries/SAL.qll b/codeql/src/drivers/libraries/SAL.qll similarity index 100% rename from src/drivers/libraries/SAL.qll rename to codeql/src/drivers/libraries/SAL.qll diff --git a/src/drivers/libraries/Suppression.qll b/codeql/src/drivers/libraries/Suppression.qll similarity index 100% rename from src/drivers/libraries/Suppression.qll rename to codeql/src/drivers/libraries/Suppression.qll diff --git a/src/drivers/libraries/wfp.qll b/codeql/src/drivers/libraries/wfp.qll similarity index 100% rename from src/drivers/libraries/wfp.qll rename to codeql/src/drivers/libraries/wfp.qll diff --git a/src/drivers/ndis/libraries/NdisDrivers.qll b/codeql/src/drivers/ndis/libraries/NdisDrivers.qll similarity index 97% rename from src/drivers/ndis/libraries/NdisDrivers.qll rename to codeql/src/drivers/ndis/libraries/NdisDrivers.qll index 8220edb8..544ae9e2 100644 --- a/src/drivers/ndis/libraries/NdisDrivers.qll +++ b/codeql/src/drivers/ndis/libraries/NdisDrivers.qll @@ -1,845 +1,845 @@ -/** - * This QL library defines classes and predicates for analyzing NDIS drivers. - * It provides definitions for NDIS dispatch routines, callback routines, and role types. - * The library also includes a typedef for the standard NDIS callback routines. - */ - -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -import cpp -import drivers.libraries.SAL - -/** - * NDIS dispatch routine class. - * We hold a routine to be a dispatch routine if there is - * an assignment in DriverEntry that assigns the function to - * the dispatch table. - */ -class NdisDispatchRoutine extends NdisCallbackRoutine { - /** - * The OID type covered by this dispatch routine. - */ - Literal dispatchType; - /** The DriverEntry function this dispatch routine was assigned in. */ - NdisDriverEntry driverEntry; - - /** - * Dispatch routines are defined by assignments of the form - * MiniportDriverObject->DriverDispatch->MiniportXxxHandler = XxxHandler; - * This characteristic predicate thus looks for assignments of this form - * where the right-side value is a function with the NDIS_DISPATCH typedef. - */ - NdisDispatchRoutine() { - callbackType.getName().matches("NDIS_DISPATCH") and - exists( - NdisCallbackRoutineAssignment cra, PointerFieldAccess dispatchTable, - PointerFieldAccess fieldAccess, VariableAccess driverObjectAccess - | - cra.getLValue() = fieldAccess and - fieldAccess.getQualifier() = dispatchTable and - dispatchTable.getQualifier() = driverObjectAccess and - driverObjectAccess.getTarget().getType().getName().matches("PNDIS_MINIPORT_BLOCK") and - cra.getTarget() = this and - cra.getEnclosingFunction() = driverEntry - ) - } - - /** Gets the OID type this dispatch routine handles, as a number. */ - - Literal getDispatchType() { result = dispatchType } - - /** Gets the DriverEntry this dispatch routine was assigned in. */ - - NdisDriverEntry getDriverEntry() { result = driverEntry } -} - -/** An assignment where the right-hand side is a NDIS callback routine. */ -class NdisCallbackRoutineAssignment extends AssignExpr { - /* - * A common paradigm in dispatch routine setup is to chain assignments to cover multiple IRPs. - * As such, it's necessary to recursively walk the assignment to handle cases such as - * DriverObject->MajorFunction[IRP_MJ_CREATE] = - * DriverObject->MajorFunction[IRP_MJ_OPEN] = - * MyMultiFunctionIrpHandler; - * However, characterstic predicates cannot be recurisve, so the logic is placed in a separate - * predicate below, isNdisCallbackRoutineAssignment. - */ - - NdisCallbackRoutineAssignment() { isNdisCallbackRoutineAssignment(this) } - - /** Gets the callback routine that this dispatch routine assignment is targeting. */ - - NdisCallbackRoutine getTarget() { - if - exists(FunctionAccess fa | - this.getRValue() = fa and - fa.getTarget() instanceof NdisCallbackRoutine - ) - then result = this.getRValue().(FunctionAccess).getTarget() - else result = getTarget_aux(this.getRValue()) - } - - /** Auxilliary function to getTarget(). */ - private NdisCallbackRoutine getTarget_aux(AssignExpr ae) { - if - exists(FunctionAccess fa | - ae.getRValue() = fa and - fa.getTarget() instanceof NdisCallbackRoutine - ) - then result = ae.getRValue().(FunctionAccess).getTarget() - else result = getTarget_aux(ae.getRValue()) - } -} - -/** Determines if a given assignment, recursively, has a NDIS callback routine as the right-hand side. */ -private predicate isNdisCallbackRoutineAssignment(AssignExpr ae) { - exists(FunctionAccess fa | - ae.getRValue() = fa and - fa.getTarget() instanceof NdisCallbackRoutine - ) - or - ae.getRValue() instanceof AssignExpr and - isNdisCallbackRoutineAssignment(ae.getRValue().(AssignExpr)) -} - -/** A typedef for Role Types */ -class NdisRoleTypeType extends TypedefType { - NdisRoleTypeType() { - ( - this.getName().matches("MINIPORT_PROCESS_SG_LIST") or - this.getName().matches("NDIS_TIMER_FUNCTION") or - this.getName().matches("NDIS_IO_WORKITEM") or - this.getName().matches("MINIPORT_ADD_DEVICE") or - this.getName().matches("MINIPORT_CANCEL_DIRECT_OID_REQUEST") or - this.getName().matches("MINIPORT_DIRECT_OID_REQUEST") or - this.getName().matches("MINIPORT_FILTER_RESOURCE_REQUIREMENTS") or - this.getName().matches("MINIPORT_START_DEVICE") or - this.getName().matches("MINIPORT_SYNCHRONIZE_MESSAGE_INTERRUPT") or - this.getName().matches("NDIS_IO_WORKITEM_FUNCTION") or - this.getName().matches("FILTER_ATTACH") or - this.getName().matches("FILTER_CANCEL_DIRECT_OID_REQUEST") or - this.getName().matches("FILTER_CANCEL_SEND_NET_BUFFER_LISTS") or - this.getName().matches("FILTER_CANCEL_OID_REQUEST") or - this.getName().matches("FILTER_DETACH") or - this.getName().matches("FILTER_DEVICE_PNP_EVENT_NOTIFY") or - this.getName().matches("FILTER_DIRECT_OID_REQUEST") or - this.getName().matches("FILTER_DIRECT_OID_REQUEST_COMPLETE") or - this.getName().matches("DRIVER_UNLOAD") or - this.getName().matches("FILTER_NET_PNP_EVENT") or - this.getName().matches("FILTER_OID_REQUEST") or - this.getName().matches("FILTER_OID_REQUEST_COMPLETE") or - this.getName().matches("FILTER_PAUSE") or - this.getName().matches("FILTER_RECEIVE_NET_BUFFER_LISTS") or - this.getName().matches("FILTER_RESTART") or - this.getName().matches("FILTER_RETURN_NET_BUFFER_LISTS") or - this.getName().matches("FILTER_SEND_NET_BUFFER_LISTS") or - this.getName().matches("FILTER_SEND_NET_BUFFER_LISTS_COMPLETE") or - this.getName().matches("FILTER_SET_MODULE_OPTIONS") or - this.getName().matches("FILTER_SET_OPTIONS") or - this.getName().matches("FILTER_STATUS") or - this.getName().matches("MINIPORT_CO_ACTIVATE_VC") or - this.getName().matches("MINIPORT_CO_CREATE_VC") or - this.getName().matches("MINIPORT_CO_DEACTIVATE_VC") or - this.getName().matches("MINIPORT_CO_DELETE_VC") or - this.getName().matches("MINIPORT_CO_OID_REQUEST") or - this.getName().matches("MINIPORT_CO_SEND_NET_BUFFER_LISTS") or - this.getName().matches("PROTOCOL_BIND_ADAPTER_EX") or - this.getName().matches("PROTOCOL_CLOSE_ADAPTER_COMPLETE_EX") or - this.getName().matches("PROTOCOL_DIRECT_OID_REQUEST_COMPLETE") or - this.getName().matches("PROTOCOL_NET_PNP_EVENT") or - this.getName().matches("PROTOCOL_OID_REQUEST_COMPLETE") or - this.getName().matches("PROTOCOL_OPEN_ADAPTER_COMPLETE_EX") or - this.getName().matches("PROTOCOL_RECEIVE_NET_BUFFER_LISTS") or - this.getName().matches("PROTOCOL_SEND_NET_BUFFER_LISTS_COMPLETE") or - this.getName().matches("PROTOCOL_SET_OPTIONS") or - this.getName().matches("PROTOCOL_STATUS_EX") or - this.getName().matches("PROTOCOL_UNBIND_ADAPTER_EX") or - this.getName().matches("PROTOCOL_UNINSTALL") or - this.getName().matches("PROTOCOL_CL_ADD_PARTY_COMPLETE") or - this.getName().matches("PROTOCOL_CL_CALL_CONNECTED") or - this.getName().matches("PROTOCOL_CL_CLOSE_AF_COMPLETE") or - this.getName().matches("PROTOCOL_CL_CLOSE_CALL_COMPLETE") or - this.getName().matches("PROTOCOL_CL_DEREGISTER_SAP_COMPLETE") or - this.getName().matches("PROTOCOL_CL_DROP_PARTY_COMPLETE") or - this.getName().matches("PROTOCOL_CL_INCOMING_CALL") or - this.getName().matches("PROTOCOL_CL_INCOMING_CALL_QOS_CHANGE") or - this.getName().matches("PROTOCOL_CL_INCOMING_CLOSE_CALL") or - this.getName().matches("PROTOCOL_CL_INCOMING_DROP_PARTY") or - this.getName().matches("PROTOCOL_CL_MAKE_CALL_COMPLETE") or - this.getName().matches("PROTOCOL_CL_MODIFY_CALL_QOS_COMPLETE") or - this.getName().matches("PROTOCOL_CL_NOTIFY_CLOSE_AF") or - this.getName().matches("PROTOCOL_CL_OPEN_AF_COMPLETE") or - this.getName().matches("PROTOCOL_CL_OPEN_AF_COMPLETE_EX") or - this.getName().matches("PROTOCOL_CL_REGISTER_SAP_COMPLETE") or - this.getName().matches("PROTOCOL_CM_ACTIVATE_VC_COMPLETE") or - this.getName().matches("PROTOCOL_CM_ADD_PARTY") or - this.getName().matches("PROTOCOL_CM_CLOSE_AF") or - this.getName().matches("PROTOCOL_CM_CLOSE_CALL") or - this.getName().matches("PROTOCOL_CM_DEACTIVATE_VC_COMPLETE") or - this.getName().matches("PROTOCOL_CM_DEREGISTER_SAP") or - this.getName().matches("PROTOCOL_CM_DROP_PARTY") or - this.getName().matches("PROTOCOL_CM_INCOMING_CALL_COMPLETE") or - this.getName().matches("PROTOCOL_CM_MAKE_CALL") or - this.getName().matches("PROTOCOL_CM_MODIFY_QOS_CALL") or - this.getName().matches("PROTOCOL_CM_NOTIFY_CLOSE_AF_COMPLETE") or - this.getName().matches("PROTOCOL_CM_OPEN_AF") or - this.getName().matches("PROTOCOL_CM_REG_SAP") or - this.getName().matches("PROTCOL_CO_AF_REGISTER_NOTIFY") or - this.getName().matches("PROTOCOL_CO_CREATE_VC") or - this.getName().matches("PROTOCOL_CO_DELETE_VC") or - this.getName().matches("PROTOCOL_CO_OID_REQUEST") or - this.getName().matches("PROTOCOL_CO_OID_REQUEST_COMPLETE") or - this.getName().matches("PROTOCOL_CO_RECEIVE_NET_BUFFER_LISTS") or - this.getName().matches("PROTOCOL_CO_SEND_NET_BUFFER_LISTS_COMPLETE") or - this.getName().matches("PROTOCOL_CO_STATUS_EX") - ) - } -} - -/** A typedef for the standard NDIS callback routines. Aka Role Types */ -class NdisCallbackRoutineTypedef extends NdisRoleTypeType { - NdisCallbackRoutineTypedef() { this.getFile().getBaseName().matches("ndis.h") } -} - -/** - * Represents a function implementing a NDIS callback routine. - * Defines a function to be a callback routine iff it has a typedef - * in its definition which matches the NDIS callback typedefs, and it - * is in a NDIS driver (includes wdm.h.) - */ -class NdisCallbackRoutine extends Function { - /** The callback routine type, i.e. DRIVER_UNLOAD. */ - NdisCallbackRoutineTypedef callbackType; - - NdisCallbackRoutine() { - exists(FunctionDeclarationEntry fde | - fde.getFunction() = this and - fde.getTypedefType() = callbackType - ) - } -} - - -/** A NDIS DriverEntry callback routine. */ -class NdisDriverEntry extends NdisCallbackRoutine { - NdisDriverEntry() { callbackType.getName().matches("DRIVER_INITIALIZE") } -} - -/** A NDIS MiniportAllocateSharedMemoryComplete callback routine. */ -class NdisMiniportAllocateSharedMemoryComplete extends NdisCallbackRoutine { - NdisMiniportAllocateSharedMemoryComplete() { - callbackType.getName().matches("MINIPORT_ALLOCATE_SHARED_MEM_COMPLETE") - } -} - -/** A NDIS MiniportHalt callback routine. */ -class NdisMiniportHalt extends NdisCallbackRoutine { - NdisMiniportHalt() { callbackType.getName().matches("MINIPORT_HALT") } -} - -/** A NDIS MiniportSetOptions callback routine. */ -class NdisMiniportSetOptions extends NdisCallbackRoutine { - NdisMiniportSetOptions() { callbackType.getName().matches("MINIPORT_SET_OPTIONS") } -} - -/** A NDIS MiniportInitialize callback routine. */ -class NdisMiniportInitialize extends NdisCallbackRoutine { - NdisMiniportInitialize() { callbackType.getName().matches("MINIPORT_INITIALIZE") } -} - -/** A NDIS MiniportPause callback routine. */ -class NdisMiniportPause extends NdisCallbackRoutine { - NdisMiniportPause() { callbackType.getName().matches("MINIPORT_PAUSE") } -} - -/** A NDIS MiniportRestart callback routine. */ -class NdisMiniportRestart extends NdisCallbackRoutine { - NdisMiniportRestart() { callbackType.getName().matches("MINIPORT_RESTART") } -} - -/** A NDIS MiniportOidRequest callback routine. */ -class NdisMiniportOidRequest extends NdisCallbackRoutine { - NdisMiniportOidRequest() { callbackType.getName().matches("MINIPORT_OID_REQUEST") } -} - -/** A NDIS MiniportInterruptDpc callback routine. */ -class NdisMiniportInterruptDpc extends NdisCallbackRoutine { - NdisMiniportInterruptDpc() { callbackType.getName().matches("MINIPORT_INTERRUPT_DPC") } -} - -/** A NDIS MiniportIsr callback routine. */ -class NdisMiniportIsr extends NdisCallbackRoutine { - NdisMiniportIsr() { callbackType.getName().matches("MINIPORT_ISR") } -} - -/** A NDIS MiniportReset callback routine. */ -class NdisMiniportReset extends NdisCallbackRoutine { - NdisMiniportReset() { callbackType.getName().matches("MINIPORT_RESET") } -} - -/** A NDIS MiniportReturnNetBufferLists callback routine. */ -class NdisMiniportReturnNetBufferLists extends NdisCallbackRoutine { - NdisMiniportReturnNetBufferLists() { - callbackType.getName().matches("MINIPORT_RETURN_NET_BUFFER_LISTS") - } -} - -/** A NDIS MiniportCancelOidRequest callback routine. */ -class NdisMiniportCancelOidRequest extends NdisCallbackRoutine { - NdisMiniportCancelOidRequest() { callbackType.getName().matches("MINIPORT_CANCEL_OID_REQUEST") } -} - -/** A NDIS MiniportShutdown callback routine. */ -class NdisMiniportShutdown extends NdisCallbackRoutine { - NdisMiniportShutdown() { callbackType.getName().matches("MINIPORT_SHUTDOWN") } -} - -/** A NDIS MiniportSendNetBufferLists callback routine. */ -class NdisMiniportSendNetBufferLists extends NdisCallbackRoutine { - NdisMiniportSendNetBufferLists() { - callbackType.getName().matches("MINIPORT_SEND_NET_BUFFER_LISTS") - } -} - -/** A NDIS MiniportCancelSend callback routine. */ -class NdisMiniportCancelSend extends NdisCallbackRoutine { - NdisMiniportCancelSend() { callbackType.getName().matches("MINIPORT_CANCEL_SEND") } -} - -/** A NDIS MiniportDevicePnpEventNotify callback routine. */ -class NdisMiniportDevicePnpEventNotify extends NdisCallbackRoutine { - NdisMiniportDevicePnpEventNotify() { - callbackType.getName().matches("MINIPORT_DEVICE_PNP_EVENT_NOTIFY") - } -} - -/** A NDIS MiniportUnload callback routine. */ -class NdisMiniportUnload extends NdisCallbackRoutine { - NdisMiniportUnload() { callbackType.getName().matches("MINIPORT_UNLOAD") } -} - -/** A NDIS MiniportCheckForHang callback routine. */ -class NdisMiniportCheckForHang extends NdisCallbackRoutine { - NdisMiniportCheckForHang() { callbackType.getName().matches("MINIPORT_CHECK_FOR_HANG") } -} - -/** A NDIS MiniportEnableInterrupt callback routine. */ -class NdisMiniportEnableInterrupt extends NdisCallbackRoutine { - NdisMiniportEnableInterrupt() { callbackType.getName().matches("MINIPORT_ENABLE_INTERRUPT") } -} - -/** A NDIS MiniportDisableInterrupt callback routine. */ -class NdisMiniportDisableInterrupt extends NdisCallbackRoutine { - NdisMiniportDisableInterrupt() { callbackType.getName().matches("MINIPORT_DISABLE_INTERRUPT") } -} - -/** A NDIS MiniportSynchronizeInterrupt callback routine. */ -class NdisMiniportSynchronizeInterrupt extends NdisCallbackRoutine { - NdisMiniportSynchronizeInterrupt() { - callbackType.getName().matches("MINIPORT_SYNCHRONIZE_INTERRUPT") - } -} - -/** A NDIS MiniportProcessSgList callback routine. */ -class NdisMiniportProcessSgList extends NdisCallbackRoutine { - NdisMiniportProcessSgList() { callbackType.getName().matches("MINIPORT_PROCESS_SG_LIST") } -} - -/** A NDIS timer callback routine. */ -class NdisTimerFunction extends NdisCallbackRoutine { - NdisTimerFunction() { callbackType.getName().matches("NDIS_TIMER_FUNCTION") } -} - -/** A NDIS I/O work item callback routine. */ -class NdisIoWorkitem extends NdisCallbackRoutine { - NdisIoWorkitem() { callbackType.getName().matches("NDIS_IO_WORKITEM") } -} - -/** A NDIS MiniportAddDevice callback routine. */ -class NdisMiniportAddDevice extends NdisCallbackRoutine { - NdisMiniportAddDevice() { callbackType.getName().matches("MINIPORT_ADD_DEVICE") } -} - -/** A NDIS MiniportCancelDirectOidRequest callback routine. */ -class NdisMiniportCancelDirectOidRequest extends NdisCallbackRoutine { - NdisMiniportCancelDirectOidRequest() { - callbackType.getName().matches("MINIPORT_CANCEL_DIRECT_OID_REQUEST") - } -} - -/** A NDIS MiniportDirectOidRequest callback routine. */ -class NdisMiniportDirectOidRequest extends NdisCallbackRoutine { - NdisMiniportDirectOidRequest() { callbackType.getName().matches("MINIPORT_DIRECT_OID_REQUEST") } -} - -/** A NDIS MiniportFilterResourceRequirements callback routine. */ -class NdisMiniportFilterResourceRequirements extends NdisCallbackRoutine { - NdisMiniportFilterResourceRequirements() { - callbackType.getName().matches("MINIPORT_FILTER_RESOURCE_REQUIREMENTS") - } -} - -/** A NDIS MiniportStartDevice callback routine. */ -class NdisMiniportStartDevice extends NdisCallbackRoutine { - NdisMiniportStartDevice() { callbackType.getName().matches("MINIPORT_START_DEVICE") } -} - -/** A NDIS MiniportSynchronizeMessageInterrupt callback routine. */ -class NdisMiniportSynchronizeMessageInterrupt extends NdisCallbackRoutine { - NdisMiniportSynchronizeMessageInterrupt() { - callbackType.getName().matches("MINIPORT_SYNCHRONIZE_MESSAGE_INTERRUPT") - } -} - -/** A NDIS IoWorkItemFunction callback routine. */ -class NdisIoWorkItemFunction extends NdisCallbackRoutine { - NdisIoWorkItemFunction() { callbackType.getName().matches("NDIS_IO_WORKITEM_FUNCTION") } -} - -/** A NDIS filter attach callback routine. */ -class NdisFilterAttach extends NdisCallbackRoutine { - NdisFilterAttach() { callbackType.getName().matches("FILTER_ATTACH") } -} - -/** A NDIS filter cancel direct OID request callback routine. */ -class NdisFilterCancelDirectOidRequest extends NdisCallbackRoutine { - NdisFilterCancelDirectOidRequest() { - callbackType.getName().matches("FILTER_CANCEL_DIRECT_OID_REQUEST") - } -} - -/** A NDIS filter cancel send net buffer lists callback routine. */ -class NdisFilterCancelSendNetBufferLists extends NdisCallbackRoutine { - NdisFilterCancelSendNetBufferLists() { - callbackType.getName().matches("FILTER_CANCEL_SEND_NET_BUFFER_LISTS") - } -} - -/** A NDIS filter cancel OID request callback routine. */ -class NdisFilterCancelOidRequest extends NdisCallbackRoutine { - NdisFilterCancelOidRequest() { callbackType.getName().matches("FILTER_CANCEL_OID_REQUEST") } -} - -/** A NDIS filter detach callback routine. */ -class NdisFilterDetach extends NdisCallbackRoutine { - NdisFilterDetach() { callbackType.getName().matches("FILTER_DETACH") } -} - -/** A NDIS filter device PNP event notify callback routine. */ -class NdisFilterDevicePnpEventNotify extends NdisCallbackRoutine { - NdisFilterDevicePnpEventNotify() { - callbackType.getName().matches("FILTER_DEVICE_PNP_EVENT_NOTIFY") - } -} - -/** A NDIS filter direct OID request callback routine. */ -class NdisFilterDirectOidRequest extends NdisCallbackRoutine { - NdisFilterDirectOidRequest() { callbackType.getName().matches("FILTER_DIRECT_OID_REQUEST") } -} - -/** A NDIS filter direct OID request complete callback routine. */ -class NdisFilterDirectOidRequestComplete extends NdisCallbackRoutine { - NdisFilterDirectOidRequestComplete() { - callbackType.getName().matches("FILTER_DIRECT_OID_REQUEST_COMPLETE") - } -} - -/** A NDIS driver unload callback routine. */ -class NdisDriverUnload extends NdisCallbackRoutine { - NdisDriverUnload() { callbackType.getName().matches("DRIVER_UNLOAD") } -} - -/** A NDIS filter net PNP event callback routine. */ -class NdisFilterNetPnpEvent extends NdisCallbackRoutine { - NdisFilterNetPnpEvent() { callbackType.getName().matches("FILTER_NET_PNP_EVENT") } -} - -/** A NDIS filter OID request callback routine. */ -class NdisFilterOidRequest extends NdisCallbackRoutine { - NdisFilterOidRequest() { callbackType.getName().matches("FILTER_OID_REQUEST") } -} - -/** A NDIS filter OID request complete callback routine. */ -class NdisFilterOidRequestComplete extends NdisCallbackRoutine { - NdisFilterOidRequestComplete() { callbackType.getName().matches("FILTER_OID_REQUEST_COMPLETE") } -} - -/** A NDIS filter pause callback routine. */ -class NdisFilterPause extends NdisCallbackRoutine { - NdisFilterPause() { callbackType.getName().matches("FILTER_PAUSE") } -} - -/** A NDIS filter receive net buffer lists callback routine. */ -class NdisFilterReceiveNetBufferLists extends NdisCallbackRoutine { - NdisFilterReceiveNetBufferLists() { - callbackType.getName().matches("FILTER_RECEIVE_NET_BUFFER_LISTS") - } -} - -/** A NDIS filter restart callback routine. */ -class NdisFilterRestart extends NdisCallbackRoutine { - NdisFilterRestart() { callbackType.getName().matches("FILTER_RESTART") } -} - -/** A NDIS filter return net buffer lists callback routine. */ -class NdisFilterReturnNetBufferLists extends NdisCallbackRoutine { - NdisFilterReturnNetBufferLists() { - callbackType.getName().matches("FILTER_RETURN_NET_BUFFER_LISTS") - } -} - -/** A NDIS filter send net buffer lists callback routine. */ -class NdisFilterSendNetBufferLists extends NdisCallbackRoutine { - NdisFilterSendNetBufferLists() { callbackType.getName().matches("FILTER_SEND_NET_BUFFER_LISTS") } -} - -/** A NDIS filter send net buffer lists complete callback routine. */ -class NdisFilterSendNetBufferListsComplete extends NdisCallbackRoutine { - NdisFilterSendNetBufferListsComplete() { - callbackType.getName().matches("FILTER_SEND_NET_BUFFER_LISTS_COMPLETE") - } -} - -/** A NDIS filter set module options callback routine. */ -class NdisFilterSetModuleOptions extends NdisCallbackRoutine { - NdisFilterSetModuleOptions() { callbackType.getName().matches("FILTER_SET_MODULE_OPTIONS") } -} - -/** A NDIS filter set options callback routine. */ -class NdisFilterSetOptions extends NdisCallbackRoutine { - NdisFilterSetOptions() { callbackType.getName().matches("FILTER_SET_OPTIONS") } -} - -/** A NDIS filter status callback routine. */ -class NdisFilterStatus extends NdisCallbackRoutine { - NdisFilterStatus() { callbackType.getName().matches("FILTER_STATUS") } -} - -/** A NDIS miniport CO activate VC callback routine. */ -class NdisMiniportCoActivateVc extends NdisCallbackRoutine { - NdisMiniportCoActivateVc() { callbackType.getName().matches("MINIPORT_CO_ACTIVATE_VC") } -} - -/** A NDIS miniport CO create VC callback routine. */ -class NdisMiniportCoCreateVc extends NdisCallbackRoutine { - NdisMiniportCoCreateVc() { callbackType.getName().matches("MINIPORT_CO_CREATE_VC") } -} - -/** A NDIS miniport CO deactivate VC callback routine. */ -class NdisMiniportCoDeactivateVc extends NdisCallbackRoutine { - NdisMiniportCoDeactivateVc() { callbackType.getName().matches("MINIPORT_CO_DEACTIVATE_VC") } -} - -/** A NDIS miniport CO delete VC callback routine. */ -class NdisMiniportCoDeleteVc extends NdisCallbackRoutine { - NdisMiniportCoDeleteVc() { callbackType.getName().matches("MINIPORT_CO_DELETE_VC") } -} - -/** A NDIS miniport CO OID request callback routine. */ -class NdisMiniportCoOidRequest extends NdisCallbackRoutine { - NdisMiniportCoOidRequest() { callbackType.getName().matches("MINIPORT_CO_OID_REQUEST") } -} - -/** A NDIS miniport CO send net buffer lists callback routine. */ -class NdisMiniportCoSendNetBufferLists extends NdisCallbackRoutine { - NdisMiniportCoSendNetBufferLists() { - callbackType.getName().matches("MINIPORT_CO_SEND_NET_BUFFER_LISTS") - } -} - -/** A NDIS protocol bind adapter ex callback routine. */ -class NdisProtocolBindAdapterEx extends NdisCallbackRoutine { - NdisProtocolBindAdapterEx() { callbackType.getName().matches("PROTOCOL_BIND_ADAPTER_EX") } -} - -/** A NDIS protocol close adapter complete ex callback routine. */ -class NdisProtocolCloseAdapterCompleteEx extends NdisCallbackRoutine { - NdisProtocolCloseAdapterCompleteEx() { - callbackType.getName().matches("PROTOCOL_CLOSE_ADAPTER_COMPLETE_EX") - } -} - -/** A NDIS protocol direct OID request complete callback routine. */ -class NdisProtocolDirectOidRequestComplete extends NdisCallbackRoutine { - NdisProtocolDirectOidRequestComplete() { - callbackType.getName().matches("PROTOCOL_DIRECT_OID_REQUEST_COMPLETE") - } -} - -/** A NDIS protocol net PNP event callback routine. */ -class NdisProtocolNetPnpEvent extends NdisCallbackRoutine { - NdisProtocolNetPnpEvent() { callbackType.getName().matches("PROTOCOL_NET_PNP_EVENT") } -} - -/** A NDIS protocol OID request complete callback routine. */ -class NdisProtocolOidRequestComplete extends NdisCallbackRoutine { - NdisProtocolOidRequestComplete() { - callbackType.getName().matches("PROTOCOL_OID_REQUEST_COMPLETE") - } -} - -/** A NDIS protocol open adapter complete ex callback routine. */ -class NdisProtocolOpenAdapterCompleteEx extends NdisCallbackRoutine { - NdisProtocolOpenAdapterCompleteEx() { - callbackType.getName().matches("PROTOCOL_OPEN_ADAPTER_COMPLETE_EX") - } -} - -/** A NDIS protocol receive net buffer lists callback routine. */ -class NdisProtocolReceiveNetBufferLists extends NdisCallbackRoutine { - NdisProtocolReceiveNetBufferLists() { - callbackType.getName().matches("PROTOCOL_RECEIVE_NET_BUFFER_LISTS") - } -} - -/** A NDIS protocol send net buffer lists complete callback routine. */ -class NdisProtocolSendNetBufferListsComplete extends NdisCallbackRoutine { - NdisProtocolSendNetBufferListsComplete() { - callbackType.getName().matches("PROTOCOL_SEND_NET_BUFFER_LISTS_COMPLETE") - } -} - -/** A NDIS protocol set options callback routine. */ -class NdisProtocolSetOptions extends NdisCallbackRoutine { - NdisProtocolSetOptions() { callbackType.getName().matches("PROTOCOL_SET_OPTIONS") } -} - -/** A NDIS protocol status ex callback routine. */ -class NdisProtocolStatusEx extends NdisCallbackRoutine { - NdisProtocolStatusEx() { callbackType.getName().matches("PROTOCOL_STATUS_EX") } -} - -/** A NDIS protocol unbind adapter ex callback routine. */ -class NdisProtocolUnbindAdapterEx extends NdisCallbackRoutine { - NdisProtocolUnbindAdapterEx() { callbackType.getName().matches("PROTOCOL_UNBIND_ADAPTER_EX") } -} - -/** A NDIS protocol uninstall callback routine. */ -class NdisProtocolUninstall extends NdisCallbackRoutine { - NdisProtocolUninstall() { callbackType.getName().matches("PROTOCOL_UNINSTALL") } -} - -/** A NDIS protocol call manager add party complete callback routine. */ -class NdisProtocolClAddPartyComplete extends NdisCallbackRoutine { - NdisProtocolClAddPartyComplete() { - callbackType.getName().matches("PROTOCOL_CL_ADD_PARTY_COMPLETE") - } -} - -/** A NDIS protocol call manager call connected callback routine. */ -class NdisProtocolClCallConnected extends NdisCallbackRoutine { - NdisProtocolClCallConnected() { callbackType.getName().matches("PROTOCOL_CL_CALL_CONNECTED") } -} - -/** A NDIS protocol call manager close AF complete callback routine. */ -class NdisProtocolClCloseAfComplete extends NdisCallbackRoutine { - NdisProtocolClCloseAfComplete() { - callbackType.getName().matches("PROTOCOL_CL_CLOSE_AF_COMPLETE") - } -} - -/** A NDIS protocol call manager close call complete callback routine. */ -class NdisProtocolClCloseCallComplete extends NdisCallbackRoutine { - NdisProtocolClCloseCallComplete() { - callbackType.getName().matches("PROTOCOL_CL_CLOSE_CALL_COMPLETE") - } -} - -/** A NDIS protocol call manager deregister SAP complete callback routine. */ -class NdisProtocolClDeregisterSapComplete extends NdisCallbackRoutine { - NdisProtocolClDeregisterSapComplete() { - callbackType.getName().matches("PROTOCOL_CL_DEREGISTER_SAP_COMPLETE") - } -} - -/** A NDIS protocol call manager drop party complete callback routine. */ -class NdisProtocolClDropPartyComplete extends NdisCallbackRoutine { - NdisProtocolClDropPartyComplete() { - callbackType.getName().matches("PROTOCOL_CL_DROP_PARTY_COMPLETE") - } -} - -/** A NDIS protocol call manager incoming call callback routine. */ -class NdisProtocolClIncomingCall extends NdisCallbackRoutine { - NdisProtocolClIncomingCall() { callbackType.getName().matches("PROTOCOL_CL_INCOMING_CALL") } -} - -/** A NDIS protocol call manager incoming call QoS change callback routine. */ -class NdisProtocolClIncomingCallQosChange extends NdisCallbackRoutine { - NdisProtocolClIncomingCallQosChange() { - callbackType.getName().matches("PROTOCOL_CL_INCOMING_CALL_QOS_CHANGE") - } -} - -/** A NDIS protocol call manager incoming close call callback routine. */ -class NdisProtocolClIncomingCloseCall extends NdisCallbackRoutine { - NdisProtocolClIncomingCloseCall() { - callbackType.getName().matches("PROTOCOL_CL_INCOMING_CLOSE_CALL") - } -} - -/** A NDIS protocol call manager incoming drop party callback routine. */ -class NdisProtocolClIncomingDropParty extends NdisCallbackRoutine { - NdisProtocolClIncomingDropParty() { - callbackType.getName().matches("PROTOCOL_CL_INCOMING_DROP_PARTY") - } -} - -/** A NDIS protocol call manager make call complete callback routine. */ -class NdisProtocolClMakeCallComplete extends NdisCallbackRoutine { - NdisProtocolClMakeCallComplete() { - callbackType.getName().matches("PROTOCOL_CL_MAKE_CALL_COMPLETE") - } -} - -/** A NDIS protocol call manager modify call QoS complete callback routine. */ -class NdisProtocolClModifyCallQosComplete extends NdisCallbackRoutine { - NdisProtocolClModifyCallQosComplete() { - callbackType.getName().matches("PROTOCOL_CL_MODIFY_CALL_QOS_COMPLETE") - } -} - -/** A NDIS protocol call manager notify close AF callback routine. */ -class NdisProtocolClNotifyCloseAf extends NdisCallbackRoutine { - NdisProtocolClNotifyCloseAf() { callbackType.getName().matches("PROTOCOL_CL_NOTIFY_CLOSE_AF") } -} - -/** A NDIS protocol call manager open AF complete callback routine. */ -class NdisProtocolClOpenAfComplete extends NdisCallbackRoutine { - NdisProtocolClOpenAfComplete() { callbackType.getName().matches("PROTOCOL_CL_OPEN_AF_COMPLETE") } -} - -/** A NDIS protocol call manager open AF complete ex callback routine. */ -class NdisProtocolClOpenAfCompleteEx extends NdisCallbackRoutine { - NdisProtocolClOpenAfCompleteEx() { - callbackType.getName().matches("PROTOCOL_CL_OPEN_AF_COMPLETE_EX") - } -} - -/** A NDIS protocol call manager register SAP complete callback routine. */ -class NdisProtocolClRegisterSapComplete extends NdisCallbackRoutine { - NdisProtocolClRegisterSapComplete() { - callbackType.getName().matches("PROTOCOL_CL_REGISTER_SAP_COMPLETE") - } -} - -/** A NDIS protocol connection manager activate VC complete callback routine. */ -class NdisProtocolCmActivateVcComplete extends NdisCallbackRoutine { - NdisProtocolCmActivateVcComplete() { - callbackType.getName().matches("PROTOCOL_CM_ACTIVATE_VC_COMPLETE") - } -} - -/** A NDIS protocol connection manager add party callback routine. */ -class NdisProtocolCmAddParty extends NdisCallbackRoutine { - NdisProtocolCmAddParty() { callbackType.getName().matches("PROTOCOL_CM_ADD_PARTY") } -} - -/** A NDIS protocol connection manager close AF callback routine. */ -class NdisProtocolCmCloseAf extends NdisCallbackRoutine { - NdisProtocolCmCloseAf() { callbackType.getName().matches("PROTOCOL_CM_CLOSE_AF") } -} - -/** A NDIS protocol connection manager close call callback routine. */ -class NdisProtocolCmCloseCall extends NdisCallbackRoutine { - NdisProtocolCmCloseCall() { callbackType.getName().matches("PROTOCOL_CM_CLOSE_CALL") } -} - -/** A NDIS protocol connection manager deactivate VC complete callback routine. */ -class NdisProtocolCmDeactivateVcComplete extends NdisCallbackRoutine { - NdisProtocolCmDeactivateVcComplete() { - callbackType.getName().matches("PROTOCOL_CM_DEACTIVATE_VC_COMPLETE") - } -} - -/** A NDIS protocol connection manager deregister SAP callback routine. */ -class NdisProtocolCmDeregisterSap extends NdisCallbackRoutine { - NdisProtocolCmDeregisterSap() { callbackType.getName().matches("PROTOCOL_CM_DEREGISTER_SAP") } -} - -/** A NDIS protocol connection manager drop party callback routine. */ -class NdisProtocolCmDropParty extends NdisCallbackRoutine { - NdisProtocolCmDropParty() { callbackType.getName().matches("PROTOCOL_CM_DROP_PARTY") } -} - -/** A NDIS protocol connection manager incoming call complete callback routine. */ -class NdisProtocolCmIncomingCallComplete extends NdisCallbackRoutine { - NdisProtocolCmIncomingCallComplete() { - callbackType.getName().matches("PROTOCOL_CM_INCOMING_CALL_COMPLETE") - } -} - -/** A NDIS protocol connection manager make call callback routine. */ -class NdisProtocolCmMakeCall extends NdisCallbackRoutine { - NdisProtocolCmMakeCall() { callbackType.getName().matches("PROTOCOL_CM_MAKE_CALL") } -} - -/** A NDIS protocol connection manager modify QoS call callback routine. */ -class NdisProtocolCmModifyQosCall extends NdisCallbackRoutine { - NdisProtocolCmModifyQosCall() { callbackType.getName().matches("PROTOCOL_CM_MODIFY_QOS_CALL") } -} - -/** A NDIS protocol connection manager notify close AF complete callback routine. */ -class NdisProtocolCmNotifyCloseAfComplete extends NdisCallbackRoutine { - NdisProtocolCmNotifyCloseAfComplete() { - callbackType.getName().matches("PROTOCOL_CM_NOTIFY_CLOSE_AF_COMPLETE") - } -} - -/** A NDIS protocol connection manager open AF callback routine. */ -class NdisProtocolCmOpenAf extends NdisCallbackRoutine { - NdisProtocolCmOpenAf() { callbackType.getName().matches("PROTOCOL_CM_OPEN_AF") } -} - -/** A NDIS protocol connection manager register SAP callback routine. */ -class NdisProtocolCmRegSap extends NdisCallbackRoutine { - NdisProtocolCmRegSap() { callbackType.getName().matches("PROTOCOL_CM_REG_SAP") } -} - -/** A NDIS protocol CO AF register notify callback routine. */ -class NdisProtocolCoAfRegisterNotify extends NdisCallbackRoutine { - NdisProtocolCoAfRegisterNotify() { - callbackType.getName().matches("PROTCOL_CO_AF_REGISTER_NOTIFY") - } -} - -/** A NDIS protocol CO create VC callback routine. */ -class NdisProtocolCoCreateVc extends NdisCallbackRoutine { - NdisProtocolCoCreateVc() { callbackType.getName().matches("PROTOCOL_CO_CREATE_VC") } -} - -/** A NDIS protocol CO delete VC callback routine. */ -class NdisProtocolCoDeleteVc extends NdisCallbackRoutine { - NdisProtocolCoDeleteVc() { callbackType.getName().matches("PROTOCOL_CO_DELETE_VC") } -} - -/** A NDIS protocol CO OID request callback routine. */ -class NdisProtocolCoOidRequest extends NdisCallbackRoutine { - NdisProtocolCoOidRequest() { callbackType.getName().matches("PROTOCOL_CO_OID_REQUEST") } -} - -/** A NDIS protocol CO OID request complete callback routine. */ -class NdisProtocolCoOidRequestComplete extends NdisCallbackRoutine { - NdisProtocolCoOidRequestComplete() { - callbackType.getName().matches("PROTOCOL_CO_OID_REQUEST_COMPLETE") - } -} - -/** A NDIS protocol CO receive net buffer lists callback routine. */ -class NdisProtocolCoReceiveNetBufferLists extends NdisCallbackRoutine { - NdisProtocolCoReceiveNetBufferLists() { - callbackType.getName().matches("PROTOCOL_CO_RECEIVE_NET_BUFFER_LISTS") - } -} - -/** A NDIS protocol CO send net buffer lists complete callback routine. */ -class NdisProtocolCoSendNetBufferListsComplete extends NdisCallbackRoutine { - NdisProtocolCoSendNetBufferListsComplete() { - callbackType.getName().matches("PROTOCOL_CO_SEND_NET_BUFFER_LISTS_COMPLETE") - } -} - -/** A NDIS protocol CO status ex callback routine. */ -class NdisProtocolCoStatusEx extends NdisCallbackRoutine { - NdisProtocolCoStatusEx() { callbackType.getName().matches("PROTOCOL_CO_STATUS_EX") } -} +/** + * This QL library defines classes and predicates for analyzing NDIS drivers. + * It provides definitions for NDIS dispatch routines, callback routines, and role types. + * The library also includes a typedef for the standard NDIS callback routines. + */ + +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +import cpp +import drivers.libraries.SAL + +/** + * NDIS dispatch routine class. + * We hold a routine to be a dispatch routine if there is + * an assignment in DriverEntry that assigns the function to + * the dispatch table. + */ +class NdisDispatchRoutine extends NdisCallbackRoutine { + /** + * The OID type covered by this dispatch routine. + */ + Literal dispatchType; + /** The DriverEntry function this dispatch routine was assigned in. */ + NdisDriverEntry driverEntry; + + /** + * Dispatch routines are defined by assignments of the form + * MiniportDriverObject->DriverDispatch->MiniportXxxHandler = XxxHandler; + * This characteristic predicate thus looks for assignments of this form + * where the right-side value is a function with the NDIS_DISPATCH typedef. + */ + NdisDispatchRoutine() { + callbackType.getName().matches("NDIS_DISPATCH") and + exists( + NdisCallbackRoutineAssignment cra, PointerFieldAccess dispatchTable, + PointerFieldAccess fieldAccess, VariableAccess driverObjectAccess + | + cra.getLValue() = fieldAccess and + fieldAccess.getQualifier() = dispatchTable and + dispatchTable.getQualifier() = driverObjectAccess and + driverObjectAccess.getTarget().getType().getName().matches("PNDIS_MINIPORT_BLOCK") and + cra.getTarget() = this and + cra.getEnclosingFunction() = driverEntry + ) + } + + /** Gets the OID type this dispatch routine handles, as a number. */ + + Literal getDispatchType() { result = dispatchType } + + /** Gets the DriverEntry this dispatch routine was assigned in. */ + + NdisDriverEntry getDriverEntry() { result = driverEntry } +} + +/** An assignment where the right-hand side is a NDIS callback routine. */ +class NdisCallbackRoutineAssignment extends AssignExpr { + /* + * A common paradigm in dispatch routine setup is to chain assignments to cover multiple IRPs. + * As such, it's necessary to recursively walk the assignment to handle cases such as + * DriverObject->MajorFunction[IRP_MJ_CREATE] = + * DriverObject->MajorFunction[IRP_MJ_OPEN] = + * MyMultiFunctionIrpHandler; + * However, characterstic predicates cannot be recurisve, so the logic is placed in a separate + * predicate below, isNdisCallbackRoutineAssignment. + */ + + NdisCallbackRoutineAssignment() { isNdisCallbackRoutineAssignment(this) } + + /** Gets the callback routine that this dispatch routine assignment is targeting. */ + + NdisCallbackRoutine getTarget() { + if + exists(FunctionAccess fa | + this.getRValue() = fa and + fa.getTarget() instanceof NdisCallbackRoutine + ) + then result = this.getRValue().(FunctionAccess).getTarget() + else result = getTarget_aux(this.getRValue()) + } + + /** Auxilliary function to getTarget(). */ + private NdisCallbackRoutine getTarget_aux(AssignExpr ae) { + if + exists(FunctionAccess fa | + ae.getRValue() = fa and + fa.getTarget() instanceof NdisCallbackRoutine + ) + then result = ae.getRValue().(FunctionAccess).getTarget() + else result = getTarget_aux(ae.getRValue()) + } +} + +/** Determines if a given assignment, recursively, has a NDIS callback routine as the right-hand side. */ +private predicate isNdisCallbackRoutineAssignment(AssignExpr ae) { + exists(FunctionAccess fa | + ae.getRValue() = fa and + fa.getTarget() instanceof NdisCallbackRoutine + ) + or + ae.getRValue() instanceof AssignExpr and + isNdisCallbackRoutineAssignment(ae.getRValue().(AssignExpr)) +} + +/** A typedef for Role Types */ +class NdisRoleTypeType extends TypedefType { + NdisRoleTypeType() { + ( + this.getName().matches("MINIPORT_PROCESS_SG_LIST") or + this.getName().matches("NDIS_TIMER_FUNCTION") or + this.getName().matches("NDIS_IO_WORKITEM") or + this.getName().matches("MINIPORT_ADD_DEVICE") or + this.getName().matches("MINIPORT_CANCEL_DIRECT_OID_REQUEST") or + this.getName().matches("MINIPORT_DIRECT_OID_REQUEST") or + this.getName().matches("MINIPORT_FILTER_RESOURCE_REQUIREMENTS") or + this.getName().matches("MINIPORT_START_DEVICE") or + this.getName().matches("MINIPORT_SYNCHRONIZE_MESSAGE_INTERRUPT") or + this.getName().matches("NDIS_IO_WORKITEM_FUNCTION") or + this.getName().matches("FILTER_ATTACH") or + this.getName().matches("FILTER_CANCEL_DIRECT_OID_REQUEST") or + this.getName().matches("FILTER_CANCEL_SEND_NET_BUFFER_LISTS") or + this.getName().matches("FILTER_CANCEL_OID_REQUEST") or + this.getName().matches("FILTER_DETACH") or + this.getName().matches("FILTER_DEVICE_PNP_EVENT_NOTIFY") or + this.getName().matches("FILTER_DIRECT_OID_REQUEST") or + this.getName().matches("FILTER_DIRECT_OID_REQUEST_COMPLETE") or + this.getName().matches("DRIVER_UNLOAD") or + this.getName().matches("FILTER_NET_PNP_EVENT") or + this.getName().matches("FILTER_OID_REQUEST") or + this.getName().matches("FILTER_OID_REQUEST_COMPLETE") or + this.getName().matches("FILTER_PAUSE") or + this.getName().matches("FILTER_RECEIVE_NET_BUFFER_LISTS") or + this.getName().matches("FILTER_RESTART") or + this.getName().matches("FILTER_RETURN_NET_BUFFER_LISTS") or + this.getName().matches("FILTER_SEND_NET_BUFFER_LISTS") or + this.getName().matches("FILTER_SEND_NET_BUFFER_LISTS_COMPLETE") or + this.getName().matches("FILTER_SET_MODULE_OPTIONS") or + this.getName().matches("FILTER_SET_OPTIONS") or + this.getName().matches("FILTER_STATUS") or + this.getName().matches("MINIPORT_CO_ACTIVATE_VC") or + this.getName().matches("MINIPORT_CO_CREATE_VC") or + this.getName().matches("MINIPORT_CO_DEACTIVATE_VC") or + this.getName().matches("MINIPORT_CO_DELETE_VC") or + this.getName().matches("MINIPORT_CO_OID_REQUEST") or + this.getName().matches("MINIPORT_CO_SEND_NET_BUFFER_LISTS") or + this.getName().matches("PROTOCOL_BIND_ADAPTER_EX") or + this.getName().matches("PROTOCOL_CLOSE_ADAPTER_COMPLETE_EX") or + this.getName().matches("PROTOCOL_DIRECT_OID_REQUEST_COMPLETE") or + this.getName().matches("PROTOCOL_NET_PNP_EVENT") or + this.getName().matches("PROTOCOL_OID_REQUEST_COMPLETE") or + this.getName().matches("PROTOCOL_OPEN_ADAPTER_COMPLETE_EX") or + this.getName().matches("PROTOCOL_RECEIVE_NET_BUFFER_LISTS") or + this.getName().matches("PROTOCOL_SEND_NET_BUFFER_LISTS_COMPLETE") or + this.getName().matches("PROTOCOL_SET_OPTIONS") or + this.getName().matches("PROTOCOL_STATUS_EX") or + this.getName().matches("PROTOCOL_UNBIND_ADAPTER_EX") or + this.getName().matches("PROTOCOL_UNINSTALL") or + this.getName().matches("PROTOCOL_CL_ADD_PARTY_COMPLETE") or + this.getName().matches("PROTOCOL_CL_CALL_CONNECTED") or + this.getName().matches("PROTOCOL_CL_CLOSE_AF_COMPLETE") or + this.getName().matches("PROTOCOL_CL_CLOSE_CALL_COMPLETE") or + this.getName().matches("PROTOCOL_CL_DEREGISTER_SAP_COMPLETE") or + this.getName().matches("PROTOCOL_CL_DROP_PARTY_COMPLETE") or + this.getName().matches("PROTOCOL_CL_INCOMING_CALL") or + this.getName().matches("PROTOCOL_CL_INCOMING_CALL_QOS_CHANGE") or + this.getName().matches("PROTOCOL_CL_INCOMING_CLOSE_CALL") or + this.getName().matches("PROTOCOL_CL_INCOMING_DROP_PARTY") or + this.getName().matches("PROTOCOL_CL_MAKE_CALL_COMPLETE") or + this.getName().matches("PROTOCOL_CL_MODIFY_CALL_QOS_COMPLETE") or + this.getName().matches("PROTOCOL_CL_NOTIFY_CLOSE_AF") or + this.getName().matches("PROTOCOL_CL_OPEN_AF_COMPLETE") or + this.getName().matches("PROTOCOL_CL_OPEN_AF_COMPLETE_EX") or + this.getName().matches("PROTOCOL_CL_REGISTER_SAP_COMPLETE") or + this.getName().matches("PROTOCOL_CM_ACTIVATE_VC_COMPLETE") or + this.getName().matches("PROTOCOL_CM_ADD_PARTY") or + this.getName().matches("PROTOCOL_CM_CLOSE_AF") or + this.getName().matches("PROTOCOL_CM_CLOSE_CALL") or + this.getName().matches("PROTOCOL_CM_DEACTIVATE_VC_COMPLETE") or + this.getName().matches("PROTOCOL_CM_DEREGISTER_SAP") or + this.getName().matches("PROTOCOL_CM_DROP_PARTY") or + this.getName().matches("PROTOCOL_CM_INCOMING_CALL_COMPLETE") or + this.getName().matches("PROTOCOL_CM_MAKE_CALL") or + this.getName().matches("PROTOCOL_CM_MODIFY_QOS_CALL") or + this.getName().matches("PROTOCOL_CM_NOTIFY_CLOSE_AF_COMPLETE") or + this.getName().matches("PROTOCOL_CM_OPEN_AF") or + this.getName().matches("PROTOCOL_CM_REG_SAP") or + this.getName().matches("PROTCOL_CO_AF_REGISTER_NOTIFY") or + this.getName().matches("PROTOCOL_CO_CREATE_VC") or + this.getName().matches("PROTOCOL_CO_DELETE_VC") or + this.getName().matches("PROTOCOL_CO_OID_REQUEST") or + this.getName().matches("PROTOCOL_CO_OID_REQUEST_COMPLETE") or + this.getName().matches("PROTOCOL_CO_RECEIVE_NET_BUFFER_LISTS") or + this.getName().matches("PROTOCOL_CO_SEND_NET_BUFFER_LISTS_COMPLETE") or + this.getName().matches("PROTOCOL_CO_STATUS_EX") + ) + } +} + +/** A typedef for the standard NDIS callback routines. Aka Role Types */ +class NdisCallbackRoutineTypedef extends NdisRoleTypeType { + NdisCallbackRoutineTypedef() { this.getFile().getBaseName().matches("ndis.h") } +} + +/** + * Represents a function implementing a NDIS callback routine. + * Defines a function to be a callback routine iff it has a typedef + * in its definition which matches the NDIS callback typedefs, and it + * is in a NDIS driver (includes wdm.h.) + */ +class NdisCallbackRoutine extends Function { + /** The callback routine type, i.e. DRIVER_UNLOAD. */ + NdisCallbackRoutineTypedef callbackType; + + NdisCallbackRoutine() { + exists(FunctionDeclarationEntry fde | + fde.getFunction() = this and + fde.getTypedefType() = callbackType + ) + } +} + + +/** A NDIS DriverEntry callback routine. */ +class NdisDriverEntry extends NdisCallbackRoutine { + NdisDriverEntry() { callbackType.getName().matches("DRIVER_INITIALIZE") } +} + +/** A NDIS MiniportAllocateSharedMemoryComplete callback routine. */ +class NdisMiniportAllocateSharedMemoryComplete extends NdisCallbackRoutine { + NdisMiniportAllocateSharedMemoryComplete() { + callbackType.getName().matches("MINIPORT_ALLOCATE_SHARED_MEM_COMPLETE") + } +} + +/** A NDIS MiniportHalt callback routine. */ +class NdisMiniportHalt extends NdisCallbackRoutine { + NdisMiniportHalt() { callbackType.getName().matches("MINIPORT_HALT") } +} + +/** A NDIS MiniportSetOptions callback routine. */ +class NdisMiniportSetOptions extends NdisCallbackRoutine { + NdisMiniportSetOptions() { callbackType.getName().matches("MINIPORT_SET_OPTIONS") } +} + +/** A NDIS MiniportInitialize callback routine. */ +class NdisMiniportInitialize extends NdisCallbackRoutine { + NdisMiniportInitialize() { callbackType.getName().matches("MINIPORT_INITIALIZE") } +} + +/** A NDIS MiniportPause callback routine. */ +class NdisMiniportPause extends NdisCallbackRoutine { + NdisMiniportPause() { callbackType.getName().matches("MINIPORT_PAUSE") } +} + +/** A NDIS MiniportRestart callback routine. */ +class NdisMiniportRestart extends NdisCallbackRoutine { + NdisMiniportRestart() { callbackType.getName().matches("MINIPORT_RESTART") } +} + +/** A NDIS MiniportOidRequest callback routine. */ +class NdisMiniportOidRequest extends NdisCallbackRoutine { + NdisMiniportOidRequest() { callbackType.getName().matches("MINIPORT_OID_REQUEST") } +} + +/** A NDIS MiniportInterruptDpc callback routine. */ +class NdisMiniportInterruptDpc extends NdisCallbackRoutine { + NdisMiniportInterruptDpc() { callbackType.getName().matches("MINIPORT_INTERRUPT_DPC") } +} + +/** A NDIS MiniportIsr callback routine. */ +class NdisMiniportIsr extends NdisCallbackRoutine { + NdisMiniportIsr() { callbackType.getName().matches("MINIPORT_ISR") } +} + +/** A NDIS MiniportReset callback routine. */ +class NdisMiniportReset extends NdisCallbackRoutine { + NdisMiniportReset() { callbackType.getName().matches("MINIPORT_RESET") } +} + +/** A NDIS MiniportReturnNetBufferLists callback routine. */ +class NdisMiniportReturnNetBufferLists extends NdisCallbackRoutine { + NdisMiniportReturnNetBufferLists() { + callbackType.getName().matches("MINIPORT_RETURN_NET_BUFFER_LISTS") + } +} + +/** A NDIS MiniportCancelOidRequest callback routine. */ +class NdisMiniportCancelOidRequest extends NdisCallbackRoutine { + NdisMiniportCancelOidRequest() { callbackType.getName().matches("MINIPORT_CANCEL_OID_REQUEST") } +} + +/** A NDIS MiniportShutdown callback routine. */ +class NdisMiniportShutdown extends NdisCallbackRoutine { + NdisMiniportShutdown() { callbackType.getName().matches("MINIPORT_SHUTDOWN") } +} + +/** A NDIS MiniportSendNetBufferLists callback routine. */ +class NdisMiniportSendNetBufferLists extends NdisCallbackRoutine { + NdisMiniportSendNetBufferLists() { + callbackType.getName().matches("MINIPORT_SEND_NET_BUFFER_LISTS") + } +} + +/** A NDIS MiniportCancelSend callback routine. */ +class NdisMiniportCancelSend extends NdisCallbackRoutine { + NdisMiniportCancelSend() { callbackType.getName().matches("MINIPORT_CANCEL_SEND") } +} + +/** A NDIS MiniportDevicePnpEventNotify callback routine. */ +class NdisMiniportDevicePnpEventNotify extends NdisCallbackRoutine { + NdisMiniportDevicePnpEventNotify() { + callbackType.getName().matches("MINIPORT_DEVICE_PNP_EVENT_NOTIFY") + } +} + +/** A NDIS MiniportUnload callback routine. */ +class NdisMiniportUnload extends NdisCallbackRoutine { + NdisMiniportUnload() { callbackType.getName().matches("MINIPORT_UNLOAD") } +} + +/** A NDIS MiniportCheckForHang callback routine. */ +class NdisMiniportCheckForHang extends NdisCallbackRoutine { + NdisMiniportCheckForHang() { callbackType.getName().matches("MINIPORT_CHECK_FOR_HANG") } +} + +/** A NDIS MiniportEnableInterrupt callback routine. */ +class NdisMiniportEnableInterrupt extends NdisCallbackRoutine { + NdisMiniportEnableInterrupt() { callbackType.getName().matches("MINIPORT_ENABLE_INTERRUPT") } +} + +/** A NDIS MiniportDisableInterrupt callback routine. */ +class NdisMiniportDisableInterrupt extends NdisCallbackRoutine { + NdisMiniportDisableInterrupt() { callbackType.getName().matches("MINIPORT_DISABLE_INTERRUPT") } +} + +/** A NDIS MiniportSynchronizeInterrupt callback routine. */ +class NdisMiniportSynchronizeInterrupt extends NdisCallbackRoutine { + NdisMiniportSynchronizeInterrupt() { + callbackType.getName().matches("MINIPORT_SYNCHRONIZE_INTERRUPT") + } +} + +/** A NDIS MiniportProcessSgList callback routine. */ +class NdisMiniportProcessSgList extends NdisCallbackRoutine { + NdisMiniportProcessSgList() { callbackType.getName().matches("MINIPORT_PROCESS_SG_LIST") } +} + +/** A NDIS timer callback routine. */ +class NdisTimerFunction extends NdisCallbackRoutine { + NdisTimerFunction() { callbackType.getName().matches("NDIS_TIMER_FUNCTION") } +} + +/** A NDIS I/O work item callback routine. */ +class NdisIoWorkitem extends NdisCallbackRoutine { + NdisIoWorkitem() { callbackType.getName().matches("NDIS_IO_WORKITEM") } +} + +/** A NDIS MiniportAddDevice callback routine. */ +class NdisMiniportAddDevice extends NdisCallbackRoutine { + NdisMiniportAddDevice() { callbackType.getName().matches("MINIPORT_ADD_DEVICE") } +} + +/** A NDIS MiniportCancelDirectOidRequest callback routine. */ +class NdisMiniportCancelDirectOidRequest extends NdisCallbackRoutine { + NdisMiniportCancelDirectOidRequest() { + callbackType.getName().matches("MINIPORT_CANCEL_DIRECT_OID_REQUEST") + } +} + +/** A NDIS MiniportDirectOidRequest callback routine. */ +class NdisMiniportDirectOidRequest extends NdisCallbackRoutine { + NdisMiniportDirectOidRequest() { callbackType.getName().matches("MINIPORT_DIRECT_OID_REQUEST") } +} + +/** A NDIS MiniportFilterResourceRequirements callback routine. */ +class NdisMiniportFilterResourceRequirements extends NdisCallbackRoutine { + NdisMiniportFilterResourceRequirements() { + callbackType.getName().matches("MINIPORT_FILTER_RESOURCE_REQUIREMENTS") + } +} + +/** A NDIS MiniportStartDevice callback routine. */ +class NdisMiniportStartDevice extends NdisCallbackRoutine { + NdisMiniportStartDevice() { callbackType.getName().matches("MINIPORT_START_DEVICE") } +} + +/** A NDIS MiniportSynchronizeMessageInterrupt callback routine. */ +class NdisMiniportSynchronizeMessageInterrupt extends NdisCallbackRoutine { + NdisMiniportSynchronizeMessageInterrupt() { + callbackType.getName().matches("MINIPORT_SYNCHRONIZE_MESSAGE_INTERRUPT") + } +} + +/** A NDIS IoWorkItemFunction callback routine. */ +class NdisIoWorkItemFunction extends NdisCallbackRoutine { + NdisIoWorkItemFunction() { callbackType.getName().matches("NDIS_IO_WORKITEM_FUNCTION") } +} + +/** A NDIS filter attach callback routine. */ +class NdisFilterAttach extends NdisCallbackRoutine { + NdisFilterAttach() { callbackType.getName().matches("FILTER_ATTACH") } +} + +/** A NDIS filter cancel direct OID request callback routine. */ +class NdisFilterCancelDirectOidRequest extends NdisCallbackRoutine { + NdisFilterCancelDirectOidRequest() { + callbackType.getName().matches("FILTER_CANCEL_DIRECT_OID_REQUEST") + } +} + +/** A NDIS filter cancel send net buffer lists callback routine. */ +class NdisFilterCancelSendNetBufferLists extends NdisCallbackRoutine { + NdisFilterCancelSendNetBufferLists() { + callbackType.getName().matches("FILTER_CANCEL_SEND_NET_BUFFER_LISTS") + } +} + +/** A NDIS filter cancel OID request callback routine. */ +class NdisFilterCancelOidRequest extends NdisCallbackRoutine { + NdisFilterCancelOidRequest() { callbackType.getName().matches("FILTER_CANCEL_OID_REQUEST") } +} + +/** A NDIS filter detach callback routine. */ +class NdisFilterDetach extends NdisCallbackRoutine { + NdisFilterDetach() { callbackType.getName().matches("FILTER_DETACH") } +} + +/** A NDIS filter device PNP event notify callback routine. */ +class NdisFilterDevicePnpEventNotify extends NdisCallbackRoutine { + NdisFilterDevicePnpEventNotify() { + callbackType.getName().matches("FILTER_DEVICE_PNP_EVENT_NOTIFY") + } +} + +/** A NDIS filter direct OID request callback routine. */ +class NdisFilterDirectOidRequest extends NdisCallbackRoutine { + NdisFilterDirectOidRequest() { callbackType.getName().matches("FILTER_DIRECT_OID_REQUEST") } +} + +/** A NDIS filter direct OID request complete callback routine. */ +class NdisFilterDirectOidRequestComplete extends NdisCallbackRoutine { + NdisFilterDirectOidRequestComplete() { + callbackType.getName().matches("FILTER_DIRECT_OID_REQUEST_COMPLETE") + } +} + +/** A NDIS driver unload callback routine. */ +class NdisDriverUnload extends NdisCallbackRoutine { + NdisDriverUnload() { callbackType.getName().matches("DRIVER_UNLOAD") } +} + +/** A NDIS filter net PNP event callback routine. */ +class NdisFilterNetPnpEvent extends NdisCallbackRoutine { + NdisFilterNetPnpEvent() { callbackType.getName().matches("FILTER_NET_PNP_EVENT") } +} + +/** A NDIS filter OID request callback routine. */ +class NdisFilterOidRequest extends NdisCallbackRoutine { + NdisFilterOidRequest() { callbackType.getName().matches("FILTER_OID_REQUEST") } +} + +/** A NDIS filter OID request complete callback routine. */ +class NdisFilterOidRequestComplete extends NdisCallbackRoutine { + NdisFilterOidRequestComplete() { callbackType.getName().matches("FILTER_OID_REQUEST_COMPLETE") } +} + +/** A NDIS filter pause callback routine. */ +class NdisFilterPause extends NdisCallbackRoutine { + NdisFilterPause() { callbackType.getName().matches("FILTER_PAUSE") } +} + +/** A NDIS filter receive net buffer lists callback routine. */ +class NdisFilterReceiveNetBufferLists extends NdisCallbackRoutine { + NdisFilterReceiveNetBufferLists() { + callbackType.getName().matches("FILTER_RECEIVE_NET_BUFFER_LISTS") + } +} + +/** A NDIS filter restart callback routine. */ +class NdisFilterRestart extends NdisCallbackRoutine { + NdisFilterRestart() { callbackType.getName().matches("FILTER_RESTART") } +} + +/** A NDIS filter return net buffer lists callback routine. */ +class NdisFilterReturnNetBufferLists extends NdisCallbackRoutine { + NdisFilterReturnNetBufferLists() { + callbackType.getName().matches("FILTER_RETURN_NET_BUFFER_LISTS") + } +} + +/** A NDIS filter send net buffer lists callback routine. */ +class NdisFilterSendNetBufferLists extends NdisCallbackRoutine { + NdisFilterSendNetBufferLists() { callbackType.getName().matches("FILTER_SEND_NET_BUFFER_LISTS") } +} + +/** A NDIS filter send net buffer lists complete callback routine. */ +class NdisFilterSendNetBufferListsComplete extends NdisCallbackRoutine { + NdisFilterSendNetBufferListsComplete() { + callbackType.getName().matches("FILTER_SEND_NET_BUFFER_LISTS_COMPLETE") + } +} + +/** A NDIS filter set module options callback routine. */ +class NdisFilterSetModuleOptions extends NdisCallbackRoutine { + NdisFilterSetModuleOptions() { callbackType.getName().matches("FILTER_SET_MODULE_OPTIONS") } +} + +/** A NDIS filter set options callback routine. */ +class NdisFilterSetOptions extends NdisCallbackRoutine { + NdisFilterSetOptions() { callbackType.getName().matches("FILTER_SET_OPTIONS") } +} + +/** A NDIS filter status callback routine. */ +class NdisFilterStatus extends NdisCallbackRoutine { + NdisFilterStatus() { callbackType.getName().matches("FILTER_STATUS") } +} + +/** A NDIS miniport CO activate VC callback routine. */ +class NdisMiniportCoActivateVc extends NdisCallbackRoutine { + NdisMiniportCoActivateVc() { callbackType.getName().matches("MINIPORT_CO_ACTIVATE_VC") } +} + +/** A NDIS miniport CO create VC callback routine. */ +class NdisMiniportCoCreateVc extends NdisCallbackRoutine { + NdisMiniportCoCreateVc() { callbackType.getName().matches("MINIPORT_CO_CREATE_VC") } +} + +/** A NDIS miniport CO deactivate VC callback routine. */ +class NdisMiniportCoDeactivateVc extends NdisCallbackRoutine { + NdisMiniportCoDeactivateVc() { callbackType.getName().matches("MINIPORT_CO_DEACTIVATE_VC") } +} + +/** A NDIS miniport CO delete VC callback routine. */ +class NdisMiniportCoDeleteVc extends NdisCallbackRoutine { + NdisMiniportCoDeleteVc() { callbackType.getName().matches("MINIPORT_CO_DELETE_VC") } +} + +/** A NDIS miniport CO OID request callback routine. */ +class NdisMiniportCoOidRequest extends NdisCallbackRoutine { + NdisMiniportCoOidRequest() { callbackType.getName().matches("MINIPORT_CO_OID_REQUEST") } +} + +/** A NDIS miniport CO send net buffer lists callback routine. */ +class NdisMiniportCoSendNetBufferLists extends NdisCallbackRoutine { + NdisMiniportCoSendNetBufferLists() { + callbackType.getName().matches("MINIPORT_CO_SEND_NET_BUFFER_LISTS") + } +} + +/** A NDIS protocol bind adapter ex callback routine. */ +class NdisProtocolBindAdapterEx extends NdisCallbackRoutine { + NdisProtocolBindAdapterEx() { callbackType.getName().matches("PROTOCOL_BIND_ADAPTER_EX") } +} + +/** A NDIS protocol close adapter complete ex callback routine. */ +class NdisProtocolCloseAdapterCompleteEx extends NdisCallbackRoutine { + NdisProtocolCloseAdapterCompleteEx() { + callbackType.getName().matches("PROTOCOL_CLOSE_ADAPTER_COMPLETE_EX") + } +} + +/** A NDIS protocol direct OID request complete callback routine. */ +class NdisProtocolDirectOidRequestComplete extends NdisCallbackRoutine { + NdisProtocolDirectOidRequestComplete() { + callbackType.getName().matches("PROTOCOL_DIRECT_OID_REQUEST_COMPLETE") + } +} + +/** A NDIS protocol net PNP event callback routine. */ +class NdisProtocolNetPnpEvent extends NdisCallbackRoutine { + NdisProtocolNetPnpEvent() { callbackType.getName().matches("PROTOCOL_NET_PNP_EVENT") } +} + +/** A NDIS protocol OID request complete callback routine. */ +class NdisProtocolOidRequestComplete extends NdisCallbackRoutine { + NdisProtocolOidRequestComplete() { + callbackType.getName().matches("PROTOCOL_OID_REQUEST_COMPLETE") + } +} + +/** A NDIS protocol open adapter complete ex callback routine. */ +class NdisProtocolOpenAdapterCompleteEx extends NdisCallbackRoutine { + NdisProtocolOpenAdapterCompleteEx() { + callbackType.getName().matches("PROTOCOL_OPEN_ADAPTER_COMPLETE_EX") + } +} + +/** A NDIS protocol receive net buffer lists callback routine. */ +class NdisProtocolReceiveNetBufferLists extends NdisCallbackRoutine { + NdisProtocolReceiveNetBufferLists() { + callbackType.getName().matches("PROTOCOL_RECEIVE_NET_BUFFER_LISTS") + } +} + +/** A NDIS protocol send net buffer lists complete callback routine. */ +class NdisProtocolSendNetBufferListsComplete extends NdisCallbackRoutine { + NdisProtocolSendNetBufferListsComplete() { + callbackType.getName().matches("PROTOCOL_SEND_NET_BUFFER_LISTS_COMPLETE") + } +} + +/** A NDIS protocol set options callback routine. */ +class NdisProtocolSetOptions extends NdisCallbackRoutine { + NdisProtocolSetOptions() { callbackType.getName().matches("PROTOCOL_SET_OPTIONS") } +} + +/** A NDIS protocol status ex callback routine. */ +class NdisProtocolStatusEx extends NdisCallbackRoutine { + NdisProtocolStatusEx() { callbackType.getName().matches("PROTOCOL_STATUS_EX") } +} + +/** A NDIS protocol unbind adapter ex callback routine. */ +class NdisProtocolUnbindAdapterEx extends NdisCallbackRoutine { + NdisProtocolUnbindAdapterEx() { callbackType.getName().matches("PROTOCOL_UNBIND_ADAPTER_EX") } +} + +/** A NDIS protocol uninstall callback routine. */ +class NdisProtocolUninstall extends NdisCallbackRoutine { + NdisProtocolUninstall() { callbackType.getName().matches("PROTOCOL_UNINSTALL") } +} + +/** A NDIS protocol call manager add party complete callback routine. */ +class NdisProtocolClAddPartyComplete extends NdisCallbackRoutine { + NdisProtocolClAddPartyComplete() { + callbackType.getName().matches("PROTOCOL_CL_ADD_PARTY_COMPLETE") + } +} + +/** A NDIS protocol call manager call connected callback routine. */ +class NdisProtocolClCallConnected extends NdisCallbackRoutine { + NdisProtocolClCallConnected() { callbackType.getName().matches("PROTOCOL_CL_CALL_CONNECTED") } +} + +/** A NDIS protocol call manager close AF complete callback routine. */ +class NdisProtocolClCloseAfComplete extends NdisCallbackRoutine { + NdisProtocolClCloseAfComplete() { + callbackType.getName().matches("PROTOCOL_CL_CLOSE_AF_COMPLETE") + } +} + +/** A NDIS protocol call manager close call complete callback routine. */ +class NdisProtocolClCloseCallComplete extends NdisCallbackRoutine { + NdisProtocolClCloseCallComplete() { + callbackType.getName().matches("PROTOCOL_CL_CLOSE_CALL_COMPLETE") + } +} + +/** A NDIS protocol call manager deregister SAP complete callback routine. */ +class NdisProtocolClDeregisterSapComplete extends NdisCallbackRoutine { + NdisProtocolClDeregisterSapComplete() { + callbackType.getName().matches("PROTOCOL_CL_DEREGISTER_SAP_COMPLETE") + } +} + +/** A NDIS protocol call manager drop party complete callback routine. */ +class NdisProtocolClDropPartyComplete extends NdisCallbackRoutine { + NdisProtocolClDropPartyComplete() { + callbackType.getName().matches("PROTOCOL_CL_DROP_PARTY_COMPLETE") + } +} + +/** A NDIS protocol call manager incoming call callback routine. */ +class NdisProtocolClIncomingCall extends NdisCallbackRoutine { + NdisProtocolClIncomingCall() { callbackType.getName().matches("PROTOCOL_CL_INCOMING_CALL") } +} + +/** A NDIS protocol call manager incoming call QoS change callback routine. */ +class NdisProtocolClIncomingCallQosChange extends NdisCallbackRoutine { + NdisProtocolClIncomingCallQosChange() { + callbackType.getName().matches("PROTOCOL_CL_INCOMING_CALL_QOS_CHANGE") + } +} + +/** A NDIS protocol call manager incoming close call callback routine. */ +class NdisProtocolClIncomingCloseCall extends NdisCallbackRoutine { + NdisProtocolClIncomingCloseCall() { + callbackType.getName().matches("PROTOCOL_CL_INCOMING_CLOSE_CALL") + } +} + +/** A NDIS protocol call manager incoming drop party callback routine. */ +class NdisProtocolClIncomingDropParty extends NdisCallbackRoutine { + NdisProtocolClIncomingDropParty() { + callbackType.getName().matches("PROTOCOL_CL_INCOMING_DROP_PARTY") + } +} + +/** A NDIS protocol call manager make call complete callback routine. */ +class NdisProtocolClMakeCallComplete extends NdisCallbackRoutine { + NdisProtocolClMakeCallComplete() { + callbackType.getName().matches("PROTOCOL_CL_MAKE_CALL_COMPLETE") + } +} + +/** A NDIS protocol call manager modify call QoS complete callback routine. */ +class NdisProtocolClModifyCallQosComplete extends NdisCallbackRoutine { + NdisProtocolClModifyCallQosComplete() { + callbackType.getName().matches("PROTOCOL_CL_MODIFY_CALL_QOS_COMPLETE") + } +} + +/** A NDIS protocol call manager notify close AF callback routine. */ +class NdisProtocolClNotifyCloseAf extends NdisCallbackRoutine { + NdisProtocolClNotifyCloseAf() { callbackType.getName().matches("PROTOCOL_CL_NOTIFY_CLOSE_AF") } +} + +/** A NDIS protocol call manager open AF complete callback routine. */ +class NdisProtocolClOpenAfComplete extends NdisCallbackRoutine { + NdisProtocolClOpenAfComplete() { callbackType.getName().matches("PROTOCOL_CL_OPEN_AF_COMPLETE") } +} + +/** A NDIS protocol call manager open AF complete ex callback routine. */ +class NdisProtocolClOpenAfCompleteEx extends NdisCallbackRoutine { + NdisProtocolClOpenAfCompleteEx() { + callbackType.getName().matches("PROTOCOL_CL_OPEN_AF_COMPLETE_EX") + } +} + +/** A NDIS protocol call manager register SAP complete callback routine. */ +class NdisProtocolClRegisterSapComplete extends NdisCallbackRoutine { + NdisProtocolClRegisterSapComplete() { + callbackType.getName().matches("PROTOCOL_CL_REGISTER_SAP_COMPLETE") + } +} + +/** A NDIS protocol connection manager activate VC complete callback routine. */ +class NdisProtocolCmActivateVcComplete extends NdisCallbackRoutine { + NdisProtocolCmActivateVcComplete() { + callbackType.getName().matches("PROTOCOL_CM_ACTIVATE_VC_COMPLETE") + } +} + +/** A NDIS protocol connection manager add party callback routine. */ +class NdisProtocolCmAddParty extends NdisCallbackRoutine { + NdisProtocolCmAddParty() { callbackType.getName().matches("PROTOCOL_CM_ADD_PARTY") } +} + +/** A NDIS protocol connection manager close AF callback routine. */ +class NdisProtocolCmCloseAf extends NdisCallbackRoutine { + NdisProtocolCmCloseAf() { callbackType.getName().matches("PROTOCOL_CM_CLOSE_AF") } +} + +/** A NDIS protocol connection manager close call callback routine. */ +class NdisProtocolCmCloseCall extends NdisCallbackRoutine { + NdisProtocolCmCloseCall() { callbackType.getName().matches("PROTOCOL_CM_CLOSE_CALL") } +} + +/** A NDIS protocol connection manager deactivate VC complete callback routine. */ +class NdisProtocolCmDeactivateVcComplete extends NdisCallbackRoutine { + NdisProtocolCmDeactivateVcComplete() { + callbackType.getName().matches("PROTOCOL_CM_DEACTIVATE_VC_COMPLETE") + } +} + +/** A NDIS protocol connection manager deregister SAP callback routine. */ +class NdisProtocolCmDeregisterSap extends NdisCallbackRoutine { + NdisProtocolCmDeregisterSap() { callbackType.getName().matches("PROTOCOL_CM_DEREGISTER_SAP") } +} + +/** A NDIS protocol connection manager drop party callback routine. */ +class NdisProtocolCmDropParty extends NdisCallbackRoutine { + NdisProtocolCmDropParty() { callbackType.getName().matches("PROTOCOL_CM_DROP_PARTY") } +} + +/** A NDIS protocol connection manager incoming call complete callback routine. */ +class NdisProtocolCmIncomingCallComplete extends NdisCallbackRoutine { + NdisProtocolCmIncomingCallComplete() { + callbackType.getName().matches("PROTOCOL_CM_INCOMING_CALL_COMPLETE") + } +} + +/** A NDIS protocol connection manager make call callback routine. */ +class NdisProtocolCmMakeCall extends NdisCallbackRoutine { + NdisProtocolCmMakeCall() { callbackType.getName().matches("PROTOCOL_CM_MAKE_CALL") } +} + +/** A NDIS protocol connection manager modify QoS call callback routine. */ +class NdisProtocolCmModifyQosCall extends NdisCallbackRoutine { + NdisProtocolCmModifyQosCall() { callbackType.getName().matches("PROTOCOL_CM_MODIFY_QOS_CALL") } +} + +/** A NDIS protocol connection manager notify close AF complete callback routine. */ +class NdisProtocolCmNotifyCloseAfComplete extends NdisCallbackRoutine { + NdisProtocolCmNotifyCloseAfComplete() { + callbackType.getName().matches("PROTOCOL_CM_NOTIFY_CLOSE_AF_COMPLETE") + } +} + +/** A NDIS protocol connection manager open AF callback routine. */ +class NdisProtocolCmOpenAf extends NdisCallbackRoutine { + NdisProtocolCmOpenAf() { callbackType.getName().matches("PROTOCOL_CM_OPEN_AF") } +} + +/** A NDIS protocol connection manager register SAP callback routine. */ +class NdisProtocolCmRegSap extends NdisCallbackRoutine { + NdisProtocolCmRegSap() { callbackType.getName().matches("PROTOCOL_CM_REG_SAP") } +} + +/** A NDIS protocol CO AF register notify callback routine. */ +class NdisProtocolCoAfRegisterNotify extends NdisCallbackRoutine { + NdisProtocolCoAfRegisterNotify() { + callbackType.getName().matches("PROTCOL_CO_AF_REGISTER_NOTIFY") + } +} + +/** A NDIS protocol CO create VC callback routine. */ +class NdisProtocolCoCreateVc extends NdisCallbackRoutine { + NdisProtocolCoCreateVc() { callbackType.getName().matches("PROTOCOL_CO_CREATE_VC") } +} + +/** A NDIS protocol CO delete VC callback routine. */ +class NdisProtocolCoDeleteVc extends NdisCallbackRoutine { + NdisProtocolCoDeleteVc() { callbackType.getName().matches("PROTOCOL_CO_DELETE_VC") } +} + +/** A NDIS protocol CO OID request callback routine. */ +class NdisProtocolCoOidRequest extends NdisCallbackRoutine { + NdisProtocolCoOidRequest() { callbackType.getName().matches("PROTOCOL_CO_OID_REQUEST") } +} + +/** A NDIS protocol CO OID request complete callback routine. */ +class NdisProtocolCoOidRequestComplete extends NdisCallbackRoutine { + NdisProtocolCoOidRequestComplete() { + callbackType.getName().matches("PROTOCOL_CO_OID_REQUEST_COMPLETE") + } +} + +/** A NDIS protocol CO receive net buffer lists callback routine. */ +class NdisProtocolCoReceiveNetBufferLists extends NdisCallbackRoutine { + NdisProtocolCoReceiveNetBufferLists() { + callbackType.getName().matches("PROTOCOL_CO_RECEIVE_NET_BUFFER_LISTS") + } +} + +/** A NDIS protocol CO send net buffer lists complete callback routine. */ +class NdisProtocolCoSendNetBufferListsComplete extends NdisCallbackRoutine { + NdisProtocolCoSendNetBufferListsComplete() { + callbackType.getName().matches("PROTOCOL_CO_SEND_NET_BUFFER_LISTS_COMPLETE") + } +} + +/** A NDIS protocol CO status ex callback routine. */ +class NdisProtocolCoStatusEx extends NdisCallbackRoutine { + NdisProtocolCoStatusEx() { callbackType.getName().matches("PROTOCOL_CO_STATUS_EX") } +} diff --git a/src/drivers/storport/libraries/StorportDrivers.qll b/codeql/src/drivers/storport/libraries/StorportDrivers.qll similarity index 97% rename from src/drivers/storport/libraries/StorportDrivers.qll rename to codeql/src/drivers/storport/libraries/StorportDrivers.qll index 42e677b7..caa07589 100644 --- a/src/drivers/storport/libraries/StorportDrivers.qll +++ b/codeql/src/drivers/storport/libraries/StorportDrivers.qll @@ -1,251 +1,251 @@ -/** - * This QL library defines classes and predicates for analyzing NDIS drivers. - * It provides definitions for NDIS dispatch routines, callback routines, and role types. - * The library also includes a typedef for the standard NDIS callback routines. - */ - -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -import cpp -import drivers.libraries.SAL - - -/** Determines if a given assignment, recursively, has a Storport callback routine as the right-hand side. */ - -private predicate isCallbackRoutineAssignment(AssignExpr ae) { - exists(FunctionAccess fa | - ae.getRValue() = fa and - fa.getTarget() instanceof StorportCallbackRoutine - ) - or - ae.getRValue() instanceof AssignExpr and - isCallbackRoutineAssignment(ae.getRValue().(AssignExpr)) -} - -/** A typedef for Role Types */ -class StorportRoleTypeType extends TypedefType { - StorportRoleTypeType() { - ( - this.getName().matches("sp_DRIVER_INITIALIZE") or - this.getName().matches("HW_INITIALIZE") or - this.getName().matches("HW_BUILDIO") or - this.getName().matches("HW_STARTIO") or - this.getName().matches("HW_INTERRUPT") or - this.getName().matches("HW_TIMER") or - this.getName().matches("HW_FIND_ADAPTER") or - this.getName().matches("HW_RESET_BUS") or - this.getName().matches("HW_ADAPTER_CONTROL") or - this.getName().matches("HW_PASSIVE_INITIALIZE_ROUTINE") or - this.getName().matches("HW_DPC_ROUTINE") or - this.getName().matches("HW_FREE_ADAPTER_RESOURCES") or - this.getName().matches("HW_PROCESS_SERVICE_REQUEST") or - this.getName().matches("HW_COMPLETE_SERVICE_IRP") or - this.getName().matches("HW_INITIALIZE_TRACING") or - this.getName().matches("HW_CLEANUP_TRACING") or - this.getName().matches("VIRTUAL_HW_FIND_ADAPTER") or - this.getName().matches("HW_MESSAGE_SIGNALED_INTERRUPT_ROUTINE") - ) - } -} - -/** A typedef for the standard Storport callback routines. Aka Role Types */ - -class StorportCallbackRoutineTypedef extends StorportRoleTypeType { - StorportCallbackRoutineTypedef() { this.getFile().getBaseName().matches("storport.h") } -} - -/** - * Represents a function implementing a Storport callback routine. - - * Defines a function to be a callback routine iff it has a typedef - * in its definition which matches the Storport callback typedefs, and it - - * is in a Storport driver (includes wdm.h.) - - */ -class StorportCallbackRoutine extends Function { - /** The callback routine type, i.e. DRIVER_UNLOAD. */ - StorportCallbackRoutineTypedef callbackType; - - StorportCallbackRoutine() { - exists(FunctionDeclarationEntry fde | - fde.getFunction() = this and - fde.getTypedefType() = callbackType - ) - } -} - -/** - * Similar to StorportCallbackRoutine, but specifically for Role Types - */ -abstract class StorportRoleTypeFunction extends Function { - StorportCallbackRoutineTypedef roleType; - - StorportRoleTypeFunction() { - exists(FunctionDeclarationEntry fde | - fde.getFunction() = this and - fde.getTypedefType() = roleType - ) - } - - string getRoleTypeString() { result = roleType.getName() } - - StorportRoleTypeType getRoleTypeType() { result = roleType } -} - -predicate hasRoleType(Function f) { f instanceof StorportRoleTypeFunction } - -class StorportDriverObjectFunctionAccess extends FunctionAccess { - StorportRoleTypeType rttExpected; - - StorportDriverObjectFunctionAccess() { - exists(VariableAccess driverObjectAccess, AssignExpr driverObjectAssign | - driverObjectAccess.getTarget().getType().getName().matches("PDRIVER_OBJECT") and - this = driverObjectAssign.getRValue() and - rttExpected = driverObjectAssign.getLValue().getUnderlyingType().(PointerType).getBaseType() - ) - } - - StorportRoleTypeType getExpectedRoleTypeType() { result = rttExpected } -} - -class StorportDriverEntryPoint extends FunctionAccess { - StorportDriverEntryPoint() { this instanceof StorportDriverObjectFunctionAccess } -} - -// declared functions that are used as if they have a role type, wether or not they do -class StorportImplicitRoleTypeFunction extends Function { - StorportRoleTypeType rttExpected; - FunctionAccess funcUse; - - StorportImplicitRoleTypeFunction() { - exists(FunctionCall fc, int n | fc.getArgument(n) instanceof FunctionAccess | - this = fc.getArgument(n).(FunctionAccess).getTarget() and - fc.getTarget().getParameter(n).getUnderlyingType().(PointerType).getBaseType() instanceof - StorportRoleTypeType and - rttExpected = fc.getTarget().getParameter(n).getUnderlyingType().(PointerType).getBaseType() and - fc.getTarget().getParameter(n).getUnderlyingType().(PointerType).getBaseType() instanceof - StorportRoleTypeType and - funcUse = fc.getArgument(n) - ) - or - exists(StorportDriverObjectFunctionAccess funcAssign | - funcAssign.getTarget() = this and - rttExpected = funcAssign.getExpectedRoleTypeType() and - funcUse = funcAssign - ) - } - - string getExpectedRoleTypeString() { result = rttExpected.toString() } - - StorportRoleTypeType getExpectedRoleTypeType() { result = rttExpected } - - string getActualRoleTypeString() { - if this instanceof StorportRoleTypeFunction - then result = this.(StorportRoleTypeFunction).getRoleTypeType().toString() - else result = "" - } - - FunctionAccess getFunctionUse() { result = funcUse } -} - -/** A Storport protocol Driver Initialize callback routine. */ -class StorportDriverInitialize extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportDriverInitialize() { callbackType.getName().matches("sp_DRIVER_INITIALIZE") } -} - -/** A Storport protocol Hardware Initialize callback routine. */ -class StorportHwInitialize extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwInitialize() { callbackType.getName().matches("HW_INITIALIZE") } -} - -/** A Storport protocol Hardware Build IO callback routine. */ -class StorportHwBuildIo extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwBuildIo() { callbackType.getName().matches("HW_BUILDIO") } -} - -/** A Storport protocol Hardware Start IO callback routine. */ -class StorportHwStartIo extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwStartIo() { callbackType.getName().matches("HW_STARTIO") } -} - -/** A Storport protocol Hardware Interrupt callback routine. */ -class StorportHwInterrupt extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwInterrupt() { callbackType.getName().matches("HW_INTERRUPT") } -} - -/** A Storport protocol Hardware Timer callback routine. */ -class StorportHwTimer extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwTimer() { callbackType.getName().matches("HW_TIMER") } -} - -/** A Storport protocol Hardware Find Adapter callback routine. */ -class StorportHwFindAdapter extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwFindAdapter() { callbackType.getName().matches("HW_FIND_ADAPTER") } -} - -/** A Storport protocol Hardware Reset Bus callback routine. */ -class StorportHwResetBus extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwResetBus() { callbackType.getName().matches("HW_RESET_BUS") } -} - -/** A Storport protocol Hardware Adapter Control callback routine. */ -class StorportHwAdapterControl extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwAdapterControl() { callbackType.getName().matches("HW_ADAPTER_CONTROL") } -} - -/** A Storport protocol Hardware Passive Initialize callback routine. */ -class StorportHwPassiveInitializeRoutine extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwPassiveInitializeRoutine() { - callbackType.getName().matches("HW_PASSIVE_INITIALIZE_ROUTINE") - } -} - -/** A Storport protocol Hardware DPC callback routine. */ -class StorportHwDpcRoutine extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwDpcRoutine() { callbackType.getName().matches("HW_DPC_ROUTINE") } -} - -/** A Storport protocol Hardware Free Adapter Resources callback routine. */ -class StorportHwFreeAdapterResources extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwFreeAdapterResources() { callbackType.getName().matches("HW_FREE_ADAPTER_RESOURCES") } -} - -/** A Storport protocol Hardware Process Service Request callback routine. */ -class StorportHwProcessServiceRequest extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwProcessServiceRequest() { callbackType.getName().matches("HW_PROCESS_SERVICE_REQUEST") } -} - -/** A Storport protocol Hardware Complete Service IRP callback routine. */ -class StorportHwCompleteServiceIrp extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwCompleteServiceIrp() { callbackType.getName().matches("HW_COMPLETE_SERVICE_IRP") } -} - -/** A Storport protocol Hardware Initialize Tracing callback routine. */ -class StorportHwInitializeTracing extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwInitializeTracing() { callbackType.getName().matches("HW_INITIALIZE_TRACING") } -} - -/** A Storport protocol Hardware Cleanup Tracing callback routine. */ -class StorportHwCleanupTracing extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportHwCleanupTracing() { callbackType.getName().matches("HW_CLEANUP_TRACING") } -} - -/** A Storport protocol Virtual Hardware Find Adapter callback routine. */ -class StorportVirtualHwFindAdapter extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportVirtualHwFindAdapter() { callbackType.getName().matches("VIRTUAL_HW_FIND_ADAPTER") } -} - -/** A Storport protocol Hardware Message Signaled Interrupt callback routine. */ -class StorportHwMessageSignaledInterruptRoutine extends StorportCallbackRoutine, - StorportRoleTypeFunction -{ - StorportHwMessageSignaledInterruptRoutine() { - callbackType.getName().matches("HW_MESSAGE_SIGNALED_INTERRUPT_ROUTINE") - } -} - -/** A Storport protocol Driver Unload callback routine. */ -class StorportDriverUnload extends StorportCallbackRoutine, StorportRoleTypeFunction { - StorportDriverUnload() { callbackType.getName().matches("DRIVER_UNLOAD") } -} +/** + * This QL library defines classes and predicates for analyzing NDIS drivers. + * It provides definitions for NDIS dispatch routines, callback routines, and role types. + * The library also includes a typedef for the standard NDIS callback routines. + */ + +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +import cpp +import drivers.libraries.SAL + + +/** Determines if a given assignment, recursively, has a Storport callback routine as the right-hand side. */ + +private predicate isCallbackRoutineAssignment(AssignExpr ae) { + exists(FunctionAccess fa | + ae.getRValue() = fa and + fa.getTarget() instanceof StorportCallbackRoutine + ) + or + ae.getRValue() instanceof AssignExpr and + isCallbackRoutineAssignment(ae.getRValue().(AssignExpr)) +} + +/** A typedef for Role Types */ +class StorportRoleTypeType extends TypedefType { + StorportRoleTypeType() { + ( + this.getName().matches("sp_DRIVER_INITIALIZE") or + this.getName().matches("HW_INITIALIZE") or + this.getName().matches("HW_BUILDIO") or + this.getName().matches("HW_STARTIO") or + this.getName().matches("HW_INTERRUPT") or + this.getName().matches("HW_TIMER") or + this.getName().matches("HW_FIND_ADAPTER") or + this.getName().matches("HW_RESET_BUS") or + this.getName().matches("HW_ADAPTER_CONTROL") or + this.getName().matches("HW_PASSIVE_INITIALIZE_ROUTINE") or + this.getName().matches("HW_DPC_ROUTINE") or + this.getName().matches("HW_FREE_ADAPTER_RESOURCES") or + this.getName().matches("HW_PROCESS_SERVICE_REQUEST") or + this.getName().matches("HW_COMPLETE_SERVICE_IRP") or + this.getName().matches("HW_INITIALIZE_TRACING") or + this.getName().matches("HW_CLEANUP_TRACING") or + this.getName().matches("VIRTUAL_HW_FIND_ADAPTER") or + this.getName().matches("HW_MESSAGE_SIGNALED_INTERRUPT_ROUTINE") + ) + } +} + +/** A typedef for the standard Storport callback routines. Aka Role Types */ + +class StorportCallbackRoutineTypedef extends StorportRoleTypeType { + StorportCallbackRoutineTypedef() { this.getFile().getBaseName().matches("storport.h") } +} + +/** + * Represents a function implementing a Storport callback routine. + + * Defines a function to be a callback routine iff it has a typedef + * in its definition which matches the Storport callback typedefs, and it + + * is in a Storport driver (includes wdm.h.) + + */ +class StorportCallbackRoutine extends Function { + /** The callback routine type, i.e. DRIVER_UNLOAD. */ + StorportCallbackRoutineTypedef callbackType; + + StorportCallbackRoutine() { + exists(FunctionDeclarationEntry fde | + fde.getFunction() = this and + fde.getTypedefType() = callbackType + ) + } +} + +/** + * Similar to StorportCallbackRoutine, but specifically for Role Types + */ +abstract class StorportRoleTypeFunction extends Function { + StorportCallbackRoutineTypedef roleType; + + StorportRoleTypeFunction() { + exists(FunctionDeclarationEntry fde | + fde.getFunction() = this and + fde.getTypedefType() = roleType + ) + } + + string getRoleTypeString() { result = roleType.getName() } + + StorportRoleTypeType getRoleTypeType() { result = roleType } +} + +predicate hasRoleType(Function f) { f instanceof StorportRoleTypeFunction } + +class StorportDriverObjectFunctionAccess extends FunctionAccess { + StorportRoleTypeType rttExpected; + + StorportDriverObjectFunctionAccess() { + exists(VariableAccess driverObjectAccess, AssignExpr driverObjectAssign | + driverObjectAccess.getTarget().getType().getName().matches("PDRIVER_OBJECT") and + this = driverObjectAssign.getRValue() and + rttExpected = driverObjectAssign.getLValue().getUnderlyingType().(PointerType).getBaseType() + ) + } + + StorportRoleTypeType getExpectedRoleTypeType() { result = rttExpected } +} + +class StorportDriverEntryPoint extends FunctionAccess { + StorportDriverEntryPoint() { this instanceof StorportDriverObjectFunctionAccess } +} + +// declared functions that are used as if they have a role type, wether or not they do +class StorportImplicitRoleTypeFunction extends Function { + StorportRoleTypeType rttExpected; + FunctionAccess funcUse; + + StorportImplicitRoleTypeFunction() { + exists(FunctionCall fc, int n | fc.getArgument(n) instanceof FunctionAccess | + this = fc.getArgument(n).(FunctionAccess).getTarget() and + fc.getTarget().getParameter(n).getUnderlyingType().(PointerType).getBaseType() instanceof + StorportRoleTypeType and + rttExpected = fc.getTarget().getParameter(n).getUnderlyingType().(PointerType).getBaseType() and + fc.getTarget().getParameter(n).getUnderlyingType().(PointerType).getBaseType() instanceof + StorportRoleTypeType and + funcUse = fc.getArgument(n) + ) + or + exists(StorportDriverObjectFunctionAccess funcAssign | + funcAssign.getTarget() = this and + rttExpected = funcAssign.getExpectedRoleTypeType() and + funcUse = funcAssign + ) + } + + string getExpectedRoleTypeString() { result = rttExpected.toString() } + + StorportRoleTypeType getExpectedRoleTypeType() { result = rttExpected } + + string getActualRoleTypeString() { + if this instanceof StorportRoleTypeFunction + then result = this.(StorportRoleTypeFunction).getRoleTypeType().toString() + else result = "" + } + + FunctionAccess getFunctionUse() { result = funcUse } +} + +/** A Storport protocol Driver Initialize callback routine. */ +class StorportDriverInitialize extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportDriverInitialize() { callbackType.getName().matches("sp_DRIVER_INITIALIZE") } +} + +/** A Storport protocol Hardware Initialize callback routine. */ +class StorportHwInitialize extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwInitialize() { callbackType.getName().matches("HW_INITIALIZE") } +} + +/** A Storport protocol Hardware Build IO callback routine. */ +class StorportHwBuildIo extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwBuildIo() { callbackType.getName().matches("HW_BUILDIO") } +} + +/** A Storport protocol Hardware Start IO callback routine. */ +class StorportHwStartIo extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwStartIo() { callbackType.getName().matches("HW_STARTIO") } +} + +/** A Storport protocol Hardware Interrupt callback routine. */ +class StorportHwInterrupt extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwInterrupt() { callbackType.getName().matches("HW_INTERRUPT") } +} + +/** A Storport protocol Hardware Timer callback routine. */ +class StorportHwTimer extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwTimer() { callbackType.getName().matches("HW_TIMER") } +} + +/** A Storport protocol Hardware Find Adapter callback routine. */ +class StorportHwFindAdapter extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwFindAdapter() { callbackType.getName().matches("HW_FIND_ADAPTER") } +} + +/** A Storport protocol Hardware Reset Bus callback routine. */ +class StorportHwResetBus extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwResetBus() { callbackType.getName().matches("HW_RESET_BUS") } +} + +/** A Storport protocol Hardware Adapter Control callback routine. */ +class StorportHwAdapterControl extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwAdapterControl() { callbackType.getName().matches("HW_ADAPTER_CONTROL") } +} + +/** A Storport protocol Hardware Passive Initialize callback routine. */ +class StorportHwPassiveInitializeRoutine extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwPassiveInitializeRoutine() { + callbackType.getName().matches("HW_PASSIVE_INITIALIZE_ROUTINE") + } +} + +/** A Storport protocol Hardware DPC callback routine. */ +class StorportHwDpcRoutine extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwDpcRoutine() { callbackType.getName().matches("HW_DPC_ROUTINE") } +} + +/** A Storport protocol Hardware Free Adapter Resources callback routine. */ +class StorportHwFreeAdapterResources extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwFreeAdapterResources() { callbackType.getName().matches("HW_FREE_ADAPTER_RESOURCES") } +} + +/** A Storport protocol Hardware Process Service Request callback routine. */ +class StorportHwProcessServiceRequest extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwProcessServiceRequest() { callbackType.getName().matches("HW_PROCESS_SERVICE_REQUEST") } +} + +/** A Storport protocol Hardware Complete Service IRP callback routine. */ +class StorportHwCompleteServiceIrp extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwCompleteServiceIrp() { callbackType.getName().matches("HW_COMPLETE_SERVICE_IRP") } +} + +/** A Storport protocol Hardware Initialize Tracing callback routine. */ +class StorportHwInitializeTracing extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwInitializeTracing() { callbackType.getName().matches("HW_INITIALIZE_TRACING") } +} + +/** A Storport protocol Hardware Cleanup Tracing callback routine. */ +class StorportHwCleanupTracing extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportHwCleanupTracing() { callbackType.getName().matches("HW_CLEANUP_TRACING") } +} + +/** A Storport protocol Virtual Hardware Find Adapter callback routine. */ +class StorportVirtualHwFindAdapter extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportVirtualHwFindAdapter() { callbackType.getName().matches("VIRTUAL_HW_FIND_ADAPTER") } +} + +/** A Storport protocol Hardware Message Signaled Interrupt callback routine. */ +class StorportHwMessageSignaledInterruptRoutine extends StorportCallbackRoutine, + StorportRoleTypeFunction +{ + StorportHwMessageSignaledInterruptRoutine() { + callbackType.getName().matches("HW_MESSAGE_SIGNALED_INTERRUPT_ROUTINE") + } +} + +/** A Storport protocol Driver Unload callback routine. */ +class StorportDriverUnload extends StorportCallbackRoutine, StorportRoleTypeFunction { + StorportDriverUnload() { callbackType.getName().matches("DRIVER_UNLOAD") } +} diff --git a/src/drivers/test/README.md b/codeql/src/drivers/test/README.md similarity index 100% rename from src/drivers/test/README.md rename to codeql/src/drivers/test/README.md diff --git a/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.sln b/codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.sln similarity index 100% rename from src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.sln rename to codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.sln diff --git a/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj b/codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj similarity index 100% rename from src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj rename to codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj diff --git a/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj.filters b/codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj.filters similarity index 100% rename from src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj.filters rename to codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj.filters diff --git a/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj.user b/codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj.user similarity index 100% rename from src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj.user rename to codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/ApplicationForDriversTestTemplate.vcxproj.user diff --git a/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/Source.cpp b/codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/Source.cpp similarity index 100% rename from src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/Source.cpp rename to codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/Source.cpp diff --git a/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/driver_snippet.c b/codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/driver_snippet.c similarity index 100% rename from src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/driver_snippet.c rename to codeql/src/drivers/test/TestTemplates/ApplicationForDriversTestTemplate/driver_snippet.c diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.inf b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.inf similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.inf rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.inf diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.sln b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.sln similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.sln rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.sln diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj.filters b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj.filters similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj.filters rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/CppKMDFTestTemplate.vcxproj.filters diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Device.c b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Device.c similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/Device.c rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Device.c diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Device.h b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Device.h similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/Device.h rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Device.h diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Driver.cpp b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Driver.cpp similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/Driver.cpp rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Driver.cpp diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Driver.h b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Driver.h similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/Driver.h rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Driver.h diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Public.h b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Public.h similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/Public.h rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Public.h diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Queue.c b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Queue.c similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/Queue.c rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Queue.c diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Queue.h b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Queue.h similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/Queue.h rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Queue.h diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/ReadMe.txt b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/ReadMe.txt similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/ReadMe.txt rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/ReadMe.txt diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Trace.h b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Trace.h similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/Trace.h rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/Trace.h diff --git a/src/drivers/test/TestTemplates/CppKMDFTestTemplate/driver/driver_snippet.cpp b/codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/driver/driver_snippet.cpp similarity index 100% rename from src/drivers/test/TestTemplates/CppKMDFTestTemplate/driver/driver_snippet.cpp rename to codeql/src/drivers/test/TestTemplates/CppKMDFTestTemplate/driver/driver_snippet.cpp diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/Device.c b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Device.c similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/Device.c rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Device.c diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/Device.h b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Device.h similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/Device.h rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Device.h diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/Driver.c b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Driver.c similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/Driver.c rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Driver.c diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/Driver.h b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Driver.h similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/Driver.h rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Driver.h diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.inf b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.inf similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.inf rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.inf diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.sln b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.sln similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.sln rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.sln diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj.filters b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj.filters similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj.filters rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/KMDFTestTemplate.vcxproj.filters diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/Public.h b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Public.h similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/Public.h rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Public.h diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/Queue.c b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Queue.c similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/Queue.c rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Queue.c diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/Queue.h b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Queue.h similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/Queue.h rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Queue.h diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/ReadMe.txt b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/ReadMe.txt similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/ReadMe.txt rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/ReadMe.txt diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/Trace.h b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Trace.h similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/Trace.h rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/Trace.h diff --git a/src/drivers/test/TestTemplates/KMDFTestTemplate/driver/driver_snippet.c b/codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/driver/driver_snippet.c similarity index 100% rename from src/drivers/test/TestTemplates/KMDFTestTemplate/driver/driver_snippet.c rename to codeql/src/drivers/test/TestTemplates/KMDFTestTemplate/driver/driver_snippet.c diff --git a/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.qhelp b/codeql/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.qhelp similarity index 100% rename from src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.qhelp rename to codeql/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.qhelp diff --git a/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.ql b/codeql/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.ql similarity index 100% rename from src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.ql rename to codeql/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.ql diff --git a/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.sarif b/codeql/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.sarif similarity index 100% rename from src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.sarif rename to codeql/src/drivers/test/TestTemplates/QueryTemplate/QueryTemplate.sarif diff --git a/src/drivers/test/TestTemplates/QueryTemplate/driver_snippet.c b/codeql/src/drivers/test/TestTemplates/QueryTemplate/driver_snippet.c similarity index 100% rename from src/drivers/test/TestTemplates/QueryTemplate/driver_snippet.c rename to codeql/src/drivers/test/TestTemplates/QueryTemplate/driver_snippet.c diff --git a/src/drivers/test/TestTemplates/WDMTestTemplate/README.md b/codeql/src/drivers/test/TestTemplates/WDMTestTemplate/README.md similarity index 100% rename from src/drivers/test/TestTemplates/WDMTestTemplate/README.md rename to codeql/src/drivers/test/TestTemplates/WDMTestTemplate/README.md diff --git a/src/drivers/test/TestTemplates/WDMTestTemplate/WDMTestTemplate.sln b/codeql/src/drivers/test/TestTemplates/WDMTestTemplate/WDMTestTemplate.sln similarity index 100% rename from src/drivers/test/TestTemplates/WDMTestTemplate/WDMTestTemplate.sln rename to codeql/src/drivers/test/TestTemplates/WDMTestTemplate/WDMTestTemplate.sln diff --git a/src/drivers/test/TestTemplates/WDMTestTemplate/driver/driver_snippet.c b/codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/driver_snippet.c similarity index 100% rename from src/drivers/test/TestTemplates/WDMTestTemplate/driver/driver_snippet.c rename to codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/driver_snippet.c diff --git a/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.c b/codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.c similarity index 100% rename from src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.c rename to codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.c diff --git a/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.h b/codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.h similarity index 100% rename from src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.h rename to codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.h diff --git a/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj b/codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj similarity index 100% rename from src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj rename to codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj diff --git a/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj.Filters b/codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj.Filters similarity index 100% rename from src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj.Filters rename to codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj.Filters diff --git a/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj.user b/codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj.user similarity index 100% rename from src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj.user rename to codeql/src/drivers/test/TestTemplates/WDMTestTemplate/driver/fail_driver1.vcxproj.user diff --git a/src/drivers/test/build_create_analyze_test.py b/codeql/src/drivers/test/build_create_analyze_test.py similarity index 100% rename from src/drivers/test/build_create_analyze_test.py rename to codeql/src/drivers/test/build_create_analyze_test.py diff --git a/src/drivers/test/compare_results.py b/codeql/src/drivers/test/compare_results.py similarity index 100% rename from src/drivers/test/compare_results.py rename to codeql/src/drivers/test/compare_results.py diff --git a/src/drivers/test/diff/AnnotationSyntax.sarif b/codeql/src/drivers/test/diff/AnnotationSyntax.sarif similarity index 100% rename from src/drivers/test/diff/AnnotationSyntax.sarif rename to codeql/src/drivers/test/diff/AnnotationSyntax.sarif diff --git a/src/drivers/test/diff/CurrentFunctionTypeNotCorrect.sarif b/codeql/src/drivers/test/diff/CurrentFunctionTypeNotCorrect.sarif similarity index 100% rename from src/drivers/test/diff/CurrentFunctionTypeNotCorrect.sarif rename to codeql/src/drivers/test/diff/CurrentFunctionTypeNotCorrect.sarif diff --git a/src/drivers/test/diff/DefaultPoolTag.sarif b/codeql/src/drivers/test/diff/DefaultPoolTag.sarif similarity index 100% rename from src/drivers/test/diff/DefaultPoolTag.sarif rename to codeql/src/drivers/test/diff/DefaultPoolTag.sarif diff --git a/src/drivers/test/diff/DefaultPoolTagExtended.sarif b/codeql/src/drivers/test/diff/DefaultPoolTagExtended.sarif similarity index 100% rename from src/drivers/test/diff/DefaultPoolTagExtended.sarif rename to codeql/src/drivers/test/diff/DefaultPoolTagExtended.sarif diff --git a/src/drivers/test/diff/DeviceInitApi.sarif b/codeql/src/drivers/test/diff/DeviceInitApi.sarif similarity index 100% rename from src/drivers/test/diff/DeviceInitApi.sarif rename to codeql/src/drivers/test/diff/DeviceInitApi.sarif diff --git a/src/drivers/test/diff/DriverEntrySaveBuffer.sarif b/codeql/src/drivers/test/diff/DriverEntrySaveBuffer.sarif similarity index 100% rename from src/drivers/test/diff/DriverEntrySaveBuffer.sarif rename to codeql/src/drivers/test/diff/DriverEntrySaveBuffer.sarif diff --git a/src/drivers/test/diff/DriverIsolationRtlViolation.sarif b/codeql/src/drivers/test/diff/DriverIsolationRtlViolation.sarif similarity index 100% rename from src/drivers/test/diff/DriverIsolationRtlViolation.sarif rename to codeql/src/drivers/test/diff/DriverIsolationRtlViolation.sarif diff --git a/src/drivers/test/diff/DriverIsolationZwViolation1.sarif b/codeql/src/drivers/test/diff/DriverIsolationZwViolation1.sarif similarity index 100% rename from src/drivers/test/diff/DriverIsolationZwViolation1.sarif rename to codeql/src/drivers/test/diff/DriverIsolationZwViolation1.sarif diff --git a/src/drivers/test/diff/DriverIsolationZwViolation2.sarif b/codeql/src/drivers/test/diff/DriverIsolationZwViolation2.sarif similarity index 100% rename from src/drivers/test/diff/DriverIsolationZwViolation2.sarif rename to codeql/src/drivers/test/diff/DriverIsolationZwViolation2.sarif diff --git a/src/drivers/test/diff/ExtendedDeprecatedApis.sarif b/codeql/src/drivers/test/diff/ExaminedValue.sarif similarity index 100% rename from src/drivers/test/diff/ExtendedDeprecatedApis.sarif rename to codeql/src/drivers/test/diff/ExaminedValue.sarif diff --git a/src/drivers/test/diff/FloatHardwareStateProtection.sarif b/codeql/src/drivers/test/diff/ExtendedDeprecatedApis.sarif similarity index 100% rename from src/drivers/test/diff/FloatHardwareStateProtection.sarif rename to codeql/src/drivers/test/diff/ExtendedDeprecatedApis.sarif diff --git a/src/drivers/test/diff/FloatSafeExit.sarif b/codeql/src/drivers/test/diff/FloatHardwareStateProtection.sarif similarity index 100% rename from src/drivers/test/diff/FloatSafeExit.sarif rename to codeql/src/drivers/test/diff/FloatHardwareStateProtection.sarif diff --git a/src/drivers/test/diff/FloatUnsafeExit.sarif b/codeql/src/drivers/test/diff/FloatSafeExit.sarif similarity index 100% rename from src/drivers/test/diff/FloatUnsafeExit.sarif rename to codeql/src/drivers/test/diff/FloatSafeExit.sarif diff --git a/src/drivers/test/diff/IRPStackEntryCopy.sarif b/codeql/src/drivers/test/diff/FloatUnsafeExit.sarif similarity index 100% rename from src/drivers/test/diff/IRPStackEntryCopy.sarif rename to codeql/src/drivers/test/diff/FloatUnsafeExit.sarif diff --git a/src/drivers/test/diff/ImportantFunctionCallOptimizedOut.sarif b/codeql/src/drivers/test/diff/IRPStackEntryCopy.sarif similarity index 100% rename from src/drivers/test/diff/ImportantFunctionCallOptimizedOut.sarif rename to codeql/src/drivers/test/diff/IRPStackEntryCopy.sarif diff --git a/src/drivers/test/diff/ImproperNotOperatorOnZero.sarif b/codeql/src/drivers/test/diff/IllegalFieldAccess.sarif similarity index 100% rename from src/drivers/test/diff/ImproperNotOperatorOnZero.sarif rename to codeql/src/drivers/test/diff/IllegalFieldAccess.sarif diff --git a/src/drivers/test/diff/InitNotCleared.sarif b/codeql/src/drivers/test/diff/IllegalFieldAccess2.sarif similarity index 100% rename from src/drivers/test/diff/InitNotCleared.sarif rename to codeql/src/drivers/test/diff/IllegalFieldAccess2.sarif diff --git a/src/drivers/test/diff/InvalidFunctionClassTypedef.sarif b/codeql/src/drivers/test/diff/IllegalFieldWrite.sarif similarity index 100% rename from src/drivers/test/diff/InvalidFunctionClassTypedef.sarif rename to codeql/src/drivers/test/diff/IllegalFieldWrite.sarif diff --git a/src/drivers/test/diff/InvalidFunctionPointerAnnotation.sarif b/codeql/src/drivers/test/diff/ImportantFunctionCallOptimizedOut.sarif similarity index 100% rename from src/drivers/test/diff/InvalidFunctionPointerAnnotation.sarif rename to codeql/src/drivers/test/diff/ImportantFunctionCallOptimizedOut.sarif diff --git a/src/drivers/test/diff/IoInitializeTimerCall.sarif b/codeql/src/drivers/test/diff/ImproperNotOperatorOnZero.sarif similarity index 100% rename from src/drivers/test/diff/IoInitializeTimerCall.sarif rename to codeql/src/drivers/test/diff/ImproperNotOperatorOnZero.sarif diff --git a/src/drivers/test/diff/IrqTooHigh.sarif b/codeql/src/drivers/test/diff/InitNotCleared.sarif similarity index 100% rename from src/drivers/test/diff/IrqTooHigh.sarif rename to codeql/src/drivers/test/diff/InitNotCleared.sarif diff --git a/src/drivers/test/diff/IrqTooLow.sarif b/codeql/src/drivers/test/diff/InvalidFunctionClassTypedef.sarif similarity index 100% rename from src/drivers/test/diff/IrqTooLow.sarif rename to codeql/src/drivers/test/diff/InvalidFunctionClassTypedef.sarif diff --git a/src/drivers/test/diff/IrqlAnnotationIssue.sarif b/codeql/src/drivers/test/diff/InvalidFunctionPointerAnnotation.sarif similarity index 100% rename from src/drivers/test/diff/IrqlAnnotationIssue.sarif rename to codeql/src/drivers/test/diff/InvalidFunctionPointerAnnotation.sarif diff --git a/src/drivers/test/diff/IrqlCancelRoutine.sarif b/codeql/src/drivers/test/diff/IoInitializeTimerCall.sarif similarity index 100% rename from src/drivers/test/diff/IrqlCancelRoutine.sarif rename to codeql/src/drivers/test/diff/IoInitializeTimerCall.sarif diff --git a/src/drivers/test/diff/IrqlFloatStateMismatch.sarif b/codeql/src/drivers/test/diff/IrqTooHigh.sarif similarity index 100% rename from src/drivers/test/diff/IrqlFloatStateMismatch.sarif rename to codeql/src/drivers/test/diff/IrqTooHigh.sarif diff --git a/src/drivers/test/diff/IrqlFunctionNotAnnotated.sarif b/codeql/src/drivers/test/diff/IrqTooLow.sarif similarity index 100% rename from src/drivers/test/diff/IrqlFunctionNotAnnotated.sarif rename to codeql/src/drivers/test/diff/IrqTooLow.sarif diff --git a/src/drivers/test/diff/IrqlIllegalValue.sarif b/codeql/src/drivers/test/diff/IrqlAnnotationIssue.sarif similarity index 100% rename from src/drivers/test/diff/IrqlIllegalValue.sarif rename to codeql/src/drivers/test/diff/IrqlAnnotationIssue.sarif diff --git a/src/drivers/test/diff/IrqlInconsistentWithRequired.sarif b/codeql/src/drivers/test/diff/IrqlCancelRoutine.sarif similarity index 100% rename from src/drivers/test/diff/IrqlInconsistentWithRequired.sarif rename to codeql/src/drivers/test/diff/IrqlCancelRoutine.sarif diff --git a/src/drivers/test/diff/IrqlLoweredImproperly.sarif b/codeql/src/drivers/test/diff/IrqlFloatStateMismatch.sarif similarity index 100% rename from src/drivers/test/diff/IrqlLoweredImproperly.sarif rename to codeql/src/drivers/test/diff/IrqlFloatStateMismatch.sarif diff --git a/src/drivers/test/diff/KeSetEventIrql.sarif b/codeql/src/drivers/test/diff/IrqlFunctionNotAnnotated.sarif similarity index 100% rename from src/drivers/test/diff/KeSetEventIrql.sarif rename to codeql/src/drivers/test/diff/IrqlFunctionNotAnnotated.sarif diff --git a/src/drivers/test/diff/KeSetEventPageable.sarif b/codeql/src/drivers/test/diff/IrqlIllegalValue.sarif similarity index 100% rename from src/drivers/test/diff/KeSetEventPageable.sarif rename to codeql/src/drivers/test/diff/IrqlIllegalValue.sarif diff --git a/src/drivers/test/diff/MultipleFunctionClassAnnotations.sarif b/codeql/src/drivers/test/diff/IrqlInconsistentWithRequired.sarif similarity index 100% rename from src/drivers/test/diff/MultipleFunctionClassAnnotations.sarif rename to codeql/src/drivers/test/diff/IrqlInconsistentWithRequired.sarif diff --git a/src/drivers/test/diff/MultithreadedAVCondition.sarif b/codeql/src/drivers/test/diff/IrqlLoweredImproperly.sarif similarity index 100% rename from src/drivers/test/diff/MultithreadedAVCondition.sarif rename to codeql/src/drivers/test/diff/IrqlLoweredImproperly.sarif diff --git a/src/drivers/test/diff/NtstatusExplicitCast.sarif b/codeql/src/drivers/test/diff/IrqlNotSaved.sarif similarity index 100% rename from src/drivers/test/diff/NtstatusExplicitCast.sarif rename to codeql/src/drivers/test/diff/IrqlNotSaved.sarif diff --git a/src/drivers/test/diff/NtstatusExplicitCast2.sarif b/codeql/src/drivers/test/diff/IrqlNotUsed.sarif similarity index 100% rename from src/drivers/test/diff/NtstatusExplicitCast2.sarif rename to codeql/src/drivers/test/diff/IrqlNotUsed.sarif diff --git a/src/drivers/test/diff/NtstatusExplicitCast3.sarif b/codeql/src/drivers/test/diff/IrqlSetTooHigh.sarif similarity index 100% rename from src/drivers/test/diff/NtstatusExplicitCast3.sarif rename to codeql/src/drivers/test/diff/IrqlSetTooHigh.sarif diff --git a/src/drivers/test/diff/IrqlSetTooLow.sarif b/codeql/src/drivers/test/diff/IrqlSetTooLow.sarif similarity index 100% rename from src/drivers/test/diff/IrqlSetTooLow.sarif rename to codeql/src/drivers/test/diff/IrqlSetTooLow.sarif diff --git a/src/drivers/test/diff/NullCharacterPointerAssignment.sarif b/codeql/src/drivers/test/diff/IrqlTooHigh.sarif similarity index 100% rename from src/drivers/test/diff/NullCharacterPointerAssignment.sarif rename to codeql/src/drivers/test/diff/IrqlTooHigh.sarif diff --git a/src/drivers/test/diff/ObReferenceMode.sarif b/codeql/src/drivers/test/diff/IrqlTooLow.sarif similarity index 100% rename from src/drivers/test/diff/ObReferenceMode.sarif rename to codeql/src/drivers/test/diff/IrqlTooLow.sarif diff --git a/src/drivers/test/diff/OperandAssignment.sarif b/codeql/src/drivers/test/diff/KeSetEventIrql.sarif similarity index 100% rename from src/drivers/test/diff/OperandAssignment.sarif rename to codeql/src/drivers/test/diff/KeSetEventIrql.sarif diff --git a/src/drivers/test/diff/PointerVariableSize.sarif b/codeql/src/drivers/test/diff/KeSetEventPageable.sarif similarity index 100% rename from src/drivers/test/diff/PointerVariableSize.sarif rename to codeql/src/drivers/test/diff/KeSetEventPageable.sarif diff --git a/src/drivers/test/diff/PoolTagIntegral.sarif b/codeql/src/drivers/test/diff/KeWaitLocal.sarif similarity index 100% rename from src/drivers/test/diff/PoolTagIntegral.sarif rename to codeql/src/drivers/test/diff/KeWaitLocal.sarif diff --git a/src/drivers/test/diff/RoutineFunctionTypeNotExpected.sarif b/codeql/src/drivers/test/diff/MultipleFunctionClassAnnotations.sarif similarity index 100% rename from src/drivers/test/diff/RoutineFunctionTypeNotExpected.sarif rename to codeql/src/drivers/test/diff/MultipleFunctionClassAnnotations.sarif diff --git a/src/drivers/test/diff/StaticInitializer.sarif b/codeql/src/drivers/test/diff/MultiplePagedCode.sarif similarity index 100% rename from src/drivers/test/diff/StaticInitializer.sarif rename to codeql/src/drivers/test/diff/MultiplePagedCode.sarif diff --git a/src/drivers/test/diff/StrictTypeMatch.sarif b/codeql/src/drivers/test/diff/MultithreadedAVCondition.sarif similarity index 100% rename from src/drivers/test/diff/StrictTypeMatch.sarif rename to codeql/src/drivers/test/diff/MultithreadedAVCondition.sarif diff --git a/src/drivers/test/diff/UnsafeCallInGlobalInit.sarif b/codeql/src/drivers/test/diff/NoPagedCode.sarif similarity index 100% rename from src/drivers/test/diff/UnsafeCallInGlobalInit.sarif rename to codeql/src/drivers/test/diff/NoPagedCode.sarif diff --git a/src/drivers/test/diff/WdkDeprecatedApis.sarif b/codeql/src/drivers/test/diff/NoPagingSegment.sarif similarity index 100% rename from src/drivers/test/diff/WdkDeprecatedApis.sarif rename to codeql/src/drivers/test/diff/NoPagingSegment.sarif diff --git a/src/drivers/test/diff/IllegalFieldAccess2.sarif b/codeql/src/drivers/test/diff/NtstatusExplicitCast.sarif similarity index 93% rename from src/drivers/test/diff/IllegalFieldAccess2.sarif rename to codeql/src/drivers/test/diff/NtstatusExplicitCast.sarif index 8d5a80f9..dea8275e 100644 --- a/src/drivers/test/diff/IllegalFieldAccess2.sarif +++ b/codeql/src/drivers/test/diff/NtstatusExplicitCast.sarif @@ -1,21 +1,21 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } } \ No newline at end of file diff --git a/src/drivers/test/diff/IllegalFieldWrite.sarif b/codeql/src/drivers/test/diff/NtstatusExplicitCast2.sarif similarity index 93% rename from src/drivers/test/diff/IllegalFieldWrite.sarif rename to codeql/src/drivers/test/diff/NtstatusExplicitCast2.sarif index 8d5a80f9..dea8275e 100644 --- a/src/drivers/test/diff/IllegalFieldWrite.sarif +++ b/codeql/src/drivers/test/diff/NtstatusExplicitCast2.sarif @@ -1,21 +1,21 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } } \ No newline at end of file diff --git a/src/drivers/test/diff/ExaminedValue.sarif b/codeql/src/drivers/test/diff/NtstatusExplicitCast3.sarif similarity index 93% rename from src/drivers/test/diff/ExaminedValue.sarif rename to codeql/src/drivers/test/diff/NtstatusExplicitCast3.sarif index 8d5a80f9..dea8275e 100644 --- a/src/drivers/test/diff/ExaminedValue.sarif +++ b/codeql/src/drivers/test/diff/NtstatusExplicitCast3.sarif @@ -1,21 +1,21 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } } \ No newline at end of file diff --git a/src/drivers/test/diff/IllegalFieldAccess.sarif b/codeql/src/drivers/test/diff/NullCharacterPointerAssignment.sarif similarity index 93% rename from src/drivers/test/diff/IllegalFieldAccess.sarif rename to codeql/src/drivers/test/diff/NullCharacterPointerAssignment.sarif index 8d5a80f9..dea8275e 100644 --- a/src/drivers/test/diff/IllegalFieldAccess.sarif +++ b/codeql/src/drivers/test/diff/NullCharacterPointerAssignment.sarif @@ -1,21 +1,21 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } } \ No newline at end of file diff --git a/codeql/src/drivers/test/diff/ObReferenceMode.sarif b/codeql/src/drivers/test/diff/ObReferenceMode.sarif new file mode 100644 index 00000000..dea8275e --- /dev/null +++ b/codeql/src/drivers/test/diff/ObReferenceMode.sarif @@ -0,0 +1,21 @@ +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } +} \ No newline at end of file diff --git a/src/drivers/test/diff/OpaqueMdlUse.sarif b/codeql/src/drivers/test/diff/OpaqueMdlUse.sarif similarity index 93% rename from src/drivers/test/diff/OpaqueMdlUse.sarif rename to codeql/src/drivers/test/diff/OpaqueMdlUse.sarif index 8d5a80f9..dea8275e 100644 --- a/src/drivers/test/diff/OpaqueMdlUse.sarif +++ b/codeql/src/drivers/test/diff/OpaqueMdlUse.sarif @@ -1,21 +1,21 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } } \ No newline at end of file diff --git a/src/drivers/test/diff/OpaqueMdlWrite.sarif b/codeql/src/drivers/test/diff/OpaqueMdlWrite.sarif similarity index 93% rename from src/drivers/test/diff/OpaqueMdlWrite.sarif rename to codeql/src/drivers/test/diff/OpaqueMdlWrite.sarif index 8d5a80f9..dea8275e 100644 --- a/src/drivers/test/diff/OpaqueMdlWrite.sarif +++ b/codeql/src/drivers/test/diff/OpaqueMdlWrite.sarif @@ -1,21 +1,21 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } } \ No newline at end of file diff --git a/codeql/src/drivers/test/diff/OperandAssignment.sarif b/codeql/src/drivers/test/diff/OperandAssignment.sarif new file mode 100644 index 00000000..dea8275e --- /dev/null +++ b/codeql/src/drivers/test/diff/OperandAssignment.sarif @@ -0,0 +1,21 @@ +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } +} \ No newline at end of file diff --git a/src/drivers/test/diff/PendingStatusError.sarif b/codeql/src/drivers/test/diff/PendingStatusError.sarif similarity index 93% rename from src/drivers/test/diff/PendingStatusError.sarif rename to codeql/src/drivers/test/diff/PendingStatusError.sarif index 8d5a80f9..dea8275e 100644 --- a/src/drivers/test/diff/PendingStatusError.sarif +++ b/codeql/src/drivers/test/diff/PendingStatusError.sarif @@ -1,21 +1,21 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } } \ No newline at end of file diff --git a/codeql/src/drivers/test/diff/PointerVariableSize.sarif b/codeql/src/drivers/test/diff/PointerVariableSize.sarif new file mode 100644 index 00000000..dea8275e --- /dev/null +++ b/codeql/src/drivers/test/diff/PointerVariableSize.sarif @@ -0,0 +1,21 @@ +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } +} \ No newline at end of file diff --git a/codeql/src/drivers/test/diff/PoolTagIntegral.sarif b/codeql/src/drivers/test/diff/PoolTagIntegral.sarif new file mode 100644 index 00000000..dea8275e --- /dev/null +++ b/codeql/src/drivers/test/diff/PoolTagIntegral.sarif @@ -0,0 +1,21 @@ +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } +} \ No newline at end of file diff --git a/src/drivers/test/diff/RoleTypeCorrectlyUsed.sarif b/codeql/src/drivers/test/diff/RoleTypeCorrectlyUsed.sarif similarity index 93% rename from src/drivers/test/diff/RoleTypeCorrectlyUsed.sarif rename to codeql/src/drivers/test/diff/RoleTypeCorrectlyUsed.sarif index 8d5a80f9..dea8275e 100644 --- a/src/drivers/test/diff/RoleTypeCorrectlyUsed.sarif +++ b/codeql/src/drivers/test/diff/RoleTypeCorrectlyUsed.sarif @@ -1,21 +1,21 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } } \ No newline at end of file diff --git a/codeql/src/drivers/test/diff/RoutineFunctionTypeNotExpected.sarif b/codeql/src/drivers/test/diff/RoutineFunctionTypeNotExpected.sarif new file mode 100644 index 00000000..dea8275e --- /dev/null +++ b/codeql/src/drivers/test/diff/RoutineFunctionTypeNotExpected.sarif @@ -0,0 +1,21 @@ +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } +} \ No newline at end of file diff --git a/codeql/src/drivers/test/diff/StaticInitializer.sarif b/codeql/src/drivers/test/diff/StaticInitializer.sarif new file mode 100644 index 00000000..dea8275e --- /dev/null +++ b/codeql/src/drivers/test/diff/StaticInitializer.sarif @@ -0,0 +1,21 @@ +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } +} \ No newline at end of file diff --git a/src/drivers/test/diff/StrSafe.sarif b/codeql/src/drivers/test/diff/StrSafe.sarif similarity index 93% rename from src/drivers/test/diff/StrSafe.sarif rename to codeql/src/drivers/test/diff/StrSafe.sarif index 8d5a80f9..dea8275e 100644 --- a/src/drivers/test/diff/StrSafe.sarif +++ b/codeql/src/drivers/test/diff/StrSafe.sarif @@ -1,21 +1,21 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } } \ No newline at end of file diff --git a/codeql/src/drivers/test/diff/StrictTypeMatch.sarif b/codeql/src/drivers/test/diff/StrictTypeMatch.sarif new file mode 100644 index 00000000..dea8275e --- /dev/null +++ b/codeql/src/drivers/test/diff/StrictTypeMatch.sarif @@ -0,0 +1,21 @@ +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } +} \ No newline at end of file diff --git a/src/drivers/test/diff/UnicodeStringFreed.sarif b/codeql/src/drivers/test/diff/UnicodeStringFreed.sarif similarity index 93% rename from src/drivers/test/diff/UnicodeStringFreed.sarif rename to codeql/src/drivers/test/diff/UnicodeStringFreed.sarif index 8d5a80f9..dea8275e 100644 --- a/src/drivers/test/diff/UnicodeStringFreed.sarif +++ b/codeql/src/drivers/test/diff/UnicodeStringFreed.sarif @@ -1,21 +1,21 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } } \ No newline at end of file diff --git a/codeql/src/drivers/test/diff/UnsafeCallInGlobalInit.sarif b/codeql/src/drivers/test/diff/UnsafeCallInGlobalInit.sarif new file mode 100644 index 00000000..dea8275e --- /dev/null +++ b/codeql/src/drivers/test/diff/UnsafeCallInGlobalInit.sarif @@ -0,0 +1,21 @@ +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } +} \ No newline at end of file diff --git a/codeql/src/drivers/test/diff/WdkDeprecatedApis.sarif b/codeql/src/drivers/test/diff/WdkDeprecatedApis.sarif new file mode 100644 index 00000000..dea8275e --- /dev/null +++ b/codeql/src/drivers/test/diff/WdkDeprecatedApis.sarif @@ -0,0 +1,21 @@ +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } +} \ No newline at end of file diff --git a/src/drivers/test/diff/WrongDispatchTableAssignment.sarif b/codeql/src/drivers/test/diff/WrongDispatchTableAssignment.sarif similarity index 93% rename from src/drivers/test/diff/WrongDispatchTableAssignment.sarif rename to codeql/src/drivers/test/diff/WrongDispatchTableAssignment.sarif index 8d5a80f9..dea8275e 100644 --- a/src/drivers/test/diff/WrongDispatchTableAssignment.sarif +++ b/codeql/src/drivers/test/diff/WrongDispatchTableAssignment.sarif @@ -1,21 +1,21 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } +{ + "all": { + "+": 0, + "-": 0 + }, + "error": { + "+": 0, + "-": 0, + "codes": [] + }, + "warning": { + "+": 0, + "-": 0, + "codes": [] + }, + "note": { + "+": 0, + "-": 0, + "codes": [] + } } \ No newline at end of file diff --git a/src/drivers/test/dvl_tests/dvl_tests.ps1 b/codeql/src/drivers/test/dvl_tests/dvl_tests.ps1 similarity index 100% rename from src/drivers/test/dvl_tests/dvl_tests.ps1 rename to codeql/src/drivers/test/dvl_tests/dvl_tests.ps1 diff --git a/src/drivers/test/dvl_tests/expected_results/clean_expected.sarif b/codeql/src/drivers/test/dvl_tests/expected_results/clean_expected.sarif similarity index 100% rename from src/drivers/test/dvl_tests/expected_results/clean_expected.sarif rename to codeql/src/drivers/test/dvl_tests/expected_results/clean_expected.sarif diff --git a/src/drivers/test/dvl_tests/expected_results/mustfix_expected.sarif b/codeql/src/drivers/test/dvl_tests/expected_results/mustfix_expected.sarif similarity index 100% rename from src/drivers/test/dvl_tests/expected_results/mustfix_expected.sarif rename to codeql/src/drivers/test/dvl_tests/expected_results/mustfix_expected.sarif diff --git a/src/drivers/test/requirements.txt b/codeql/src/drivers/test/requirements.txt similarity index 100% rename from src/drivers/test/requirements.txt rename to codeql/src/drivers/test/requirements.txt diff --git a/src/drivers/wdm/libraries/Mdl.qll b/codeql/src/drivers/wdm/libraries/Mdl.qll similarity index 100% rename from src/drivers/wdm/libraries/Mdl.qll rename to codeql/src/drivers/wdm/libraries/Mdl.qll diff --git a/src/drivers/wdm/libraries/WdmDrivers.qll b/codeql/src/drivers/wdm/libraries/WdmDrivers.qll similarity index 100% rename from src/drivers/wdm/libraries/WdmDrivers.qll rename to codeql/src/drivers/wdm/libraries/WdmDrivers.qll diff --git a/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.qhelp b/codeql/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.qhelp similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.qhelp rename to codeql/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.qhelp diff --git a/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.ql b/codeql/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.ql similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.ql rename to codeql/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.ql diff --git a/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.sarif b/codeql/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.sarif similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.sarif rename to codeql/src/drivers/wdm/queries/IllegalFieldAccess/IllegalFieldAccess.sarif diff --git a/src/drivers/wdm/queries/IllegalFieldAccess/driver_snippet.c b/codeql/src/drivers/wdm/queries/IllegalFieldAccess/driver_snippet.c similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldAccess/driver_snippet.c rename to codeql/src/drivers/wdm/queries/IllegalFieldAccess/driver_snippet.c diff --git a/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.qhelp b/codeql/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.qhelp similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.qhelp rename to codeql/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.qhelp diff --git a/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.ql b/codeql/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.ql similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.ql rename to codeql/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.ql diff --git a/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.sarif b/codeql/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.sarif similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.sarif rename to codeql/src/drivers/wdm/queries/IllegalFieldAccess2/IllegalFieldAccess2.sarif diff --git a/src/drivers/wdm/queries/IllegalFieldAccess2/driver_snippet.c b/codeql/src/drivers/wdm/queries/IllegalFieldAccess2/driver_snippet.c similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldAccess2/driver_snippet.c rename to codeql/src/drivers/wdm/queries/IllegalFieldAccess2/driver_snippet.c diff --git a/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.qhelp b/codeql/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.qhelp similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.qhelp rename to codeql/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.qhelp diff --git a/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.ql b/codeql/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.ql similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.ql rename to codeql/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.ql diff --git a/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.sarif b/codeql/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.sarif similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.sarif rename to codeql/src/drivers/wdm/queries/IllegalFieldWrite/IllegalFieldWrite.sarif diff --git a/src/drivers/wdm/queries/IllegalFieldWrite/driver_snippet.c b/codeql/src/drivers/wdm/queries/IllegalFieldWrite/driver_snippet.c similarity index 100% rename from src/drivers/wdm/queries/IllegalFieldWrite/driver_snippet.c rename to codeql/src/drivers/wdm/queries/IllegalFieldWrite/driver_snippet.c diff --git a/src/drivers/wdm/queries/InconsistentDispatchAnnotations.ql b/codeql/src/drivers/wdm/queries/InconsistentDispatchAnnotations.ql similarity index 100% rename from src/drivers/wdm/queries/InconsistentDispatchAnnotations.ql rename to codeql/src/drivers/wdm/queries/InconsistentDispatchAnnotations.ql diff --git a/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.qhelp b/codeql/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.qhelp similarity index 100% rename from src/drivers/wdm/queries/InitNotCleared/InitNotCleared.qhelp rename to codeql/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.qhelp diff --git a/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.ql b/codeql/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.ql similarity index 100% rename from src/drivers/wdm/queries/InitNotCleared/InitNotCleared.ql rename to codeql/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.ql diff --git a/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.sarif b/codeql/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.sarif similarity index 100% rename from src/drivers/wdm/queries/InitNotCleared/InitNotCleared.sarif rename to codeql/src/drivers/wdm/queries/InitNotCleared/InitNotCleared.sarif diff --git a/src/drivers/wdm/queries/InitNotCleared/driver_snippet.c b/codeql/src/drivers/wdm/queries/InitNotCleared/driver_snippet.c similarity index 100% rename from src/drivers/wdm/queries/InitNotCleared/driver_snippet.c rename to codeql/src/drivers/wdm/queries/InitNotCleared/driver_snippet.c diff --git a/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.qhelp b/codeql/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.qhelp similarity index 100% rename from src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.qhelp rename to codeql/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.qhelp diff --git a/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.ql b/codeql/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.ql similarity index 97% rename from src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.ql rename to codeql/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.ql index 7e27b0b5..ff228aa6 100644 --- a/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.ql +++ b/codeql/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.ql @@ -1,32 +1,32 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -/** - * @id cpp/drivers/kewaitlocal-requires-kernel-mode - * @name Use of local variable and UserMode in call to KeWaitSingleObject - * @description When the first argument to KeWaitForSingleObject is a local variable, the Mode parameter must be KernelMode. - * @platform Desktop - * @security.severity Low - * @feature.area Multiple - * @impact Exploitable Design - * @repro.text The following code locations contain a call to KeWaitForSingleObject while waiting for a local kernel-mode object, but the Mode parameter has not been set to KernelMode. - * @owner.email sdat@microsoft.com - * @opaqueid CQLD-C28135 - * @kind problem - * @problem.severity warning - * @precision high - * @tags correctness - * ca_ported - * wddst - * @scope domainspecific - * @query-version v2 - */ - -import cpp - -from FunctionCall call, VariableAccess va -where - call.getTarget().getName() = "KeWaitForSingleObject" and - call.getArgument(2).getValue().toInt() != 0 and - call.getArgument(0).(AddressOfExpr).getOperand() = va and - va.getTarget() instanceof StackVariable +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +/** + * @id cpp/drivers/kewaitlocal-requires-kernel-mode + * @name Use of local variable and UserMode in call to KeWaitSingleObject + * @description When the first argument to KeWaitForSingleObject is a local variable, the Mode parameter must be KernelMode. + * @platform Desktop + * @security.severity Low + * @feature.area Multiple + * @impact Exploitable Design + * @repro.text The following code locations contain a call to KeWaitForSingleObject while waiting for a local kernel-mode object, but the Mode parameter has not been set to KernelMode. + * @owner.email sdat@microsoft.com + * @opaqueid CQLD-C28135 + * @kind problem + * @problem.severity warning + * @precision high + * @tags correctness + * ca_ported + * wddst + * @scope domainspecific + * @query-version v2 + */ + +import cpp + +from FunctionCall call, VariableAccess va +where + call.getTarget().getName() = "KeWaitForSingleObject" and + call.getArgument(2).getValue().toInt() != 0 and + call.getArgument(0).(AddressOfExpr).getOperand() = va and + va.getTarget() instanceof StackVariable select call, "$@: KeWaitForSingleObject should have a KernelMode AccessMode when the $@ is local", call.getControlFlowScope(), call.getControlFlowScope().getQualifiedName(), va.getTarget(), "first argument" \ No newline at end of file diff --git a/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.sarif b/codeql/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.sarif similarity index 96% rename from src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.sarif rename to codeql/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.sarif index b8c9ff70..db70a582 100644 --- a/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.sarif +++ b/codeql/src/drivers/wdm/queries/KeWaitLocal/KeWaitLocal.sarif @@ -1,236 +1,236 @@ -{ - "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", - "version" : "2.1.0", - "runs" : [ { - "tool" : { - "driver" : { - "name" : "CodeQL", - "organization" : "GitHub", - "semanticVersion" : "2.15.1", - "notifications" : [ { - "id" : "cpp/baseline/expected-extracted-files", - "name" : "cpp/baseline/expected-extracted-files", - "shortDescription" : { - "text" : "Expected extracted files" - }, - "fullDescription" : { - "text" : "Files appearing in the source archive that are expected to be extracted." - }, - "defaultConfiguration" : { - "enabled" : true - }, - "properties" : { - "tags" : [ "expected-extracted-files", "telemetry" ] - } - } ], - "rules" : [ { - "id" : "cpp/drivers/kewaitlocal-requires-kernel-mode", - "name" : "cpp/drivers/kewaitlocal-requires-kernel-mode", - "shortDescription" : { - "text" : "Use of local variable and UserMode in call to KeWaitSingleObject" - }, - "fullDescription" : { - "text" : "When the first argument to KeWaitForSingleObject is a local variable, the Mode parameter must be KernelMode." - }, - "defaultConfiguration" : { - "enabled" : true, - "level" : "warning" - }, - "properties" : { - "tags" : [ "correctness", "wddst" ], - "description" : "When the first argument to KeWaitForSingleObject is a local variable, the Mode parameter must be KernelMode.", - "feature.area" : "Multiple", - "id" : "cpp/drivers/kewaitlocal-requires-kernel-mode", - "impact" : "Exploitable Design", - "kind" : "problem", - "name" : "Use of local variable and UserMode in call to KeWaitSingleObject", - "opaqueid" : "CQLD-C28135", - "owner.email" : "sdat@microsoft.com", - "platform" : "Desktop", - "precision" : "high", - "problem.severity" : "warning", - "query-version" : "v2", - "repro.text" : "The following code locations contain a call to KeWaitForSingleObject while waiting for a local kernel-mode object, but the Mode parameter has not been set to KernelMode.", - "scope" : "domainspecific", - "security.severity" : "Low" - } - } ] - }, - "extensions" : [ { - "name" : "microsoft/windows-drivers", - "semanticVersion" : "0.2.0+143fe74d66f4093412a7b21390672217b557bba2", - "locations" : [ { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - } ] - }, - "invocations" : [ { - "toolExecutionNotifications" : [ { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - }, { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 1 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - }, { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/fail_driver1.h", - "uriBaseId" : "%SRCROOT%", - "index" : 2 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - } ], - "executionSuccessful" : true - } ], - "artifacts" : [ { - "location" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - }, { - "location" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 1 - } - }, { - "location" : { - "uri" : "driver/fail_driver1.h", - "uriBaseId" : "%SRCROOT%", - "index" : 2 - } - } ], - "results" : [ { - "ruleId" : "cpp/drivers/kewaitlocal-requires-kernel-mode", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/kewaitlocal-requires-kernel-mode", - "index" : 0 - }, - "message" : { - "text" : "[good_use](1): KeWaitForSingleObject should have a KernelMode AccessMode when the [first argument](2) is local" - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 10, - "startColumn" : 5, - "endColumn" : 26 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "61bc3c7079348327:1", - "primaryLocationStartColumnFingerprint" : "0" - }, - "relatedLocations" : [ { - "id" : 1, - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 7, - "startColumn" : 6, - "endColumn" : 14 - } - }, - "message" : { - "text" : "good_use" - } - }, { - "id" : 2, - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 9, - "startColumn" : 12, - "endColumn" : 19 - } - }, - "message" : { - "text" : "first argument" - } - } ] - } ], - "columnKind" : "utf16CodeUnits", - "properties" : { - "semmle.formatSpecifier" : "sarifv2.1.0" - } - } ] +{ + "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", + "version" : "2.1.0", + "runs" : [ { + "tool" : { + "driver" : { + "name" : "CodeQL", + "organization" : "GitHub", + "semanticVersion" : "2.15.1", + "notifications" : [ { + "id" : "cpp/baseline/expected-extracted-files", + "name" : "cpp/baseline/expected-extracted-files", + "shortDescription" : { + "text" : "Expected extracted files" + }, + "fullDescription" : { + "text" : "Files appearing in the source archive that are expected to be extracted." + }, + "defaultConfiguration" : { + "enabled" : true + }, + "properties" : { + "tags" : [ "expected-extracted-files", "telemetry" ] + } + } ], + "rules" : [ { + "id" : "cpp/drivers/kewaitlocal-requires-kernel-mode", + "name" : "cpp/drivers/kewaitlocal-requires-kernel-mode", + "shortDescription" : { + "text" : "Use of local variable and UserMode in call to KeWaitSingleObject" + }, + "fullDescription" : { + "text" : "When the first argument to KeWaitForSingleObject is a local variable, the Mode parameter must be KernelMode." + }, + "defaultConfiguration" : { + "enabled" : true, + "level" : "warning" + }, + "properties" : { + "tags" : [ "correctness", "wddst" ], + "description" : "When the first argument to KeWaitForSingleObject is a local variable, the Mode parameter must be KernelMode.", + "feature.area" : "Multiple", + "id" : "cpp/drivers/kewaitlocal-requires-kernel-mode", + "impact" : "Exploitable Design", + "kind" : "problem", + "name" : "Use of local variable and UserMode in call to KeWaitSingleObject", + "opaqueid" : "CQLD-C28135", + "owner.email" : "sdat@microsoft.com", + "platform" : "Desktop", + "precision" : "high", + "problem.severity" : "warning", + "query-version" : "v2", + "repro.text" : "The following code locations contain a call to KeWaitForSingleObject while waiting for a local kernel-mode object, but the Mode parameter has not been set to KernelMode.", + "scope" : "domainspecific", + "security.severity" : "Low" + } + } ] + }, + "extensions" : [ { + "name" : "microsoft/windows-drivers", + "semanticVersion" : "0.2.0+143fe74d66f4093412a7b21390672217b557bba2", + "locations" : [ { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + } ] + }, + "invocations" : [ { + "toolExecutionNotifications" : [ { + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + } + } ], + "message" : { + "text" : "" + }, + "level" : "none", + "descriptor" : { + "id" : "cpp/baseline/expected-extracted-files", + "index" : 0 + }, + "properties" : { + "formattedMessage" : { + "text" : "" + } + } + }, { + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/fail_driver1.c", + "uriBaseId" : "%SRCROOT%", + "index" : 1 + } + } + } ], + "message" : { + "text" : "" + }, + "level" : "none", + "descriptor" : { + "id" : "cpp/baseline/expected-extracted-files", + "index" : 0 + }, + "properties" : { + "formattedMessage" : { + "text" : "" + } + } + }, { + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/fail_driver1.h", + "uriBaseId" : "%SRCROOT%", + "index" : 2 + } + } + } ], + "message" : { + "text" : "" + }, + "level" : "none", + "descriptor" : { + "id" : "cpp/baseline/expected-extracted-files", + "index" : 0 + }, + "properties" : { + "formattedMessage" : { + "text" : "" + } + } + } ], + "executionSuccessful" : true + } ], + "artifacts" : [ { + "location" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + }, { + "location" : { + "uri" : "driver/fail_driver1.c", + "uriBaseId" : "%SRCROOT%", + "index" : 1 + } + }, { + "location" : { + "uri" : "driver/fail_driver1.h", + "uriBaseId" : "%SRCROOT%", + "index" : 2 + } + } ], + "results" : [ { + "ruleId" : "cpp/drivers/kewaitlocal-requires-kernel-mode", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/kewaitlocal-requires-kernel-mode", + "index" : 0 + }, + "message" : { + "text" : "[good_use](1): KeWaitForSingleObject should have a KernelMode AccessMode when the [first argument](2) is local" + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 10, + "startColumn" : 5, + "endColumn" : 26 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "61bc3c7079348327:1", + "primaryLocationStartColumnFingerprint" : "0" + }, + "relatedLocations" : [ { + "id" : 1, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 7, + "startColumn" : 6, + "endColumn" : 14 + } + }, + "message" : { + "text" : "good_use" + } + }, { + "id" : 2, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 9, + "startColumn" : 12, + "endColumn" : 19 + } + }, + "message" : { + "text" : "first argument" + } + } ] + } ], + "columnKind" : "utf16CodeUnits", + "properties" : { + "semmle.formatSpecifier" : "sarifv2.1.0" + } + } ] } \ No newline at end of file diff --git a/src/drivers/wdm/queries/KeWaitLocal/driver_snippet.c b/codeql/src/drivers/wdm/queries/KeWaitLocal/driver_snippet.c similarity index 100% rename from src/drivers/wdm/queries/KeWaitLocal/driver_snippet.c rename to codeql/src/drivers/wdm/queries/KeWaitLocal/driver_snippet.c diff --git a/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.qhelp b/codeql/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.qhelp similarity index 97% rename from src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.qhelp rename to codeql/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.qhelp index 70fdef92..3d4c7862 100644 --- a/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.qhelp +++ b/codeql/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.qhelp @@ -1,24 +1,24 @@ - - - -

- 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. -

-
- -

- Remove all but one PAGED_CODE OR PAGED_CODE_LOCKED macro. -

-
- - - - -
  • - - C28171 warning - Windows Drivers - -
  • -
    -
    + + + +

    + 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. +

    +
    + +

    + Remove all but one PAGED_CODE OR PAGED_CODE_LOCKED macro. +

    +
    + + + + +
  • + + C28171 warning - Windows Drivers + +
  • +
    +
    diff --git a/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.ql b/codeql/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.ql similarity index 97% rename from src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.ql rename to codeql/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.ql index 202c4e3f..4a245dc6 100644 --- a/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.ql +++ b/codeql/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.ql @@ -1,36 +1,36 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -/** - * @id cpp/drivers/multiple-paged-code - * @name Multiple instances of PAGED_CODE or PAGED_CODE_LOCKED - * @description The function has more than one instance of PAGED_CODE or PAGED_CODE_LOCKED. This can cause issues when debugging, using Code Analysis, or running on checked builds. - * @platform Desktop - * @security.severity Low - * @feature.area Multiple - * @impact Insecure Coding Practice - * @repro.text The following code locations are duplicate PAGED_CODE() calls within a function. - * @owner.email sdat@microsoft.com - * @opaqueid CQLD-C28171 - * @kind problem - * @problem.severity warning - * @precision high - * @tags correctness - * ca_ported - * wddst - * @scope domainspecific - * @query-version v1 - */ - -import cpp -import drivers.libraries.Page - -// Selects functions that have at least two instances of a PAGED_CODE macro. -from MacroInvocation mi, MacroInvocation mi2 -where - mi.getEnclosingFunction() = mi2.getEnclosingFunction() and - mi.getEnclosingFunction() instanceof PagedFunctionDeclaration and - mi.getMacroName() = ["PAGED_CODE", "PAGED_CODE_LOCKED"] and - mi2.getMacroName() = ["PAGED_CODE", "PAGED_CODE_LOCKED"] and - mi.getLocation().getStartLine() < mi2.getLocation().getStartLine() -select mi2, - "Functions in a paged section must have exactly one instance of the PAGED_CODE or PAGED_CODE_LOCKED macro" +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +/** + * @id cpp/drivers/multiple-paged-code + * @name Multiple instances of PAGED_CODE or PAGED_CODE_LOCKED + * @description The function has more than one instance of PAGED_CODE or PAGED_CODE_LOCKED. This can cause issues when debugging, using Code Analysis, or running on checked builds. + * @platform Desktop + * @security.severity Low + * @feature.area Multiple + * @impact Insecure Coding Practice + * @repro.text The following code locations are duplicate PAGED_CODE() calls within a function. + * @owner.email sdat@microsoft.com + * @opaqueid CQLD-C28171 + * @kind problem + * @problem.severity warning + * @precision high + * @tags correctness + * ca_ported + * wddst + * @scope domainspecific + * @query-version v1 + */ + +import cpp +import drivers.libraries.Page + +// Selects functions that have at least two instances of a PAGED_CODE macro. +from MacroInvocation mi, MacroInvocation mi2 +where + mi.getEnclosingFunction() = mi2.getEnclosingFunction() and + mi.getEnclosingFunction() instanceof PagedFunctionDeclaration and + mi.getMacroName() = ["PAGED_CODE", "PAGED_CODE_LOCKED"] and + mi2.getMacroName() = ["PAGED_CODE", "PAGED_CODE_LOCKED"] and + mi.getLocation().getStartLine() < mi2.getLocation().getStartLine() +select mi2, + "Functions in a paged section must have exactly one instance of the PAGED_CODE or PAGED_CODE_LOCKED macro" diff --git a/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.sarif b/codeql/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.sarif similarity index 97% rename from src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.sarif rename to codeql/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.sarif index 41a84ed4..e8ebfd83 100644 --- a/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.sarif +++ b/codeql/src/drivers/wdm/queries/MultiplePagedCode/MultiplePagedCode.sarif @@ -1,114 +1,114 @@ -{ - "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", - "version" : "2.1.0", - "runs" : [ { - "tool" : { - "driver" : { - "name" : "CodeQL", - "organization" : "GitHub", - "semanticVersion" : "2.11.5", - "rules" : [ { - "id" : "cpp/drivers/multiple-paged-code", - "name" : "cpp/drivers/multiple-paged-code", - "shortDescription" : { - "text" : "Multiple instances of PAGED_CODE or PAGED_CODE_LOCKED" - }, - "fullDescription" : { - "text" : "The function has more than one instance of PAGED_CODE or PAGED_CODE_LOCKED. This can cause issues when debugging, using Code Analysis, or running on checked builds." - }, - "defaultConfiguration" : { - "enabled" : true, - "level" : "warning" - }, - "properties" : { - "tags" : [ "correctness", "wddst" ], - "description" : "The function has more than one instance of PAGED_CODE or PAGED_CODE_LOCKED. This can cause issues when debugging, using Code Analysis, or running on checked builds.", - "feature.area" : "Multiple", - "id" : "cpp/drivers/multiple-paged-code", - "impact" : "Insecure Coding Practice", - "kind" : "problem", - "name" : "Multiple instances of PAGED_CODE or PAGED_CODE_LOCKED", - "opaqueid" : "CQLD-C28171", - "owner.email" : "sdat@microsoft.com", - "platform" : "Desktop", - "precision" : "high", - "problem.severity" : "warning", - "query-version" : "v1", - "repro.text" : "The following code locations are duplicate PAGED_CODE() calls within a function.", - "scope" : "domainspecific", - "security.severity" : "Low" - } - } ] - }, - "extensions" : [ { - "name" : "microsoft/windows-drivers", - "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", - "locations" : [ { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - }, { - "name" : "legacy-upgrades", - "semanticVersion" : "0.0.0", - "locations" : [ { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - } ] - }, - "artifacts" : [ { - "location" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - } ], - "results" : [ { - "ruleId" : "cpp/drivers/multiple-paged-code", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/multiple-paged-code", - "index" : 0 - }, - "message" : { - "text" : "Functions in a paged section must have exactly one instance of the PAGED_CODE or PAGED_CODE_LOCKED macro" - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 50, - "startColumn" : 5, - "endColumn" : 17 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "c7556935fb8cd898:1", - "primaryLocationStartColumnFingerprint" : "0" - } - } ], - "columnKind" : "utf16CodeUnits", - "properties" : { - "semmle.formatSpecifier" : "sarifv2.1.0" - } - } ] +{ + "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", + "version" : "2.1.0", + "runs" : [ { + "tool" : { + "driver" : { + "name" : "CodeQL", + "organization" : "GitHub", + "semanticVersion" : "2.11.5", + "rules" : [ { + "id" : "cpp/drivers/multiple-paged-code", + "name" : "cpp/drivers/multiple-paged-code", + "shortDescription" : { + "text" : "Multiple instances of PAGED_CODE or PAGED_CODE_LOCKED" + }, + "fullDescription" : { + "text" : "The function has more than one instance of PAGED_CODE or PAGED_CODE_LOCKED. This can cause issues when debugging, using Code Analysis, or running on checked builds." + }, + "defaultConfiguration" : { + "enabled" : true, + "level" : "warning" + }, + "properties" : { + "tags" : [ "correctness", "wddst" ], + "description" : "The function has more than one instance of PAGED_CODE or PAGED_CODE_LOCKED. This can cause issues when debugging, using Code Analysis, or running on checked builds.", + "feature.area" : "Multiple", + "id" : "cpp/drivers/multiple-paged-code", + "impact" : "Insecure Coding Practice", + "kind" : "problem", + "name" : "Multiple instances of PAGED_CODE or PAGED_CODE_LOCKED", + "opaqueid" : "CQLD-C28171", + "owner.email" : "sdat@microsoft.com", + "platform" : "Desktop", + "precision" : "high", + "problem.severity" : "warning", + "query-version" : "v1", + "repro.text" : "The following code locations are duplicate PAGED_CODE() calls within a function.", + "scope" : "domainspecific", + "security.severity" : "Low" + } + } ] + }, + "extensions" : [ { + "name" : "microsoft/windows-drivers", + "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", + "locations" : [ { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + }, { + "name" : "legacy-upgrades", + "semanticVersion" : "0.0.0", + "locations" : [ { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + } ] + }, + "artifacts" : [ { + "location" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + } ], + "results" : [ { + "ruleId" : "cpp/drivers/multiple-paged-code", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/multiple-paged-code", + "index" : 0 + }, + "message" : { + "text" : "Functions in a paged section must have exactly one instance of the PAGED_CODE or PAGED_CODE_LOCKED macro" + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 50, + "startColumn" : 5, + "endColumn" : 17 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "c7556935fb8cd898:1", + "primaryLocationStartColumnFingerprint" : "0" + } + } ], + "columnKind" : "utf16CodeUnits", + "properties" : { + "semmle.formatSpecifier" : "sarifv2.1.0" + } + } ] } \ No newline at end of file diff --git a/src/drivers/wdm/queries/MultiplePagedCode/driver_snippet.c b/codeql/src/drivers/wdm/queries/MultiplePagedCode/driver_snippet.c similarity index 94% rename from src/drivers/wdm/queries/MultiplePagedCode/driver_snippet.c rename to codeql/src/drivers/wdm/queries/MultiplePagedCode/driver_snippet.c index 4bc016a1..90c811d7 100644 --- a/src/drivers/wdm/queries/MultiplePagedCode/driver_snippet.c +++ b/codeql/src/drivers/wdm/queries/MultiplePagedCode/driver_snippet.c @@ -1,58 +1,58 @@ -// 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; -} - - - - - +// 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; +} + + + + + diff --git a/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.qhelp b/codeql/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.qhelp similarity index 96% rename from src/drivers/wdm/queries/NoPagedCode/NoPagedCode.qhelp rename to codeql/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.qhelp index 30f24036..c5f9abc1 100644 --- a/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.qhelp +++ b/codeql/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.qhelp @@ -1,25 +1,25 @@ - - - -

    - The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found. -

    -
    - -

    - 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. -

    -
    - - - - -
  • - - C28170 warning - Windows Drivers - -
  • -
    -
    + + + +

    + The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found. +

    +
    + +

    + 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. +

    +
    + + + + +
  • + + C28170 warning - Windows Drivers + +
  • +
    +
    diff --git a/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.ql b/codeql/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.ql similarity index 97% rename from src/drivers/wdm/queries/NoPagedCode/NoPagedCode.ql rename to codeql/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.ql index 3fec43bd..1b96c5a5 100644 --- a/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.ql +++ b/codeql/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.ql @@ -1,32 +1,32 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -/** - * @id cpp/drivers/no-paged-code - * @name No PAGED_CODE invocation - * @description The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found. This can cause issues when debugging, using Code Analysis, or running on checked builds. - * @platform Desktop - * @security.severity Low - * @feature.area Multiple - * @impact Insecure Coding Practice - * @repro.text The following code locations are duplicate PAGED_CODE() calls within a function. - * @owner.email sdat@microsoft.com - * @opaqueid CQLD-C28170 - * @kind problem - * @problem.severity warning - * @precision low - * @tags correctness - * ca_ported - * wddst - * @scope domainspecific - * @query-version v1 - */ - -import cpp -import drivers.libraries.Page - -from PagedFunctionDeclaration f -where - f.getEntryPoint() instanceof BlockStmt and - not f instanceof PagedFunc -select f, - "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found." +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +/** + * @id cpp/drivers/no-paged-code + * @name No PAGED_CODE invocation + * @description The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found. This can cause issues when debugging, using Code Analysis, or running on checked builds. + * @platform Desktop + * @security.severity Low + * @feature.area Multiple + * @impact Insecure Coding Practice + * @repro.text The following code locations are duplicate PAGED_CODE() calls within a function. + * @owner.email sdat@microsoft.com + * @opaqueid CQLD-C28170 + * @kind problem + * @problem.severity warning + * @precision low + * @tags correctness + * ca_ported + * wddst + * @scope domainspecific + * @query-version v1 + */ + +import cpp +import drivers.libraries.Page + +from PagedFunctionDeclaration f +where + f.getEntryPoint() instanceof BlockStmt and + not f instanceof PagedFunc +select f, + "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found." diff --git a/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.sarif b/codeql/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.sarif similarity index 97% rename from src/drivers/wdm/queries/NoPagedCode/NoPagedCode.sarif rename to codeql/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.sarif index 33fc00ac..978b9fa1 100644 --- a/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.sarif +++ b/codeql/src/drivers/wdm/queries/NoPagedCode/NoPagedCode.sarif @@ -1,169 +1,169 @@ -{ - "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", - "version" : "2.1.0", - "runs" : [ { - "tool" : { - "driver" : { - "name" : "CodeQL", - "organization" : "GitHub", - "semanticVersion" : "2.11.5", - "rules" : [ { - "id" : "cpp/drivers/no-paged-code", - "name" : "cpp/drivers/no-paged-code", - "shortDescription" : { - "text" : "No PAGED_CODE invocation" - }, - "fullDescription" : { - "text" : "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found. This can cause issues when debugging, using Code Analysis, or running on checked builds." - }, - "defaultConfiguration" : { - "enabled" : true, - "level" : "warning" - }, - "properties" : { - "tags" : [ "correctness", "wddst" ], - "description" : "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found. This can cause issues when debugging, using Code Analysis, or running on checked builds.", - "feature.area" : "Multiple", - "id" : "cpp/drivers/no-paged-code", - "impact" : "Insecure Coding Practice", - "kind" : "problem", - "name" : "No PAGED_CODE invocation", - "opaqueid" : "CQLD-C28170", - "owner.email" : "sdat@microsoft.com", - "platform" : "Desktop", - "precision" : "low", - "problem.severity" : "warning", - "query-version" : "v1", - "repro.text" : "The following code locations are duplicate PAGED_CODE() calls within a function.", - "scope" : "domainspecific", - "security.severity" : "Low" - } - } ] - }, - "extensions" : [ { - "name" : "microsoft/windows-drivers", - "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", - "locations" : [ { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - }, { - "name" : "legacy-upgrades", - "semanticVersion" : "0.0.0", - "locations" : [ { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - } ] - }, - "artifacts" : [ { - "location" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - } ], - "results" : [ { - "ruleId" : "cpp/drivers/no-paged-code", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/no-paged-code", - "index" : 0 - }, - "message" : { - "text" : "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 72, - "startColumn" : 10, - "endColumn" : 15 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "94d36694269ab444:1", - "primaryLocationStartColumnFingerprint" : "9" - } - }, { - "ruleId" : "cpp/drivers/no-paged-code", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/no-paged-code", - "index" : 0 - }, - "message" : { - "text" : "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 56, - "startColumn" : 10, - "endColumn" : 15 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "abeb76d8090a66a7:1", - "primaryLocationStartColumnFingerprint" : "9" - } - }, { - "ruleId" : "cpp/drivers/no-paged-code", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/no-paged-code", - "index" : 0 - }, - "message" : { - "text" : "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 42, - "endColumn" : 17 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "2b677663d4f4eaae:1", - "primaryLocationStartColumnFingerprint" : "0" - } - } ], - "columnKind" : "utf16CodeUnits", - "properties" : { - "semmle.formatSpecifier" : "sarifv2.1.0" - } - } ] +{ + "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", + "version" : "2.1.0", + "runs" : [ { + "tool" : { + "driver" : { + "name" : "CodeQL", + "organization" : "GitHub", + "semanticVersion" : "2.11.5", + "rules" : [ { + "id" : "cpp/drivers/no-paged-code", + "name" : "cpp/drivers/no-paged-code", + "shortDescription" : { + "text" : "No PAGED_CODE invocation" + }, + "fullDescription" : { + "text" : "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found. This can cause issues when debugging, using Code Analysis, or running on checked builds." + }, + "defaultConfiguration" : { + "enabled" : true, + "level" : "warning" + }, + "properties" : { + "tags" : [ "correctness", "wddst" ], + "description" : "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found. This can cause issues when debugging, using Code Analysis, or running on checked builds.", + "feature.area" : "Multiple", + "id" : "cpp/drivers/no-paged-code", + "impact" : "Insecure Coding Practice", + "kind" : "problem", + "name" : "No PAGED_CODE invocation", + "opaqueid" : "CQLD-C28170", + "owner.email" : "sdat@microsoft.com", + "platform" : "Desktop", + "precision" : "low", + "problem.severity" : "warning", + "query-version" : "v1", + "repro.text" : "The following code locations are duplicate PAGED_CODE() calls within a function.", + "scope" : "domainspecific", + "security.severity" : "Low" + } + } ] + }, + "extensions" : [ { + "name" : "microsoft/windows-drivers", + "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", + "locations" : [ { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + }, { + "name" : "legacy-upgrades", + "semanticVersion" : "0.0.0", + "locations" : [ { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + } ] + }, + "artifacts" : [ { + "location" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + } ], + "results" : [ { + "ruleId" : "cpp/drivers/no-paged-code", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/no-paged-code", + "index" : 0 + }, + "message" : { + "text" : "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 72, + "startColumn" : 10, + "endColumn" : 15 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "94d36694269ab444:1", + "primaryLocationStartColumnFingerprint" : "9" + } + }, { + "ruleId" : "cpp/drivers/no-paged-code", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/no-paged-code", + "index" : 0 + }, + "message" : { + "text" : "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 56, + "startColumn" : 10, + "endColumn" : 15 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "abeb76d8090a66a7:1", + "primaryLocationStartColumnFingerprint" : "9" + } + }, { + "ruleId" : "cpp/drivers/no-paged-code", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/no-paged-code", + "index" : 0 + }, + "message" : { + "text" : "The function has been declared to be in a paged segment, but neither PAGED_CODE nor PAGED_CODE_LOCKED was found." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 42, + "endColumn" : 17 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "2b677663d4f4eaae:1", + "primaryLocationStartColumnFingerprint" : "0" + } + } ], + "columnKind" : "utf16CodeUnits", + "properties" : { + "semmle.formatSpecifier" : "sarifv2.1.0" + } + } ] } \ No newline at end of file diff --git a/src/drivers/wdm/queries/NoPagedCode/driver_snippet.c b/codeql/src/drivers/wdm/queries/NoPagedCode/driver_snippet.c similarity index 94% rename from src/drivers/wdm/queries/NoPagedCode/driver_snippet.c rename to codeql/src/drivers/wdm/queries/NoPagedCode/driver_snippet.c index 903c70ab..b324a297 100644 --- a/src/drivers/wdm/queries/NoPagedCode/driver_snippet.c +++ b/codeql/src/drivers/wdm/queries/NoPagedCode/driver_snippet.c @@ -1,74 +1,74 @@ -// 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; +// 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; } \ No newline at end of file diff --git a/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.qhelp b/codeql/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.qhelp similarity index 97% rename from src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.qhelp rename to codeql/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.qhelp index e3b825e7..685ad550 100644 --- a/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.qhelp +++ b/codeql/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.qhelp @@ -1,24 +1,24 @@ - - - -

    - 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. -

    -
    - -

    - Put a function/routine that calls PAGED_CODE in a paged section using #pragma alloc_text or #pragma code_seg. -

    -
    - - - - -
  • - - C28172 warning - Windows Drivers - -
  • -
    -
    + + + +

    + 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. +

    +
    + +

    + Put a function/routine that calls PAGED_CODE in a paged section using #pragma alloc_text or #pragma code_seg. +

    +
    + + + + +
  • + + C28172 warning - Windows Drivers + +
  • +
    +
    diff --git a/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.ql b/codeql/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.ql similarity index 97% rename from src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.ql rename to codeql/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.ql index 566b110b..4a1fa0a5 100644 --- a/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.ql +++ b/codeql/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.ql @@ -1,34 +1,34 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -/** - * @id cpp/drivers/no-paged-code - * @name No paging segment for PAGED_CODE macro invocation - * @description The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment. This can cause issues when debugging, using Code Analysis, or running on checked builds. - * @platform Desktop - * @security.severity Low - * @feature.area Multiple - * @impact Insecure Coding Practice - * @repro.text The following code locations have PAGED_CODE() or PAGED_CODE_LOCKED() calls but they were not put in paged segments. - * @owner.email sdat@microsoft.com - * @opaqueid CQLD-C28172 - * @kind problem - * @problem.severity warning - * @precision low - * @tags correctness - * ca_ported - * wddst - * @scope domainspecific - * @query-version v1 - */ - -import cpp -import drivers.libraries.Page - -from PagedFunc pf -where - not pf instanceof FunctionWithPageSet and - not isPagedSegSetWithMacroAbove(pf) and - not isAllocUsedToLocatePagedFunc(pf) -select pf, - "The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment" +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +/** + * @id cpp/drivers/no-paged-code + * @name No paging segment for PAGED_CODE macro invocation + * @description The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment. This can cause issues when debugging, using Code Analysis, or running on checked builds. + * @platform Desktop + * @security.severity Low + * @feature.area Multiple + * @impact Insecure Coding Practice + * @repro.text The following code locations have PAGED_CODE() or PAGED_CODE_LOCKED() calls but they were not put in paged segments. + * @owner.email sdat@microsoft.com + * @opaqueid CQLD-C28172 + * @kind problem + * @problem.severity warning + * @precision low + * @tags correctness + * ca_ported + * wddst + * @scope domainspecific + * @query-version v1 + */ + +import cpp +import drivers.libraries.Page + +from PagedFunc pf +where + not pf instanceof FunctionWithPageSet and + not isPagedSegSetWithMacroAbove(pf) and + not isAllocUsedToLocatePagedFunc(pf) +select pf, + "The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment" \ No newline at end of file diff --git a/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.sarif b/codeql/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.sarif similarity index 97% rename from src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.sarif rename to codeql/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.sarif index acd7317f..348d3499 100644 --- a/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.sarif +++ b/codeql/src/drivers/wdm/queries/NoPagingSegment/NoPagingSegment.sarif @@ -1,141 +1,141 @@ -{ - "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", - "version" : "2.1.0", - "runs" : [ { - "tool" : { - "driver" : { - "name" : "CodeQL", - "organization" : "GitHub", - "semanticVersion" : "2.11.5", - "rules" : [ { - "id" : "cpp/drivers/no-paged-code", - "name" : "cpp/drivers/no-paged-code", - "shortDescription" : { - "text" : "No paging segment for PAGED_CODE macro invocation" - }, - "fullDescription" : { - "text" : "The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment. This can cause issues when debugging, using Code Analysis, or running on checked builds." - }, - "defaultConfiguration" : { - "enabled" : true, - "level" : "warning" - }, - "properties" : { - "tags" : [ "correctness", "wddst" ], - "description" : "The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment. This can cause issues when debugging, using Code Analysis, or running on checked builds.", - "feature.area" : "Multiple", - "id" : "cpp/drivers/no-paged-code", - "impact" : "Insecure Coding Practice", - "kind" : "problem", - "name" : "No paging segment for PAGED_CODE macro invocation", - "opaqueid" : "CQLD-C28172", - "owner.email" : "sdat@microsoft.com", - "platform" : "Desktop", - "precision" : "low", - "problem.severity" : "warning", - "query-version" : "v1", - "repro.text" : "The following code locations have PAGED_CODE() or PAGED_CODE_LOCKED() calls but they were not put in paged segments.", - "scope" : "domainspecific", - "security.severity" : "Low" - } - } ] - }, - "extensions" : [ { - "name" : "microsoft/windows-drivers", - "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", - "locations" : [ { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - }, { - "name" : "legacy-upgrades", - "semanticVersion" : "0.0.0", - "locations" : [ { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - } ] - }, - "artifacts" : [ { - "location" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - } ], - "results" : [ { - "ruleId" : "cpp/drivers/no-paged-code", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/no-paged-code", - "index" : 0 - }, - "message" : { - "text" : "The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment" - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 65, - "startColumn" : 10, - "endColumn" : 15 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "98adc396925ec049:1", - "primaryLocationStartColumnFingerprint" : "9" - } - }, { - "ruleId" : "cpp/drivers/no-paged-code", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/no-paged-code", - "index" : 0 - }, - "message" : { - "text" : "The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment" - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 41, - "endColumn" : 17 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "2b677663d4f4eaae:1", - "primaryLocationStartColumnFingerprint" : "0" - } - } ], - "columnKind" : "utf16CodeUnits", - "properties" : { - "semmle.formatSpecifier" : "sarifv2.1.0" - } - } ] +{ + "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", + "version" : "2.1.0", + "runs" : [ { + "tool" : { + "driver" : { + "name" : "CodeQL", + "organization" : "GitHub", + "semanticVersion" : "2.11.5", + "rules" : [ { + "id" : "cpp/drivers/no-paged-code", + "name" : "cpp/drivers/no-paged-code", + "shortDescription" : { + "text" : "No paging segment for PAGED_CODE macro invocation" + }, + "fullDescription" : { + "text" : "The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment. This can cause issues when debugging, using Code Analysis, or running on checked builds." + }, + "defaultConfiguration" : { + "enabled" : true, + "level" : "warning" + }, + "properties" : { + "tags" : [ "correctness", "wddst" ], + "description" : "The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment. This can cause issues when debugging, using Code Analysis, or running on checked builds.", + "feature.area" : "Multiple", + "id" : "cpp/drivers/no-paged-code", + "impact" : "Insecure Coding Practice", + "kind" : "problem", + "name" : "No paging segment for PAGED_CODE macro invocation", + "opaqueid" : "CQLD-C28172", + "owner.email" : "sdat@microsoft.com", + "platform" : "Desktop", + "precision" : "low", + "problem.severity" : "warning", + "query-version" : "v1", + "repro.text" : "The following code locations have PAGED_CODE() or PAGED_CODE_LOCKED() calls but they were not put in paged segments.", + "scope" : "domainspecific", + "security.severity" : "Low" + } + } ] + }, + "extensions" : [ { + "name" : "microsoft/windows-drivers", + "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", + "locations" : [ { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + }, { + "name" : "legacy-upgrades", + "semanticVersion" : "0.0.0", + "locations" : [ { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + } ] + }, + "artifacts" : [ { + "location" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + } ], + "results" : [ { + "ruleId" : "cpp/drivers/no-paged-code", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/no-paged-code", + "index" : 0 + }, + "message" : { + "text" : "The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment" + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 65, + "startColumn" : 10, + "endColumn" : 15 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "98adc396925ec049:1", + "primaryLocationStartColumnFingerprint" : "9" + } + }, { + "ruleId" : "cpp/drivers/no-paged-code", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/no-paged-code", + "index" : 0 + }, + "message" : { + "text" : "The function has PAGED_CODE or PAGED_CODE_LOCKED but is not declared to be in a paged segment" + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 41, + "endColumn" : 17 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "2b677663d4f4eaae:1", + "primaryLocationStartColumnFingerprint" : "0" + } + } ], + "columnKind" : "utf16CodeUnits", + "properties" : { + "semmle.formatSpecifier" : "sarifv2.1.0" + } + } ] } \ No newline at end of file diff --git a/src/drivers/wdm/queries/NoPagingSegment/driver_snippet.c b/codeql/src/drivers/wdm/queries/NoPagingSegment/driver_snippet.c similarity index 94% rename from src/drivers/wdm/queries/NoPagingSegment/driver_snippet.c rename to codeql/src/drivers/wdm/queries/NoPagingSegment/driver_snippet.c index d7ceb0cb..682d6b95 100644 --- a/src/drivers/wdm/queries/NoPagingSegment/driver_snippet.c +++ b/codeql/src/drivers/wdm/queries/NoPagingSegment/driver_snippet.c @@ -1,76 +1,76 @@ -// 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; +// 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; } \ No newline at end of file diff --git a/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.qhelp b/codeql/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.qhelp similarity index 100% rename from src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.qhelp rename to codeql/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.qhelp diff --git a/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.ql b/codeql/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.ql similarity index 100% rename from src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.ql rename to codeql/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.ql diff --git a/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.sarif b/codeql/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.sarif similarity index 100% rename from src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.sarif rename to codeql/src/drivers/wdm/queries/ObReferenceMode/ObReferenceMode.sarif diff --git a/src/drivers/wdm/queries/ObReferenceMode/driver_snippet.c b/codeql/src/drivers/wdm/queries/ObReferenceMode/driver_snippet.c similarity index 100% rename from src/drivers/wdm/queries/ObReferenceMode/driver_snippet.c rename to codeql/src/drivers/wdm/queries/ObReferenceMode/driver_snippet.c diff --git a/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.qhelp b/codeql/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.qhelp similarity index 100% rename from src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.qhelp rename to codeql/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.qhelp diff --git a/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.ql b/codeql/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.ql similarity index 100% rename from src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.ql rename to codeql/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.ql diff --git a/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.sarif b/codeql/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.sarif similarity index 100% rename from src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.sarif rename to codeql/src/drivers/wdm/queries/OpaqueMdlUse/OpaqueMdlUse.sarif diff --git a/src/drivers/wdm/queries/OpaqueMdlUse/driver_snippet.c b/codeql/src/drivers/wdm/queries/OpaqueMdlUse/driver_snippet.c similarity index 100% rename from src/drivers/wdm/queries/OpaqueMdlUse/driver_snippet.c rename to codeql/src/drivers/wdm/queries/OpaqueMdlUse/driver_snippet.c diff --git a/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.qhelp b/codeql/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.qhelp similarity index 100% rename from src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.qhelp rename to codeql/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.qhelp diff --git a/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.ql b/codeql/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.ql similarity index 100% rename from src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.ql rename to codeql/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.ql diff --git a/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.sarif b/codeql/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.sarif similarity index 100% rename from src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.sarif rename to codeql/src/drivers/wdm/queries/OpaqueMdlWrite/OpaqueMdlWrite.sarif diff --git a/src/drivers/wdm/queries/OpaqueMdlWrite/driver_snippet.c b/codeql/src/drivers/wdm/queries/OpaqueMdlWrite/driver_snippet.c similarity index 100% rename from src/drivers/wdm/queries/OpaqueMdlWrite/driver_snippet.c rename to codeql/src/drivers/wdm/queries/OpaqueMdlWrite/driver_snippet.c diff --git a/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.qhelp b/codeql/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.qhelp similarity index 100% rename from src/drivers/wdm/queries/PendingStatusError/PendingStatusError.qhelp rename to codeql/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.qhelp diff --git a/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.ql b/codeql/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.ql similarity index 97% rename from src/drivers/wdm/queries/PendingStatusError/PendingStatusError.ql rename to codeql/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.ql index 457f98d8..1ab52dbd 100644 --- a/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.ql +++ b/codeql/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.ql @@ -1,73 +1,73 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -/** - * @id cpp/drivers/pending-status-error - * @name Did not return STATUS_PENDING after IoMarkIrpPending call - * @description 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. For more information please refer C28143 Code Analysis rule. - * @platform Desktop - * @security.severity Low - * @feature.area Multiple - * @impact Insecure Coding Practice - * @repro.text The following code locations potentially contain IoMarkIrpPending calls that do not return STATUS_PENDING - * @owner.email sdat@microsoft.com - * @opaqueid CQLD-C28143 - * @kind problem - * @problem.severity warning - * @precision Low - * @tags correctness - * ca_ported - * wddst - * @scope domainspecific - * @query-version v1 - */ - -import cpp -import drivers.wdm.libraries.WdmDrivers - -//Represents elements with IO_COMPLETION_ROUTINE type -class IORoutineTypedef extends TypedefType { - IORoutineTypedef() { this.getName().matches("IO_COMPLETION_ROUTINE") } -} - -//Evaluates to true for IO_COMPLETION_ROUTINE type routines. -predicate isIOCompletionRoutine(Function f) { - exists(FunctionDeclarationEntry fde | - fde.getFunction() = f and - fde.getTypedefType() instanceof IORoutineTypedef - ) -} - -predicate returnsStatusPending(FunctionCall call) { - exists(ReturnStmt rs | - //259 is the integer representaion for STATUS_PENDING - ( - rs.getExpr().(Literal).getValue().toInt() = 259 and - call.getASuccessor*() = rs - or - exists(VariableAccess va1, AssignExpr ae, VariableAccess va2 | - ( - //STATUS_PENDING assignment can occur before or after the function call. - call.getEnclosingFunction() = ae.getEnclosingFunction() and - ( - call.getAPredecessor*() = ae - or - call.getASuccessor*() = ae - ) - ) and - ae.getRValue().(Literal).getValue().toInt() = 259 and - ae.getLValue() = va1 and - ae.getASuccessor*() = rs and - va2.getParent() = rs and - va2.getTarget().getName() = va1.getTarget().getName() - ) - ) - ) -} - -from FunctionCall call -where - call.getTarget().getName() = "IoMarkIrpPending" and - call.getEnclosingFunction() instanceof WdmDispatchRoutine and - not returnsStatusPending(call) and - not isIOCompletionRoutine(call.getEnclosingFunction()) -select call, "The return type should be STATUS_PENDING when making IoMarkIrpPending calls" +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +/** + * @id cpp/drivers/pending-status-error + * @name Did not return STATUS_PENDING after IoMarkIrpPending call + * @description 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. For more information please refer C28143 Code Analysis rule. + * @platform Desktop + * @security.severity Low + * @feature.area Multiple + * @impact Insecure Coding Practice + * @repro.text The following code locations potentially contain IoMarkIrpPending calls that do not return STATUS_PENDING + * @owner.email sdat@microsoft.com + * @opaqueid CQLD-C28143 + * @kind problem + * @problem.severity warning + * @precision Low + * @tags correctness + * ca_ported + * wddst + * @scope domainspecific + * @query-version v1 + */ + +import cpp +import drivers.wdm.libraries.WdmDrivers + +//Represents elements with IO_COMPLETION_ROUTINE type +class IORoutineTypedef extends TypedefType { + IORoutineTypedef() { this.getName().matches("IO_COMPLETION_ROUTINE") } +} + +//Evaluates to true for IO_COMPLETION_ROUTINE type routines. +predicate isIOCompletionRoutine(Function f) { + exists(FunctionDeclarationEntry fde | + fde.getFunction() = f and + fde.getTypedefType() instanceof IORoutineTypedef + ) +} + +predicate returnsStatusPending(FunctionCall call) { + exists(ReturnStmt rs | + //259 is the integer representaion for STATUS_PENDING + ( + rs.getExpr().(Literal).getValue().toInt() = 259 and + call.getASuccessor*() = rs + or + exists(VariableAccess va1, AssignExpr ae, VariableAccess va2 | + ( + //STATUS_PENDING assignment can occur before or after the function call. + call.getEnclosingFunction() = ae.getEnclosingFunction() and + ( + call.getAPredecessor*() = ae + or + call.getASuccessor*() = ae + ) + ) and + ae.getRValue().(Literal).getValue().toInt() = 259 and + ae.getLValue() = va1 and + ae.getASuccessor*() = rs and + va2.getParent() = rs and + va2.getTarget().getName() = va1.getTarget().getName() + ) + ) + ) +} + +from FunctionCall call +where + call.getTarget().getName() = "IoMarkIrpPending" and + call.getEnclosingFunction() instanceof WdmDispatchRoutine and + not returnsStatusPending(call) and + not isIOCompletionRoutine(call.getEnclosingFunction()) +select call, "The return type should be STATUS_PENDING when making IoMarkIrpPending calls" diff --git a/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.sarif b/codeql/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.sarif similarity index 97% rename from src/drivers/wdm/queries/PendingStatusError/PendingStatusError.sarif rename to codeql/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.sarif index 3c9fac0a..3a78df51 100644 --- a/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.sarif +++ b/codeql/src/drivers/wdm/queries/PendingStatusError/PendingStatusError.sarif @@ -1,114 +1,114 @@ -{ - "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", - "version" : "2.1.0", - "runs" : [ { - "tool" : { - "driver" : { - "name" : "CodeQL", - "organization" : "GitHub", - "semanticVersion" : "2.11.5", - "rules" : [ { - "id" : "cpp/drivers/pending-status-error", - "name" : "cpp/drivers/pending-status-error", - "shortDescription" : { - "text" : "Did not return STATUS_PENDING after IoMarkIrpPending call" - }, - "fullDescription" : { - "text" : "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. For more information please refer C28143 Code Analysis rule." - }, - "defaultConfiguration" : { - "enabled" : true, - "level" : "warning" - }, - "properties" : { - "tags" : [ "correctness", "wddst" ], - "description" : "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. For more information please refer C28143 Code Analysis rule.", - "feature.area" : "Multiple", - "id" : "cpp/drivers/pending-status-error", - "impact" : "Insecure Coding Practice", - "kind" : "problem", - "name" : "Did not return STATUS_PENDING after IoMarkIrpPending call", - "opaqueid" : "CQLD-C28143", - "owner.email" : "sdat@microsoft.com", - "platform" : "Desktop", - "precision" : "Low", - "problem.severity" : "warning", - "query-version" : "v1", - "repro.text" : "The following code locations potentially contain IoMarkIrpPending calls that do not return STATUS_PENDING", - "scope" : "domainspecific", - "security.severity" : "Low" - } - } ] - }, - "extensions" : [ { - "name" : "microsoft/windows-drivers", - "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", - "locations" : [ { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - }, { - "name" : "legacy-upgrades", - "semanticVersion" : "0.0.0", - "locations" : [ { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - } ] - }, - "artifacts" : [ { - "location" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - } ], - "results" : [ { - "ruleId" : "cpp/drivers/pending-status-error", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/pending-status-error", - "index" : 0 - }, - "message" : { - "text" : "The return type should be STATUS_PENDING when making IoMarkIrpPending calls" - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 57, - "startColumn" : 9, - "endColumn" : 25 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "53405033a4fa7dc4:1", - "primaryLocationStartColumnFingerprint" : "0" - } - } ], - "columnKind" : "utf16CodeUnits", - "properties" : { - "semmle.formatSpecifier" : "sarifv2.1.0" - } - } ] +{ + "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", + "version" : "2.1.0", + "runs" : [ { + "tool" : { + "driver" : { + "name" : "CodeQL", + "organization" : "GitHub", + "semanticVersion" : "2.11.5", + "rules" : [ { + "id" : "cpp/drivers/pending-status-error", + "name" : "cpp/drivers/pending-status-error", + "shortDescription" : { + "text" : "Did not return STATUS_PENDING after IoMarkIrpPending call" + }, + "fullDescription" : { + "text" : "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. For more information please refer C28143 Code Analysis rule." + }, + "defaultConfiguration" : { + "enabled" : true, + "level" : "warning" + }, + "properties" : { + "tags" : [ "correctness", "wddst" ], + "description" : "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. For more information please refer C28143 Code Analysis rule.", + "feature.area" : "Multiple", + "id" : "cpp/drivers/pending-status-error", + "impact" : "Insecure Coding Practice", + "kind" : "problem", + "name" : "Did not return STATUS_PENDING after IoMarkIrpPending call", + "opaqueid" : "CQLD-C28143", + "owner.email" : "sdat@microsoft.com", + "platform" : "Desktop", + "precision" : "Low", + "problem.severity" : "warning", + "query-version" : "v1", + "repro.text" : "The following code locations potentially contain IoMarkIrpPending calls that do not return STATUS_PENDING", + "scope" : "domainspecific", + "security.severity" : "Low" + } + } ] + }, + "extensions" : [ { + "name" : "microsoft/windows-drivers", + "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", + "locations" : [ { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + }, { + "name" : "legacy-upgrades", + "semanticVersion" : "0.0.0", + "locations" : [ { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + } ] + }, + "artifacts" : [ { + "location" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + } ], + "results" : [ { + "ruleId" : "cpp/drivers/pending-status-error", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/pending-status-error", + "index" : 0 + }, + "message" : { + "text" : "The return type should be STATUS_PENDING when making IoMarkIrpPending calls" + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 57, + "startColumn" : 9, + "endColumn" : 25 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "53405033a4fa7dc4:1", + "primaryLocationStartColumnFingerprint" : "0" + } + } ], + "columnKind" : "utf16CodeUnits", + "properties" : { + "semmle.formatSpecifier" : "sarifv2.1.0" + } + } ] } \ No newline at end of file diff --git a/src/drivers/wdm/queries/PendingStatusError/driver_snippet.c b/codeql/src/drivers/wdm/queries/PendingStatusError/driver_snippet.c similarity index 95% rename from src/drivers/wdm/queries/PendingStatusError/driver_snippet.c rename to codeql/src/drivers/wdm/queries/PendingStatusError/driver_snippet.c index 3506deb4..12611512 100644 --- a/src/drivers/wdm/queries/PendingStatusError/driver_snippet.c +++ b/codeql/src/drivers/wdm/queries/PendingStatusError/driver_snippet.c @@ -1,62 +1,62 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// -// driver_snippet.c -// - -//Macros to enable or disable a code section that may or maynot conflict with this test. -#define SET_PENDING 1 -#define SET_DISPATCH 1 - - -//Template. Not called in this test. -void top_level_call(){} - - -//Passing Case -_Dispatch_type_(IRP_MJ_SYSTEM_WRITE) -DRIVER_DISPATCH DispatchWrite; - -_Use_decl_annotations_ -NTSTATUS -DispatchWrite ( - PDEVICE_OBJECT DeviceObject, - PIRP Irp - ) -{ - - UNREFERENCED_PARAMETER(DeviceObject); - PAGED_CODE(); - NTSTATUS status; - - status = STATUS_PENDING; - //The call below represents a passing case for PendingStatusError. - IoMarkIrpPending(Irp); - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; -} - -//Failing Case -_Dispatch_type_(IRP_MJ_SET_INFORMATION) -DRIVER_DISPATCH DispatchSetInformation; - -_Use_decl_annotations_ -NTSTATUS -DispatchSetInformation ( - PDEVICE_OBJECT DeviceObject, - PIRP Irp - ) -{ - - UNREFERENCED_PARAMETER(DeviceObject); - NTSTATUS status; - //The condition doesn't matter. It's for testing. - if(TRUE){ - //The call below represents a failing case for PendingStatusError. - IoMarkIrpPending(Irp); - } - status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// +// driver_snippet.c +// + +//Macros to enable or disable a code section that may or maynot conflict with this test. +#define SET_PENDING 1 +#define SET_DISPATCH 1 + + +//Template. Not called in this test. +void top_level_call(){} + + +//Passing Case +_Dispatch_type_(IRP_MJ_SYSTEM_WRITE) +DRIVER_DISPATCH DispatchWrite; + +_Use_decl_annotations_ +NTSTATUS +DispatchWrite ( + PDEVICE_OBJECT DeviceObject, + PIRP Irp + ) +{ + + UNREFERENCED_PARAMETER(DeviceObject); + PAGED_CODE(); + NTSTATUS status; + + status = STATUS_PENDING; + //The call below represents a passing case for PendingStatusError. + IoMarkIrpPending(Irp); + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return status; +} + +//Failing Case +_Dispatch_type_(IRP_MJ_SET_INFORMATION) +DRIVER_DISPATCH DispatchSetInformation; + +_Use_decl_annotations_ +NTSTATUS +DispatchSetInformation ( + PDEVICE_OBJECT DeviceObject, + PIRP Irp + ) +{ + + UNREFERENCED_PARAMETER(DeviceObject); + NTSTATUS status; + //The condition doesn't matter. It's for testing. + if(TRUE){ + //The call below represents a failing case for PendingStatusError. + IoMarkIrpPending(Irp); + } + status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return status; +} diff --git a/src/drivers/wdm/queries/README.md b/codeql/src/drivers/wdm/queries/README.md similarity index 98% rename from src/drivers/wdm/queries/README.md rename to codeql/src/drivers/wdm/queries/README.md index cf307d49..4a07205f 100644 --- a/src/drivers/wdm/queries/README.md +++ b/codeql/src/drivers/wdm/queries/README.md @@ -1,7 +1,7 @@ -### The queries in general will have the following structure - -* PendingStatusError/ - - PendingStatusError.sarif -> Expected result of running PendingStatusError.ql on the sample database - - PendingStatusError.ql -> The query - - PendingStatusError.qhelp -> Query documentation using CodeQL styles +### The queries in general will have the following structure + +* PendingStatusError/ + - PendingStatusError.sarif -> Expected result of running PendingStatusError.ql on the sample database + - PendingStatusError.ql -> The query + - PendingStatusError.qhelp -> Query documentation using CodeQL styles - driver_snippet.c -> A test file containing passing and failing cases. \ No newline at end of file diff --git a/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.qhelp b/codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.qhelp similarity index 97% rename from src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.qhelp rename to codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.qhelp index 39d692fa..70f1b6af 100644 --- a/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.qhelp +++ b/codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.qhelp @@ -1,44 +1,44 @@ - - - -

    - 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.

    -
    - -

    - 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. -

    -
    - -

    - In this example, the driver has a DRIVER_DISPATCH routine that is not annotated with the type(s) of IRP it handles. -

    - MajorFunction[IRP_MJ_CREATE] = SampleCreate; - ]]> - -

    - The driver should instead annotate its dispatch routines appropriately. -

    - MajorFunction[IRP_MJ_CREATE] = SampleCreate;... - ]]> - -
    - -
  • - - C28168 warning - Windows Drivers - -
  • -
  • - - C28169 warning - Windows Drivers - -
  • -
    -
    + + + +

    + 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.

    +
    + +

    + 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. +

    +
    + +

    + In this example, the driver has a DRIVER_DISPATCH routine that is not annotated with the type(s) of IRP it handles. +

    + MajorFunction[IRP_MJ_CREATE] = SampleCreate; + ]]> + +

    + The driver should instead annotate its dispatch routines appropriately. +

    + MajorFunction[IRP_MJ_CREATE] = SampleCreate;... + ]]> + +
    + +
  • + + C28168 warning - Windows Drivers + +
  • +
  • + + C28169 warning - Windows Drivers + +
  • +
    +
    diff --git a/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.ql b/codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.ql similarity index 97% rename from src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.ql rename to codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.ql index e8204ba4..b91271c6 100644 --- a/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.ql +++ b/codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.ql @@ -1,95 +1,95 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -/** - * @id cpp/drivers/wrong-dispatch-table-assignment - * @name Incorrect dispatch table assignment - * @description The dispatch table assignment satisfies either 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. - * @platform Desktop - * @security.severity Low - * @feature.area Multiple - * @impact Exploitable design - * @repro.text The following lines of code may potentially contain incorrect assignment to dispatch table entry. - * @owner.email sdat@microsoft.com - * @opaqueid CQLD-D0003 - * @kind problem - * @problem.severity recommendation - * @precision Low - * @tags correctness - * wddst - * @scope domainspecific - * @query-version v1 - */ - -import cpp -import drivers.wdm.libraries.WdmDrivers -import drivers.libraries.SAL - -//Evaluates to true for AssignExpr for whom the right hand side evaluates to a FunctionAccess whose target is -//a WdmDispatchRoutine but its dispatch type annotation doesn't match the dispatch table entry -predicate dispatchAnnotationMismatched(AssignExpr ae) { - exists(DispatchTypeDefinition dmi, WdmDispatchRoutine wdr, FunctionAccess faa | - ae.getRValue().(FunctionAccess) = faa and - faa.getTarget() = wdr and - dmi.getDeclarationEntry() = wdr.getADeclarationEntry() and - not wdr.matchesAnnotation(dmi) - ) -} - -//Evaluates to true if a given assignment, recursively, has a WdmDispatchRoutine callback routine as the right hand side -predicate dispatchRoutineExists(AssignExpr ae) { - exists(FunctionAccess fa | - ae.getRValue() = fa and - fa.getTarget() instanceof WdmDispatchRoutine - ) - or - ae.getRValue() instanceof AssignExpr and - dispatchRoutineExists(ae.getRValue().(AssignExpr)) -} - -//Represents dispatch table AssignExpr whose right hand side is not a funtion of type DRIVER_DISPATCH -class NonDispatchFunction extends AssignExpr { - NonDispatchFunction() { - exists( - ArrayExpr dispatchTable, PointerFieldAccess fieldAccess, VariableAccess driverObjectAccess - | - this.getLValue() = dispatchTable and - not dispatchRoutineExists(this) and - dispatchTable.getArrayBase() = fieldAccess and - fieldAccess.getQualifier() = driverObjectAccess and - driverObjectAccess.getTarget().getType().getName().matches("PDRIVER_OBJECT") and - this.getEnclosingFunction() instanceof WdmDriverEntry - ) - } -} - -//Evaluates to true for a dispatch table assignment where the dispatch function doesn't have annotation matching "this" dispatch table entry. -predicate dispatchAnnotationMissing(AssignExpr ae) { - exists(CallbackRoutineAssignment cra, WdmDispatchRoutine dr | - ae = cra and - cra.getTarget() = dr and - not exists(DispatchTypeDefinition dmi | dmi.getDeclarationEntry() = dr.getADeclarationEntry()) - ) -} - -//Represents AssignExpr that satisfy either of the three scenarios given below -class WrongDispatchFunctionAssignments extends AssignExpr { - string message; - - WrongDispatchFunctionAssignments() { - this instanceof NonDispatchFunction and - message = - "Dispatch table assignment should have a DRIVER_DISPATCH type routine as its right-hand side value." - or - dispatchAnnotationMissing(this) and - message = "The dispatch function does not have a dispatch type annotation." - or - dispatchAnnotationMismatched(this) and - message = - "The dispatch function does not have a dispatch type annotation matching this dispatch table entry." - } - - string getMessage() { result = message } -} - -from WrongDispatchFunctionAssignments wdfa -select wdfa, wdfa.getMessage() +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +/** + * @id cpp/drivers/wrong-dispatch-table-assignment + * @name Incorrect dispatch table assignment + * @description The dispatch table assignment satisfies either 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. + * @platform Desktop + * @security.severity Low + * @feature.area Multiple + * @impact Exploitable design + * @repro.text The following lines of code may potentially contain incorrect assignment to dispatch table entry. + * @owner.email sdat@microsoft.com + * @opaqueid CQLD-D0003 + * @kind problem + * @problem.severity recommendation + * @precision Low + * @tags correctness + * wddst + * @scope domainspecific + * @query-version v1 + */ + +import cpp +import drivers.wdm.libraries.WdmDrivers +import drivers.libraries.SAL + +//Evaluates to true for AssignExpr for whom the right hand side evaluates to a FunctionAccess whose target is +//a WdmDispatchRoutine but its dispatch type annotation doesn't match the dispatch table entry +predicate dispatchAnnotationMismatched(AssignExpr ae) { + exists(DispatchTypeDefinition dmi, WdmDispatchRoutine wdr, FunctionAccess faa | + ae.getRValue().(FunctionAccess) = faa and + faa.getTarget() = wdr and + dmi.getDeclarationEntry() = wdr.getADeclarationEntry() and + not wdr.matchesAnnotation(dmi) + ) +} + +//Evaluates to true if a given assignment, recursively, has a WdmDispatchRoutine callback routine as the right hand side +predicate dispatchRoutineExists(AssignExpr ae) { + exists(FunctionAccess fa | + ae.getRValue() = fa and + fa.getTarget() instanceof WdmDispatchRoutine + ) + or + ae.getRValue() instanceof AssignExpr and + dispatchRoutineExists(ae.getRValue().(AssignExpr)) +} + +//Represents dispatch table AssignExpr whose right hand side is not a funtion of type DRIVER_DISPATCH +class NonDispatchFunction extends AssignExpr { + NonDispatchFunction() { + exists( + ArrayExpr dispatchTable, PointerFieldAccess fieldAccess, VariableAccess driverObjectAccess + | + this.getLValue() = dispatchTable and + not dispatchRoutineExists(this) and + dispatchTable.getArrayBase() = fieldAccess and + fieldAccess.getQualifier() = driverObjectAccess and + driverObjectAccess.getTarget().getType().getName().matches("PDRIVER_OBJECT") and + this.getEnclosingFunction() instanceof WdmDriverEntry + ) + } +} + +//Evaluates to true for a dispatch table assignment where the dispatch function doesn't have annotation matching "this" dispatch table entry. +predicate dispatchAnnotationMissing(AssignExpr ae) { + exists(CallbackRoutineAssignment cra, WdmDispatchRoutine dr | + ae = cra and + cra.getTarget() = dr and + not exists(DispatchTypeDefinition dmi | dmi.getDeclarationEntry() = dr.getADeclarationEntry()) + ) +} + +//Represents AssignExpr that satisfy either of the three scenarios given below +class WrongDispatchFunctionAssignments extends AssignExpr { + string message; + + WrongDispatchFunctionAssignments() { + this instanceof NonDispatchFunction and + message = + "Dispatch table assignment should have a DRIVER_DISPATCH type routine as its right-hand side value." + or + dispatchAnnotationMissing(this) and + message = "The dispatch function does not have a dispatch type annotation." + or + dispatchAnnotationMismatched(this) and + message = + "The dispatch function does not have a dispatch type annotation matching this dispatch table entry." + } + + string getMessage() { result = message } +} + +from WrongDispatchFunctionAssignments wdfa +select wdfa, wdfa.getMessage() diff --git a/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.sarif b/codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.sarif similarity index 97% rename from src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.sarif rename to codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.sarif index b354bf5d..28227ab4 100644 --- a/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.sarif +++ b/codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/WrongDispatchTableAssignment.sarif @@ -1,170 +1,170 @@ -{ - "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", - "version" : "2.1.0", - "runs" : [ { - "tool" : { - "driver" : { - "name" : "CodeQL", - "organization" : "GitHub", - "semanticVersion" : "2.11.5", - "rules" : [ { - "id" : "cpp/drivers/wrong-dispatch-table-assignment", - "name" : "cpp/drivers/wrong-dispatch-table-assignment", - "shortDescription" : { - "text" : "Incorrect dispatch table assignment" - }, - "fullDescription" : { - "text" : "The dispatch table assignment satisfies either 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." - }, - "defaultConfiguration" : { - "enabled" : true, - "level" : "warning" - }, - "properties" : { - "tags" : [ "correctness", "wddst" ], - "description" : "The dispatch table assignment satisfies either 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.", - "feature.area" : "Multiple", - "id" : "cpp/drivers/wrong-dispatch-table-assignment", - "impact" : "Exploitable design", - "kind" : "problem", - "name" : "Incorrect dispatch table assignment", - "opaqueid" : "CQLD-D0003", - "owner.email" : "sdat@microsoft.com", - "platform" : "Desktop", - "precision" : "Low", - "problem.severity" : "warning", - "query-version" : "v1", - "repro.text" : "The following lines of code may potentially contain incorrect assignment to dispatch table entry.", - "scope" : "domainspecific", - "security.severity" : "Low" - } - } ] - }, - "extensions" : [ { - "name" : "microsoft/windows-drivers", - "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", - "locations" : [ { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - }, { - "name" : "legacy-upgrades", - "semanticVersion" : "0.0.0", - "locations" : [ { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - } ] - }, - "artifacts" : [ { - "location" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - } ], - "results" : [ { - "ruleId" : "cpp/drivers/wrong-dispatch-table-assignment", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/wrong-dispatch-table-assignment", - "index" : 0 - }, - "message" : { - "text" : "The dispatch function does not have a dispatch type annotation matching this dispatch table entry." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 63, - "startColumn" : 5, - "endColumn" : 92 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "2fec3da094885e8a:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/wrong-dispatch-table-assignment", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/wrong-dispatch-table-assignment", - "index" : 0 - }, - "message" : { - "text" : "Dispatch table assignment should have a DRIVER_DISPATCH type routine as its right-hand side value." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 64, - "startColumn" : 5, - "endColumn" : 90 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "8b6f17daca28a190:1", - "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/wrong-dispatch-table-assignment", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/wrong-dispatch-table-assignment", - "index" : 0 - }, - "message" : { - "text" : "The dispatch function does not have a dispatch type annotation." - }, - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - }, - "region" : { - "startLine" : 67, - "startColumn" : 5, - "endColumn" : 89 - } - } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "aa91e7d0d2a92d50:1", - "primaryLocationStartColumnFingerprint" : "0" - } - } ], - "columnKind" : "utf16CodeUnits", - "properties" : { - "semmle.formatSpecifier" : "sarifv2.1.0" - } - } ] +{ + "$schema" : "https://json.schemastore.org/sarif-2.1.0.json", + "version" : "2.1.0", + "runs" : [ { + "tool" : { + "driver" : { + "name" : "CodeQL", + "organization" : "GitHub", + "semanticVersion" : "2.11.5", + "rules" : [ { + "id" : "cpp/drivers/wrong-dispatch-table-assignment", + "name" : "cpp/drivers/wrong-dispatch-table-assignment", + "shortDescription" : { + "text" : "Incorrect dispatch table assignment" + }, + "fullDescription" : { + "text" : "The dispatch table assignment satisfies either 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." + }, + "defaultConfiguration" : { + "enabled" : true, + "level" : "warning" + }, + "properties" : { + "tags" : [ "correctness", "wddst" ], + "description" : "The dispatch table assignment satisfies either 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.", + "feature.area" : "Multiple", + "id" : "cpp/drivers/wrong-dispatch-table-assignment", + "impact" : "Exploitable design", + "kind" : "problem", + "name" : "Incorrect dispatch table assignment", + "opaqueid" : "CQLD-D0003", + "owner.email" : "sdat@microsoft.com", + "platform" : "Desktop", + "precision" : "Low", + "problem.severity" : "warning", + "query-version" : "v1", + "repro.text" : "The following lines of code may potentially contain incorrect assignment to dispatch table entry.", + "scope" : "domainspecific", + "security.severity" : "Low" + } + } ] + }, + "extensions" : [ { + "name" : "microsoft/windows-drivers", + "semanticVersion" : "0.1.0+933e876f096a70922173e4d5ad604d99d4481af4", + "locations" : [ { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + }, { + "name" : "legacy-upgrades", + "semanticVersion" : "0.0.0", + "locations" : [ { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/", + "description" : { + "text" : "The QL pack root directory." + } + }, { + "uri" : "file:///C:/codeql-home/codeql/legacy-upgrades/qlpack.yml", + "description" : { + "text" : "The QL pack definition file." + } + } ] + } ] + }, + "artifacts" : [ { + "location" : { + "uri" : "driver/fail_driver1.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + } + } ], + "results" : [ { + "ruleId" : "cpp/drivers/wrong-dispatch-table-assignment", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/wrong-dispatch-table-assignment", + "index" : 0 + }, + "message" : { + "text" : "The dispatch function does not have a dispatch type annotation matching this dispatch table entry." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/fail_driver1.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 63, + "startColumn" : 5, + "endColumn" : 92 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "2fec3da094885e8a:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/wrong-dispatch-table-assignment", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/wrong-dispatch-table-assignment", + "index" : 0 + }, + "message" : { + "text" : "Dispatch table assignment should have a DRIVER_DISPATCH type routine as its right-hand side value." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/fail_driver1.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 64, + "startColumn" : 5, + "endColumn" : 90 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "8b6f17daca28a190:1", + "primaryLocationStartColumnFingerprint" : "0" + } + }, { + "ruleId" : "cpp/drivers/wrong-dispatch-table-assignment", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/wrong-dispatch-table-assignment", + "index" : 0 + }, + "message" : { + "text" : "The dispatch function does not have a dispatch type annotation." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/fail_driver1.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 67, + "startColumn" : 5, + "endColumn" : 89 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "aa91e7d0d2a92d50:1", + "primaryLocationStartColumnFingerprint" : "0" + } + } ], + "columnKind" : "utf16CodeUnits", + "properties" : { + "semmle.formatSpecifier" : "sarifv2.1.0" + } + } ] } \ No newline at end of file diff --git a/src/drivers/wdm/queries/WrongDispatchTableAssignment/driver_snippet.c b/codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/driver_snippet.c similarity index 95% rename from src/drivers/wdm/queries/WrongDispatchTableAssignment/driver_snippet.c rename to codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/driver_snippet.c index 320f17ba..bcdd37fe 100644 --- a/src/drivers/wdm/queries/WrongDispatchTableAssignment/driver_snippet.c +++ b/codeql/src/drivers/wdm/queries/WrongDispatchTableAssignment/driver_snippet.c @@ -1,26 +1,26 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - - -//Fails: missing SAL annotation -DRIVER_DISPATCH DispatchPnp; - -//Fails: annotation mismatch -_Dispatch_type_(IRP_MJ_CLOSE) -DRIVER_DISPATCH DispatchCreate; - -//Fails: since the expected SAL annotation for IRP_% types is _Dispatch_type_ -_Function_class_(IRP_MJ_READ) -_Function_class_(DRIVER_DISPATCH) -NTSTATUS -DispatchRead ( - _In_ PDEVICE_OBJECT DeviceObject, - _Inout_ PIRP Irp - ); - -//Passs -_Dispatch_type_(IRP_MN_CANCEL_REMOVE_DEVICE) -_Dispatch_type_(IRP_MN_CANCEL_STOP_DEVICE) -DRIVER_DISPATCH DispatchCancel; - -void top_level_call(){} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + + +//Fails: missing SAL annotation +DRIVER_DISPATCH DispatchPnp; + +//Fails: annotation mismatch +_Dispatch_type_(IRP_MJ_CLOSE) +DRIVER_DISPATCH DispatchCreate; + +//Fails: since the expected SAL annotation for IRP_% types is _Dispatch_type_ +_Function_class_(IRP_MJ_READ) +_Function_class_(DRIVER_DISPATCH) +NTSTATUS +DispatchRead ( + _In_ PDEVICE_OBJECT DeviceObject, + _Inout_ PIRP Irp + ); + +//Passs +_Dispatch_type_(IRP_MN_CANCEL_REMOVE_DEVICE) +_Dispatch_type_(IRP_MN_CANCEL_STOP_DEVICE) +DRIVER_DISPATCH DispatchCancel; + +void top_level_call(){} diff --git a/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.qhelp b/codeql/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.qhelp similarity index 100% rename from src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.qhelp rename to codeql/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.qhelp diff --git a/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.ql b/codeql/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.ql similarity index 100% rename from src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.ql rename to codeql/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosure.ql diff --git a/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosureBadCode.c b/codeql/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosureBadCode.c similarity index 100% rename from src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosureBadCode.c rename to codeql/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosureBadCode.c diff --git a/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosureGoodCode.c b/codeql/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosureGoodCode.c similarity index 100% rename from src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosureGoodCode.c rename to codeql/src/microsoft/Likely Bugs/Boundary Violations/PaddingByteInformationDisclosureGoodCode.c diff --git a/src/microsoft/Likely Bugs/Conversion/BadOverflowGuard.qhelp b/codeql/src/microsoft/Likely Bugs/Conversion/BadOverflowGuard.qhelp similarity index 100% rename from src/microsoft/Likely Bugs/Conversion/BadOverflowGuard.qhelp rename to codeql/src/microsoft/Likely Bugs/Conversion/BadOverflowGuard.qhelp diff --git a/src/microsoft/Likely Bugs/Conversion/BadOverflowGuard.ql b/codeql/src/microsoft/Likely Bugs/Conversion/BadOverflowGuard.ql similarity index 100% rename from src/microsoft/Likely Bugs/Conversion/BadOverflowGuard.ql rename to codeql/src/microsoft/Likely Bugs/Conversion/BadOverflowGuard.ql diff --git a/src/microsoft/Likely Bugs/Conversion/BadOverflowGuardBadCode.c b/codeql/src/microsoft/Likely Bugs/Conversion/BadOverflowGuardBadCode.c similarity index 100% rename from src/microsoft/Likely Bugs/Conversion/BadOverflowGuardBadCode.c rename to codeql/src/microsoft/Likely Bugs/Conversion/BadOverflowGuardBadCode.c diff --git a/src/microsoft/Likely Bugs/Conversion/BadOverflowGuardGoodCode.c b/codeql/src/microsoft/Likely Bugs/Conversion/BadOverflowGuardGoodCode.c similarity index 100% rename from src/microsoft/Likely Bugs/Conversion/BadOverflowGuardGoodCode.c rename to codeql/src/microsoft/Likely Bugs/Conversion/BadOverflowGuardGoodCode.c diff --git a/src/microsoft/Likely Bugs/Conversion/InfiniteLoop.qhelp b/codeql/src/microsoft/Likely Bugs/Conversion/InfiniteLoop.qhelp similarity index 100% rename from src/microsoft/Likely Bugs/Conversion/InfiniteLoop.qhelp rename to codeql/src/microsoft/Likely Bugs/Conversion/InfiniteLoop.qhelp diff --git a/src/microsoft/Likely Bugs/Conversion/InfiniteLoop.ql b/codeql/src/microsoft/Likely Bugs/Conversion/InfiniteLoop.ql similarity index 100% rename from src/microsoft/Likely Bugs/Conversion/InfiniteLoop.ql rename to codeql/src/microsoft/Likely Bugs/Conversion/InfiniteLoop.ql diff --git a/src/microsoft/Likely Bugs/Conversion/InfiniteLoopBadCode.c b/codeql/src/microsoft/Likely Bugs/Conversion/InfiniteLoopBadCode.c similarity index 100% rename from src/microsoft/Likely Bugs/Conversion/InfiniteLoopBadCode.c rename to codeql/src/microsoft/Likely Bugs/Conversion/InfiniteLoopBadCode.c diff --git a/src/microsoft/Likely Bugs/Conversion/InfiniteLoopGoodCode.c b/codeql/src/microsoft/Likely Bugs/Conversion/InfiniteLoopGoodCode.c similarity index 100% rename from src/microsoft/Likely Bugs/Conversion/InfiniteLoopGoodCode.c rename to codeql/src/microsoft/Likely Bugs/Conversion/InfiniteLoopGoodCode.c diff --git a/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.qhelp b/codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.qhelp similarity index 100% rename from src/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.qhelp rename to codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.qhelp diff --git a/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.ql b/codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.ql similarity index 100% rename from src/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.ql rename to codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/ProbableUseAfterFree.ql diff --git a/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.qhelp b/codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.qhelp similarity index 100% rename from src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.qhelp rename to codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.qhelp diff --git a/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.ql b/codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.ql similarity index 100% rename from src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.ql rename to codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree.ql diff --git a/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFreeLib.qhelp b/codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFreeLib.qhelp similarity index 100% rename from src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFreeLib.qhelp rename to codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFreeLib.qhelp diff --git a/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFreeLib.qll b/codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFreeLib.qll similarity index 100% rename from src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFreeLib.qll rename to codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFreeLib.qll diff --git a/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree_bad.c b/codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree_bad.c similarity index 100% rename from src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree_bad.c rename to codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree_bad.c diff --git a/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree_good.c b/codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree_good.c similarity index 100% rename from src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree_good.c rename to codeql/src/microsoft/Likely Bugs/Memory Management/UseAfterFree/UseAfterFree_good.c diff --git a/src/microsoft/Likely Bugs/UninitializedPtrField.qhelp b/codeql/src/microsoft/Likely Bugs/UninitializedPtrField.qhelp similarity index 100% rename from src/microsoft/Likely Bugs/UninitializedPtrField.qhelp rename to codeql/src/microsoft/Likely Bugs/UninitializedPtrField.qhelp diff --git a/src/microsoft/Likely Bugs/UninitializedPtrField.ql b/codeql/src/microsoft/Likely Bugs/UninitializedPtrField.ql similarity index 100% rename from src/microsoft/Likely Bugs/UninitializedPtrField.ql rename to codeql/src/microsoft/Likely Bugs/UninitializedPtrField.ql diff --git a/src/microsoft/Likely Bugs/UninitializedPtrFieldBadCode.c b/codeql/src/microsoft/Likely Bugs/UninitializedPtrFieldBadCode.c similarity index 100% rename from src/microsoft/Likely Bugs/UninitializedPtrFieldBadCode.c rename to codeql/src/microsoft/Likely Bugs/UninitializedPtrFieldBadCode.c diff --git a/src/microsoft/Likely Bugs/UninitializedPtrFieldGoodCode.c b/codeql/src/microsoft/Likely Bugs/UninitializedPtrFieldGoodCode.c similarity index 100% rename from src/microsoft/Likely Bugs/UninitializedPtrFieldGoodCode.c rename to codeql/src/microsoft/Likely Bugs/UninitializedPtrFieldGoodCode.c diff --git a/src/microsoft/Security/CWE/CWE-704/WcharCharConversion.cpp b/codeql/src/microsoft/Security/CWE/CWE-704/WcharCharConversion.cpp similarity index 100% rename from src/microsoft/Security/CWE/CWE-704/WcharCharConversion.cpp rename to codeql/src/microsoft/Security/CWE/CWE-704/WcharCharConversion.cpp diff --git a/src/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.qhelp b/codeql/src/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.qhelp similarity index 100% rename from src/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.qhelp rename to codeql/src/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.qhelp diff --git a/src/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.ql b/codeql/src/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.ql similarity index 100% rename from src/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.ql rename to codeql/src/microsoft/Security/CWE/CWE-704/WcharCharConversionLimited.ql diff --git a/src/microsoft/Security/Crytpography/HardcodedIVCNG.qhelp b/codeql/src/microsoft/Security/Crytpography/HardcodedIVCNG.qhelp similarity index 100% rename from src/microsoft/Security/Crytpography/HardcodedIVCNG.qhelp rename to codeql/src/microsoft/Security/Crytpography/HardcodedIVCNG.qhelp diff --git a/src/microsoft/Security/Crytpography/HardcodedIVCNG.ql b/codeql/src/microsoft/Security/Crytpography/HardcodedIVCNG.ql similarity index 100% rename from src/microsoft/Security/Crytpography/HardcodedIVCNG.ql rename to codeql/src/microsoft/Security/Crytpography/HardcodedIVCNG.ql diff --git a/src/microsoft/commons/Literals.qll b/codeql/src/microsoft/commons/Literals.qll similarity index 100% rename from src/microsoft/commons/Literals.qll rename to codeql/src/microsoft/commons/Literals.qll diff --git a/src/microsoft/commons/MemoryAllocation.qll b/codeql/src/microsoft/commons/MemoryAllocation.qll similarity index 100% rename from src/microsoft/commons/MemoryAllocation.qll rename to codeql/src/microsoft/commons/MemoryAllocation.qll diff --git a/src/qlpack.yml b/codeql/src/qlpack.yml similarity index 100% rename from src/qlpack.yml rename to codeql/src/qlpack.yml diff --git a/src/windows-driver-suites/mustfix.qls b/codeql/src/windows-driver-suites/mustfix.qls similarity index 100% rename from src/windows-driver-suites/mustfix.qls rename to codeql/src/windows-driver-suites/mustfix.qls diff --git a/src/windows-driver-suites/mustrun.qls b/codeql/src/windows-driver-suites/mustrun.qls similarity index 100% rename from src/windows-driver-suites/mustrun.qls rename to codeql/src/windows-driver-suites/mustrun.qls diff --git a/src/windows-driver-suites/ported_driver_ca_checks.qls b/codeql/src/windows-driver-suites/ported_driver_ca_checks.qls similarity index 100% rename from src/windows-driver-suites/ported_driver_ca_checks.qls rename to codeql/src/windows-driver-suites/ported_driver_ca_checks.qls diff --git a/src/windows-driver-suites/recommended.qls b/codeql/src/windows-driver-suites/recommended.qls similarity index 100% rename from src/windows-driver-suites/recommended.qls rename to codeql/src/windows-driver-suites/recommended.qls diff --git a/src/drivers/test/diff/IrqlNotSaved.sarif b/src/drivers/test/diff/IrqlNotSaved.sarif deleted file mode 100644 index 8d5a80f9..00000000 --- a/src/drivers/test/diff/IrqlNotSaved.sarif +++ /dev/null @@ -1,21 +0,0 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } -} \ No newline at end of file diff --git a/src/drivers/test/diff/IrqlNotUsed.sarif b/src/drivers/test/diff/IrqlNotUsed.sarif deleted file mode 100644 index 8d5a80f9..00000000 --- a/src/drivers/test/diff/IrqlNotUsed.sarif +++ /dev/null @@ -1,21 +0,0 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } -} \ No newline at end of file diff --git a/src/drivers/test/diff/IrqlSetTooHigh.sarif b/src/drivers/test/diff/IrqlSetTooHigh.sarif deleted file mode 100644 index 8d5a80f9..00000000 --- a/src/drivers/test/diff/IrqlSetTooHigh.sarif +++ /dev/null @@ -1,21 +0,0 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } -} \ No newline at end of file diff --git a/src/drivers/test/diff/IrqlTooHigh.sarif b/src/drivers/test/diff/IrqlTooHigh.sarif deleted file mode 100644 index 8d5a80f9..00000000 --- a/src/drivers/test/diff/IrqlTooHigh.sarif +++ /dev/null @@ -1,21 +0,0 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } -} \ No newline at end of file diff --git a/src/drivers/test/diff/IrqlTooLow.sarif b/src/drivers/test/diff/IrqlTooLow.sarif deleted file mode 100644 index 8d5a80f9..00000000 --- a/src/drivers/test/diff/IrqlTooLow.sarif +++ /dev/null @@ -1,21 +0,0 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } -} \ No newline at end of file diff --git a/src/drivers/test/diff/KeWaitLocal.sarif b/src/drivers/test/diff/KeWaitLocal.sarif deleted file mode 100644 index 8d5a80f9..00000000 --- a/src/drivers/test/diff/KeWaitLocal.sarif +++ /dev/null @@ -1,21 +0,0 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } -} \ No newline at end of file diff --git a/src/drivers/test/diff/MultiplePagedCode.sarif b/src/drivers/test/diff/MultiplePagedCode.sarif deleted file mode 100644 index 8d5a80f9..00000000 --- a/src/drivers/test/diff/MultiplePagedCode.sarif +++ /dev/null @@ -1,21 +0,0 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } -} \ No newline at end of file diff --git a/src/drivers/test/diff/NoPagedCode.sarif b/src/drivers/test/diff/NoPagedCode.sarif deleted file mode 100644 index 8d5a80f9..00000000 --- a/src/drivers/test/diff/NoPagedCode.sarif +++ /dev/null @@ -1,21 +0,0 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } -} \ No newline at end of file diff --git a/src/drivers/test/diff/NoPagingSegment.sarif b/src/drivers/test/diff/NoPagingSegment.sarif deleted file mode 100644 index 8d5a80f9..00000000 --- a/src/drivers/test/diff/NoPagingSegment.sarif +++ /dev/null @@ -1,21 +0,0 @@ -{ - "all": { - "+": 0, - "-": 0 - }, - "error": { - "+": 0, - "-": 0, - "codes": [] - }, - "warning": { - "+": 0, - "-": 0, - "codes": [] - }, - "note": { - "+": 0, - "-": 0, - "codes": [] - } -} \ No newline at end of file diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.projitems b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.projitems new file mode 100644 index 00000000..9c35b4da --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.projitems @@ -0,0 +1,53 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + b700bd9e-9b3e-4e3f-b6da-36591d7c83b8 + + + CodeQL.VisualStudio.Core + + + + + + + CodeQLGeneralOptionsControl.xaml + + + + CodeQLInstallHelper.xaml + + + + + + + InstallWindow.xaml + + + + + + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + + + Designer + PublicResXFileCodeGenerator + + + \ No newline at end of file diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.shproj b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.shproj new file mode 100644 index 00000000..099c7903 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.shproj @@ -0,0 +1,13 @@ + + + + b700bd9e-9b3e-4e3f-b6da-36591d7c83b8 + 14.0 + + + + + + + + diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLCommand.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLCommand.cs new file mode 100644 index 00000000..1c00cf51 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLCommand.cs @@ -0,0 +1,387 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.ComponentModel.Design; +using System.Diagnostics; +using System.Linq; +using System.Linq.Expressions; +using System.Runtime.InteropServices; +using System.Security.Policy; +using System.Threading.Tasks; + +using Microsoft.CodeQL.Options; +using Microsoft.CodeQL.Controls; +using Microsoft.CodeQL.Views; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Threading; + + +namespace Microsoft.CodeQL.Core +{ + internal class CodeQLCommand + { + /// + /// Command ID for CodeQL analyze. + /// + public const int CodeQLAnalyzeCommandId = 0x0100; + + /// + /// Command ID for CodeQL kill process. + /// + public const int CodeQLStopCommandId = 0x0110; + + /// + /// Command ID for CodeQL load queries. + /// + public const int CodeQLLoadQueriesCommandId = 0x0111; + + /// + /// Command ID for CodeQL install packs. + /// + public const int CodeQLInstallerCommandID = 0x0112; + + /// + /// Command ID for CodeQL database create. + /// + public const int CodeQLDatabaseCommandId = 0x133; + + /// + /// Command ID for CodeQL combo box. + /// + public const int CodeQLComboId = 0x155; + + /// + /// Command ID for CodeQL combo box get list. + /// + public const int ComboGetListId = 0x156; + + /// + /// Command menu group (command set GUID). + /// + public static readonly Guid CommandSet = new Guid("4fc96981-3ec2-43c7-acf0-96d73b1203e8"); + + /// + /// VS Package that provides this command, not null. + /// + private readonly Package package; + + private static string _currentDropDownComboChoice; + private static string[] _discoveredComboChoices; + + /// + /// Initializes a new instance of the class. + /// Adds our command handlers for menu (commands must exist in the command table file). + /// + /// Owner package, not null. + private CodeQLCommand(Package package) + { + this.package = package ?? throw new ArgumentNullException(nameof(package)); + + var commandService = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService; + if (commandService != null) + { + var oleCommand = new OleMenuCommand( + this.MenuItemCallback, + new CommandID(CommandSet, CodeQLAnalyzeCommandId)); + commandService.AddCommand(oleCommand); + + oleCommand = new OleMenuCommand( + this.MenuItemCallback, + new CommandID(CommandSet, CodeQLStopCommandId)); + commandService.AddCommand(oleCommand); + + oleCommand = new OleMenuCommand( + this.MenuItemCallback, + new CommandID(CommandSet, CodeQLLoadQueriesCommandId)); + commandService.AddCommand(oleCommand); + + oleCommand = new OleMenuCommand( + this.MenuItemCallback, + new CommandID(CommandSet, CodeQLInstallerCommandID)); + commandService.AddCommand(oleCommand); + + // Combo box + oleCommand = new OleMenuCommand( + new EventHandler(this.OnMenuMyDropDownCombo), + new CommandID(CommandSet, CodeQLComboId)); + commandService.AddCommand(oleCommand); + + oleCommand = new OleMenuCommand( + new EventHandler(this.OnMenuMyDropDownComboGetList), + new CommandID(CommandSet, ComboGetListId)); + commandService.AddCommand(oleCommand); + } + CodeQLService.CodeQLUpateExePath(); + } + + /// + /// Gets the instance of the command. + /// + public static CodeQLCommand Instance + { + get; + private set; + } + + /// + /// Gets the service provider from the owner package. + /// + private IServiceProvider ServiceProvider => this.package; + + /// + /// Initializes the singleton instance of the command. + /// + /// Owner package, not null. + public static void Initialize(Package package) + { + Instance = new CodeQLCommand(package); + } + + private void MenuItemCallback(object sender, EventArgs e) + { + if (!CodeQLService.CodeQLIsInstalled()) + { + CodeQLInstallHelper codeQLInstallHelper = new CodeQLInstallHelper(); + codeQLInstallHelper.ShowDialog(); + } + + this.MenuItemCallbackAsync(sender, e).FileAndForget("Microsoft/SARIF/Viewer/CodeQL/Failed"); // FIXME + } + + /// + /// This function is the callback used to execute the command when the menu item is clicked. + /// See the constructor to see how the menu item is associated with this function using + /// OleMenuCommandService service and MenuCommand class. + /// + /// Event sender. + /// Event args. + private async System.Threading.Tasks.Task MenuItemCallbackAsync(object sender, EventArgs e) + { + + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + + var menuCommand = (OleMenuCommand)sender; + switch (menuCommand.CommandID.ID) + { + case CodeQLInstallerCommandID: + CodeQLInstallHelper codeQLInstallHelper = new CodeQLInstallHelper(); + codeQLInstallHelper.ShowDialog(); + break; + case CodeQLAnalyzeCommandId: + bool dbSuccessful = false; + + if (CodeQLService.Instance.IsCodeQLTaskRunning()) + { + throw new Exception("CodeQL already running"); // FIXME + } + if (string.IsNullOrEmpty(_currentDropDownComboChoice)) + { + throw new Exception("No query selected"); + } + CodeQLService.Instance.InitTask(); + + Trace.WriteLine("Creating CodeQL database"); + try + { + dbSuccessful = await CodeQLService.Instance.GenerateCodeQLDatabaseAsync(); + } + catch (Exception ex) + { + CodeQLService.Instance.ClearTask(); + VsShellUtilities.ShowMessageBox(Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider, + $"CodeQL database create failed. " + ex.Message + " See output for details.", + null, // title + OLEMSGICON.OLEMSGICON_CRITICAL, + OLEMSGBUTTON.OLEMSGBUTTON_OK, + OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); + } + + if (dbSuccessful + && CodeQLService.Instance.IsCodeQLTaskCompleted()) + { + CodeQLService.Instance.InitTask(); // init again since starting a new CodeQL process + Trace.WriteLine($"Starting CodeQL analysis using {_currentDropDownComboChoice}"); + try + { + await CodeQLService.Instance.RunCodeQLQueryAsync(_currentDropDownComboChoice.Trim()); + } + catch (Exception ex) + { + CodeQLService.Instance.ClearTask(); + VsShellUtilities.ShowMessageBox(Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider, + $"CodeQL analysis failed. " + ex.Message + " See output for details.", + null, // title + OLEMSGICON.OLEMSGICON_CRITICAL, + OLEMSGBUTTON.OLEMSGBUTTON_OK, + OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); + } + } + CodeQLService.Instance.ClearTask(); + + break; + case CodeQLStopCommandId: + CodeQLService.Instance.CancelIfRunning(); + break; + case CodeQLDatabaseCommandId: + try + { + if (!CodeQLService.Instance.IsCodeQLTaskCompleted()) + { + throw new Exception("CodeQL already running"); // FIXME + } + + CodeQLService.Instance.InitTask(); + _ = await CodeQLService.Instance.GenerateCodeQLDatabaseAsync(); + CodeQLService.Instance.ClearTask(); + } + catch (Exception ex) + { + CodeQLService.Instance.ClearTask(); + throw new Exception(ex.ToString()); // FIXME + } + + break; + case CodeQLLoadQueriesCommandId: + await CodeqlRefreshAvailableQueriesAsync(); + break; + case CodeQLComboId: + break; + case ComboGetListId: + break; + default: + break; + } + } + + private void OnMenuMyDropDownCombo(object sender, EventArgs e) + { + if (e is OleMenuCmdEventArgs eventArgs) + { + IntPtr vOut = eventArgs.OutValue; + if (vOut != IntPtr.Zero) + { + // when vOut is non-NULL, the IDE is requesting the current value for the combo + Marshal.GetNativeVariantForObject(_currentDropDownComboChoice, vOut); + } + else + { + _currentDropDownComboChoice = eventArgs.InValue is string newChoice ? newChoice : throw new ArgumentException("Invalid Selection"); + } + } + else + { + // We should never get here; EventArgs are required. + throw new ArgumentException("EventArgs are required"); // force an exception to be thrown + } + } + + + private void OnMenuMyDropDownComboGetList(object sender, EventArgs e) + { + if (e is OleMenuCmdEventArgs eventArgs) + { + object inParam = eventArgs.InValue; + IntPtr vOut = eventArgs.OutValue; + + if (inParam != null) + { + throw new ArgumentException("InParamIllegal"); // force an exception to be thrown + } + else if (vOut != IntPtr.Zero) + { + _discoveredComboChoices = CodeQLService.Instance.AvailableQueries.ToArray(); + if (_discoveredComboChoices == null) + { + _ = ThreadHelper.JoinableTaskFactory.RunAsync(async () => await CodeqlRefreshAvailableQueriesAsync()); + } + + if (!_discoveredComboChoices.Contains(_currentDropDownComboChoice)) + { + _currentDropDownComboChoice = _discoveredComboChoices[0]; + } + Marshal.GetNativeVariantForObject(_discoveredComboChoices, vOut); + } + else + { + throw new ArgumentException("OutParamRequired"); // force an exception to be thrown + } + } + else + { + throw new ArgumentException("InParamIllegal"); // force an exception to be thrown + } + } + + public async System.Threading.Tasks.Task CodeqlRefreshAvailableQueriesAsync() + { + if (CodeQLService.CodeQLIsInstalled()) + { + _discoveredComboChoices = await CodeQLService.Instance.FindAvailableQueriesAsync(); + if (_discoveredComboChoices != null && _discoveredComboChoices.Length != 0) + { + _currentDropDownComboChoice = _discoveredComboChoices[0]; + } + } + } + + private static InfoBar noCodeQLInfoBar = null; + + public static async System.Threading.Tasks.Task CheckForCodeQLAsync() + { + if (!CodeQLService.CodeQLIsInstalled() ) + { + if(noCodeQLInfoBar == null) + { + noCodeQLInfoBar = new InfoBar( + content: new[] + { + new InfoBarTextSpan("CodeQL not installed. "), + new InfoBarButton("Click Here To Install CodeQL"), + }, + (actionItem) => + { + CodeQLInstallHelper codeQLInstallHelper = new CodeQLInstallHelper(); + bool? success = codeQLInstallHelper.ShowDialog(); + if (success == true) + { + ThreadHelper.JoinableTaskFactory.Run(async () => { await noCodeQLInfoBar.CloseAsync(); noCodeQLInfoBar = null; }); + } + }, + null, + default); + } + } + else if ((await CodeQLService.Instance.FindAvailableQueriesAsync()).Length == 0 ) + { + if (noCodeQLInfoBar == null) + { + noCodeQLInfoBar = new InfoBar( + content: new[] + { + new InfoBarTextSpan("No CodeQL Packs Found. "), + new InfoBarButton("Click Here To Install CodeQL Packs"), + }, + (actionItem) => + { + CodeQLInstallHelper codeQLInstallHelper = new CodeQLInstallHelper(); + bool? success = codeQLInstallHelper.ShowDialog(); + if (success == true) + { + ThreadHelper.JoinableTaskFactory.Run(async () => { await noCodeQLInfoBar.CloseAsync(); noCodeQLInfoBar = null; }); + } + }, + null, + default); + } + } + if (noCodeQLInfoBar != null) + { + await noCodeQLInfoBar.ShowAsync(); + } + await CodeQLCommand.Instance.CodeqlRefreshAvailableQueriesAsync(); + } + } +} diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLExceptions.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLExceptions.cs new file mode 100644 index 00000000..07481068 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLExceptions.cs @@ -0,0 +1,95 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Microsoft.VisualStudio.CodeAnalysis.CodeQL.Exceptions +{ + + public class CodeQLAlreadyRunningException : Exception + { + public CodeQLAlreadyRunningException() + { + } + + public CodeQLAlreadyRunningException(string message) + : base(message) + { + } + + public CodeQLAlreadyRunningException(string message, Exception inner) + : base(message, inner) + { + } + } + public class DatabaseNotFinalizedException : Exception + { + public DatabaseNotFinalizedException() + { + } + + public DatabaseNotFinalizedException(string message) + : base(message) + { + } + + public DatabaseNotFinalizedException(string message, Exception inner) + : base(message, inner) + { + } + } + public class CodeQLPacksNotFoundException : Exception + { + public CodeQLPacksNotFoundException() + { + } + + public CodeQLPacksNotFoundException(string message) + : base(message) + { + } + + public CodeQLPacksNotFoundException(string message, Exception inner) + : base(message, inner) + { + } + } + public class CodeQLExeNotFoundException : Exception + { + public CodeQLExeNotFoundException() + { + } + + public CodeQLExeNotFoundException(string message) + : base(message) + { + } + + public CodeQLExeNotFoundException(string message, Exception inner) + : base(message, inner) + { + } + } + public class CodeQLException : Exception + { + public CodeQLException() + { + } + + public CodeQLException(string message) + : base(message) + { + } + + public CodeQLException(string message, Exception inner) + : base(message, inner) + { + } + } + + public class CodeQLExceptionHandler + { + + + } +} diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptions.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptions.cs new file mode 100644 index 00000000..1f266760 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptions.cs @@ -0,0 +1,78 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Windows.Controls; + +using Microsoft.VisualStudio.Shell; + +namespace Microsoft.CodeQL.Options +{ + internal class CodeQLGeneralOptions : ICodeQLGeneralOptions + { + private readonly string cliPathDefaultValue = "C:/codeql-home/codeql/"; + private readonly string additionalQueryLocationsDefaultValue = ""; + private readonly string memoryUsageDefaultValue = ""; + private readonly string threadsDefaultValue = "1"; + private readonly string customBuildCommandDefaultValue = ""; + private readonly AsyncPackage package; + + private readonly CodeQLGeneralOptionsPage optionPage; + + + /// + /// Initializes a new instance of the class. + /// Get visual studio option values. + /// + /// Owner package, not null. + private CodeQLGeneralOptions(AsyncPackage package) + { + this.package = package ?? throw new ArgumentNullException(nameof(package)); + this.optionPage = (CodeQLGeneralOptionsPage)this.package.GetDialogPage(typeof(CodeQLGeneralOptionsPage)); + } + + private CodeQLGeneralOptions() { } + public string CliPath => this.optionPage?.CliPathOption ?? cliPathDefaultValue; + public string AdditionalQueryLocations => this.optionPage?.QueryLocationsOption ?? additionalQueryLocationsDefaultValue; + public string MemoryUsage => this.optionPage?.MemoryOption ?? memoryUsageDefaultValue; + public string Threads => this.optionPage?.ThreadsOption ?? threadsDefaultValue; + public string CustomBuildCommand => this.optionPage?.BuildCmdOption ?? customBuildCommandDefaultValue; + + + public readonly Dictionary OptionStates; + + /// + /// Gets the instance of the command. + /// + public static CodeQLGeneralOptions Instance { get; private set; } + + /// + /// Initializes the singleton instance of the class. + /// + /// Owner package, not null. + /// A representing the asynchronous operation. + public static async System.Threading.Tasks.Task InitializeAsync(AsyncPackage package) + { + // Switch to the main thread + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken); + + Instance = new CodeQLGeneralOptions(package); + } + + public static void InitializeForUnitTests() + { + Instance = new CodeQLGeneralOptions(); + } + + public bool IsOptionEnabled(string optionName) + { + if (this.OptionStates.TryGetValue(optionName, out bool state)) + { + return state; + } + + return false; + } + } +} diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsControl.xaml b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsControl.xaml new file mode 100644 index 00000000..68f59d9f --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsControl.xaml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsControl.xaml.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsControl.xaml.cs new file mode 100644 index 00000000..2d421334 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsControl.xaml.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Windows.Controls; + +namespace Microsoft.CodeQL.Options +{ + /// + /// Interaction logic for SarifGeneralOptionsControl.xaml. + /// + public partial class CodeQLGeneralOptionsControl : UserControl + { + /// + /// A handle to the options page instance that this control is bound to. + /// + private readonly CodeQLGeneralOptionsPage generalOptionsPage; + + public CodeQLGeneralOptionsControl(CodeQLGeneralOptionsPage page) + { + InitializeComponent(); + generalOptionsPage = page; + this.DataContext = generalOptionsPage; + } + } +} diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsPage.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsPage.cs new file mode 100644 index 00000000..ff02ef34 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLGeneralOptionsPage.cs @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using System.Windows; + +using Microsoft.VisualStudio.Shell; + +namespace Microsoft.CodeQL.Options +{ + [ComVisible(true)] + public class CodeQLGeneralOptionsPage : UIElementDialogPage + { + private readonly Lazy _codeqlViewerOptionsControl; + + public CodeQLGeneralOptionsPage() + { + _codeqlViewerOptionsControl = new Lazy(() => new CodeQLGeneralOptionsControl(this)); + } + + public string CliPathOption { get; set; } = ""; + public string QueryLocationsOption { get; set; } = ""; + public string MemoryOption { get; set; } = ""; + public string ThreadsOption { get; set; } = "1"; + public string BuildCmdOption { get; set; } = ""; + + /// + /// Gets the Windows Presentation Foundation (WPF) child element to be hosted inside the Options dialog page. + /// + /// The WPF child element. + protected override UIElement Child + { + get + { + return _codeqlViewerOptionsControl.Value; + } + } + + /// + /// This occurs when the User selecting 'Ok' and right before the dialog page UI closes entirely. + /// This override handles the case when the user types inside an editable combobox and + /// immediately hits enter causing the window to close without firing the combobox LostFocus event. + /// + /// Event arguments. + protected override void OnApply(PageApplyEventArgs e) + { + base.OnApply(e); // Saves the user's changes. + } + + /// + /// This page is called when VS wants to activate this page. + /// ie. when the user opens the tools options page. + /// + /// Cancellation event arguments. + protected override void OnActivate(CancelEventArgs e) + { + // The UI caches the settings even though the tools options page is closed. + // This load call ensures we display data that was saved. This is to handle + // the case when the user hits the cancel button and reloads the page. + LoadSettingsFromStorage(); + + base.OnActivate(e); + } + } +} diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLInstallHelper.xaml b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLInstallHelper.xaml new file mode 100644 index 00000000..9f999d84 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLInstallHelper.xaml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IconAndText + StretchHorizontally + + QuerySuite + CodeQL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/License.txt b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/License.txt new file mode 100644 index 00000000..79898fe8 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/License.txt @@ -0,0 +1,7 @@ +CodeQL Visual Studio Extension 1.0.0 +Copyright (c) Microsoft Corporation +All rights reserved. +MIT License +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Properties/AssemblyInfo.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..b9f39b74 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Properties/AssemblyInfo.cs @@ -0,0 +1,46 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CodeQL.VisualStudio")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("CodeQL.VisualStudio")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +internal static partial class ThisAssembly +{ + internal const string AssemblyVersion = "1.0.0.0"; + internal const string AssemblyFileVersion = "1.0.0.01"; + internal const string AssemblyInformationalVersion = "1.0.0+alpha"; + internal const string AssemblyName = "Microsoft.CodeQL"; + internal const string AssemblyConfiguration = "Debug"; + internal const string GitCommitId = ""; + internal const bool IsPublicRelease = false; + internal const bool IsPrerelease = true; + internal static readonly System.DateTime GitCommitDate = new System.DateTime(638857939290000000L, System.DateTimeKind.Utc); + internal const string RootNamespace = "Microsoft.CodeQL"; +} diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/VSPackage.resx b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/VSPackage.resx new file mode 100644 index 00000000..bf73b12f --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/VSPackage.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Microsoft SARIF Viewer + + + Visual Studio Static Analysis Results Interchange Format (SARIF) log file viewer + + \ No newline at end of file diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/icon.png b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..06efa295ca02bdc4622fab281e44e0729ba957f2 GIT binary patch literal 4600 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 + + + + CodeQL Visual Studio Extension + CodeQL Visual Studio Extension + License.txt + icon.png + true + + + + amd64 + + + arm64 + + + amd64 + + + arm64 + + + amd64 + + + arm64 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tools/extensions/CodeQL.VisualStudio/LICENSE b/tools/extensions/CodeQL.VisualStudio/LICENSE new file mode 100644 index 00000000..21071075 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE From 6f2b35f84accd30d0348fd047f71004dd3c6f6a4 Mon Sep 17 00:00:00 2001 From: Jacob Ronstadt Date: Thu, 26 Jun 2025 14:49:48 -0700 Subject: [PATCH 04/18] fix project issues --- .../CodeQL.VisualStudio.Core.projitems | 53 ---------- .../CodeQL.VisualStudio.Core.shproj | 13 --- .../CodeQL.VisualStudio.Core/License.txt | 7 -- .../CodeQL.VisualStudio.sln | 8 +- .../CodeQL.VisualStudio.csproj | 97 ++++++++++++++++-- .../CodeQLCommand.cs | 0 .../CodeQLExceptions.cs | 0 .../CodeQLGeneralOptions.cs | 0 .../CodeQLGeneralOptionsControl.xaml | 2 +- .../CodeQLGeneralOptionsControl.xaml.cs | 0 .../CodeQLGeneralOptionsPage.cs | 0 .../CodeQLInstallHelper.xaml | 0 .../CodeQLInstallHelper.xaml.cs | 0 .../CodeQLOptionsControlResources.xaml | 45 ++++++++ .../CodeQLPackage.cs | 37 +------ .../CodeQL.VisualStudio/CodeQLPackage.vsct | 20 +--- .../CodeQLRunner.cs | 0 .../CodeQLService.cs | 0 .../ICodeQLGeneralOptions.cs | 0 .../Icons/Annotate_Default.ico | Bin 0 -> 346024 bytes .../Icons/Annotate_Error.ico | Bin 0 -> 91536 bytes .../Icons/Annotate_Help.ico | Bin 0 -> 343736 bytes .../Icons/Annotate_Warning.ico | Bin 0 -> 68655 bytes .../Icons/Annotate_info.ico | Bin 0 -> 25214 bytes .../CodeQL.VisualStudio/Icons/CodeQL.png | Bin 0 -> 410 bytes .../CodeQL.VisualStudio/Icons/Gear.ico | Bin 0 -> 98182 bytes .../Icons/Images_32bit.bmp | Bin 0 -> 6534 bytes .../Icons/Images_32bit.png | Bin 0 -> 2561 bytes .../Icons/MenuItemsImages.png | Bin 0 -> 1999 bytes .../Icons/ToolWindow1Command.png | Bin 0 -> 1172 bytes .../CodeQL.VisualStudio/Icons/certificate.bmp | Bin 0 -> 824 bytes .../CodeQL.VisualStudio/Icons/certificate.png | Bin 0 -> 427 bytes .../CodeQL.VisualStudio/Icons/db.ico | Bin 0 -> 45451 bytes .../CodeQL.VisualStudio/Icons/db.png | Bin 0 -> 193 bytes .../CodeQL.VisualStudio/Icons/delete.ico | Bin 0 -> 127440 bytes .../CodeQL.VisualStudio/Icons/delete.png | Bin 0 -> 743 bytes .../CodeQL.VisualStudio/Icons/magnify.ico | Bin 0 -> 114349 bytes .../CodeQL.VisualStudio/Icons/rec.png | Bin 0 -> 859 bytes .../CodeQL.VisualStudio/Icons/refresh.ico | Bin 0 -> 894 bytes .../CodeQL.VisualStudio/Icons/sdv.ico | Bin 0 -> 15086 bytes .../CodeQL.VisualStudio/Icons/task.png | Bin 0 -> 585 bytes .../CodeQL.VisualStudio/Icons/zoom.png | Bin 0 -> 736 bytes .../InfoBar.cs | 0 .../InstallWindow.xaml | 0 .../InstallWindow.xaml.cs | 0 .../OutputWindowTracerListener.cs | 61 +++++++++++ .../ProjectHelper.cs | 0 .../Resources.Designer.cs | 0 .../Resources.resx | 0 .../Resources1.Designer.cs | 63 ++++++++++++ 50 files changed, 268 insertions(+), 138 deletions(-) delete mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.projitems delete mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.shproj delete mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/License.txt rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/CodeQLCommand.cs (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/CodeQLExceptions.cs (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/CodeQLGeneralOptions.cs (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/CodeQLGeneralOptionsControl.xaml (98%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/CodeQLGeneralOptionsControl.xaml.cs (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/CodeQLGeneralOptionsPage.cs (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/CodeQLInstallHelper.xaml (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/CodeQLInstallHelper.xaml.cs (100%) create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLOptionsControlResources.xaml rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/CodeQLPackage.cs (85%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/CodeQLRunner.cs (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/CodeQLService.cs (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/ICodeQLGeneralOptions.cs (100%) create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_Default.ico create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_Error.ico create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_Help.ico create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_Warning.ico create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_info.ico create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/CodeQL.png create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Gear.ico create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Images_32bit.bmp create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Images_32bit.png create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/MenuItemsImages.png create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/ToolWindow1Command.png create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/certificate.bmp create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/certificate.png create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/db.ico create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/db.png create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/delete.ico create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/delete.png create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/magnify.ico create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/rec.png create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/refresh.ico create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/sdv.ico create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/task.png create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/zoom.png rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/InfoBar.cs (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/InstallWindow.xaml (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/InstallWindow.xaml.cs (100%) create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/OutputWindowTracerListener.cs rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/ProjectHelper.cs (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/Resources.Designer.cs (100%) rename tools/extensions/CodeQL.VisualStudio/{CodeQL.VisualStudio.Core => CodeQL.VisualStudio}/Resources.resx (100%) create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Resources1.Designer.cs diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.projitems b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.projitems deleted file mode 100644 index 9c35b4da..00000000 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.projitems +++ /dev/null @@ -1,53 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - true - b700bd9e-9b3e-4e3f-b6da-36591d7c83b8 - - - CodeQL.VisualStudio.Core - - - - - - - CodeQLGeneralOptionsControl.xaml - - - - CodeQLInstallHelper.xaml - - - - - - - InstallWindow.xaml - - - - - - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - - - Designer - PublicResXFileCodeGenerator - - - \ No newline at end of file diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.shproj b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.shproj deleted file mode 100644 index 099c7903..00000000 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQL.VisualStudio.Core.shproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - b700bd9e-9b3e-4e3f-b6da-36591d7c83b8 - 14.0 - - - - - - - - diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/License.txt b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/License.txt deleted file mode 100644 index 79898fe8..00000000 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/License.txt +++ /dev/null @@ -1,7 +0,0 @@ -CodeQL Visual Studio Extension 1.0.0 -Copyright (c) Microsoft Corporation -All rights reserved. -MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.sln b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.sln index b931f645..fac43749 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.sln +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.sln @@ -1,12 +1,10 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.14.36015.10 d17.14 +VisualStudioVersion = 17.14.36015.10 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeQL.VisualStudio", "CodeQL.VisualStudio\CodeQL.VisualStudio.csproj", "{A89159FF-1F39-4B8B-8F0F-4FD0C748EA99}" EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CodeQL.VisualStudio.Core", "CodeQL.VisualStudio.Core\CodeQL.VisualStudio.Core.shproj", "{B700BD9E-9B3E-4E3F-B6DA-36591D7C83B8}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -36,8 +34,4 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B4799894-7787-4965-A9FD-A18C3CD61EB5} EndGlobalSection - GlobalSection(SharedMSBuildProjectFiles) = preSolution - CodeQL.VisualStudio.Core\CodeQL.VisualStudio.Core.projitems*{a89159ff-1f39-4b8b-8f0f-4fd0c748ea99}*SharedItemsImports = 4 - CodeQL.VisualStudio.Core\CodeQL.VisualStudio.Core.projitems*{b700bd9e-9b3e-4e3f-b6da-36591d7c83b8}*SharedItemsImports = 13 - EndGlobalSection EndGlobal diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj index 935b3f1d..147e4e76 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj @@ -6,6 +6,7 @@ + Debug AnyCPU @@ -20,8 +21,8 @@ true true true - false - false + true + true true true Program @@ -47,7 +48,35 @@ 4 + + + + + CodeQLGeneralOptionsControl.xaml + + + Component + + + CodeQLInstallHelper.xaml + + + + + + + + InstallWindow.xaml + + + + + + True + True + Resources.resx + @@ -86,6 +115,9 @@ 17.14.40260 + + 17.14.40264 + 17.14.40264 @@ -99,24 +131,75 @@ - - - - + + PublicResXFileCodeGenerator + Designer + Resources1.Designer.cs + + + + + + + + + + + + + + + + + + + + + + + + Always true + + Menus.ctmenu + - + + + + + VsixManifestGenerator + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + - + - - - - - - - - - - - - + + + diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLRunner.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs similarity index 100% rename from tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLRunner.cs rename to tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLService.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs similarity index 100% rename from tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/CodeQLService.cs rename to tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/ICodeQLGeneralOptions.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ICodeQLGeneralOptions.cs similarity index 100% rename from tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/ICodeQLGeneralOptions.cs rename to tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ICodeQLGeneralOptions.cs diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_Default.ico b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_Default.ico new file mode 100644 index 0000000000000000000000000000000000000000..7caf85f40e530ae550cdd40bd50377d45df68237 GIT binary patch literal 346024 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

    rC)bUyX* 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

    0TQ}0Qet5P`wkzMtJkiBm%GXzxg;Nk3m&=0 zZVdM0UNCp=Bfn|WZjBf+WJAUB<-fu8k_W~K#t2?N+rjqGC;dCyg3)>E3~ji~tFOG$ zuxtDFOUH~H`O}=hz{gnU!KvfKoVrTPuVJm()ZGUpG;+BNnL0r_jqNQxy$4G-pZ?Nn z4CbeLwvZY=@5x^S8%crCx8#)tl_l4r^78WH%93wM9VxY_iBt)0DsDb4rTO@;q@#Cl z={0?b44pMbW=AfT%{zC=W$YVw{rU~v&muDyYcN*2Ff{ZLbmR80L4)E86)gA#uAhF1 z`BNDP+hc5j?fiFp&_3xenPXFDDj|QFG-kwzt3d$)kGRh({mLH9C*a;r)OD`wykW}@ znGzf#o!ooNx041*>(L#hs^{C1V|*cTc;>)9oY}=O6MKI9<9rtO<_yA~ogvuAaX$8Z zT!g(Jm%Jg42uM^Oal~LB`ZbWX*mrsjWO+V$F0!nYUGTm%^KK_SCJ&S;3j!oQc^hm4 z^PsV&26ccj!`Q_t*ji{%(4*;-C;#|Or%rRx4#w*G5XLOFi|u1O|6TkM?U6Bx_Q`y* zMDVzuw=eJx0N#PXJLq-b54`8+2L8Z$32NN#}>%eV&X`JtSc_X7c`RAA>E{p?=T6*daDPIVh~-JemHLYs8KhKNJqaYKY>l2~plU~5yrNG_?*b{$0 z;O`IoXG8u5e{ewjBZ)t3W)(Py1@>zp>w$ezNpMgK9F!Kv?lR)ohvR`_^6ci)Qf1Z$ z($jCS%v=&Gdk!8&oVcdfYB)$h9yWjO+{cs0j=kBob?ZR1k8$BGwiCkk{^9+P@R>jB zVX$X@L*H1gZ;u`^K3-n;kb~= zIc5C#JAJx$kAL;mS3g8s8Jo-5?PmM`*>Tww`}`HkmVIaB;K6%BX3u_rHFI(Q@c}39 zD^?{+j}ap@XK6aFwLCoxI1U5uBcBq72RIl7>^+J9bI^ZqFcH{0^&k5%JN*wnHyaXU z@Q2+j1pbTZe~3S9U?n&p{%dUf6QKVaf&FHKKlFcRS>R9Hf&amZ;y4C5i}U?urOuL1 zrI+szS%&+ge#F}2v|08kXb;RA{AbL#H)7DB12wBv>k7>4Ln=V>L;jf@WWc^*y?UR+ zN1lmTvgDE3Hrw>XlC5~;- z{~h3fHn0~qZ~(X;CI^+oak`2)E>@K1cT|*j=C_k^bEnJB{YP}~5BgE^zZ$Muo2 zgKJs14<+{SH6tMI5Lf)iK=;SH>OcJt{LoZzK>U5_e+>T6|2e>aE@T1pKMWku2NC~B z;O~q9z<-@f44@4#1`vO>0pPzMatQbzg&eOeSx!|I$9c$=ic)a3n|$LtP*$$ri2KE^ zY5qVCD7cUQ5&G+wK5fxrv3c@O7xl$^dqBR03J#DkkmNk@;@Z(Wy0k zOjXGOJIH#mx;TEQC>549lM%DLtf z?H7C_X&I1De{%oP1F1RgZG0y_eNvXsKQir@Kp{tXAAAt4XPjv95aV#SJ|0wdPb zi$GZK{WJ1X+7W%)n}hoHU5Q%N15=k|o*WsIDE%gllrlqW*!`%i@Ga1D59+(k0ndrM zVo%)%_5&PJW=vIikY?=_m5#dTTH+5MS?lj79o{02Z}5HWkE#EM{~`Xg0phPQ*w}y_ zhocw=p#Rzz0|#p%><`lqZ6XJZ1>k`F0oQzpcEFq{Q%q(|APJrvVP+Z z88U6G)E^B$;Q_t(1kRqoYBXdN&MAfm555NR1pbK0c}5nIvp3JX!mj7svxV#RKX`Co zxTg;vp9Fk`911qYJSdR(+dhan(0s;W$YR<6@YlXTrZ~+082u1!K>ZMSNCpRt1Ihtn z&2HwT5aWvs2geYT?U+EHL45 zJd&4@z_CwOS+;ArV(a=RE$xZc_qo3UYtXlTzJ;|Uu>ZiR-LL`l3)nZ)7)<;j+7E^u z7#mmu4xD`f69*87*Fc;$U^svsXe@voq|y$+f%c7U4vZZzFJeqk9$*Ks1;>R7Qhk04 z&5M3O?TB?nauAJLw%6FPH$MIN!wACAA~sm(Fgqw<9MF2?(REQtyuAxzMf+t z)ct@(VbW=GAIUNrcuvR)0p{Zz$6@TVJkmcZj{W0c3P7Z)S>p~mphYSaH zJT|^a`^WS}5XNQAPwm(Y9vGjqo~tMy__vc4@$0o-!LbYq{PW}SqemYoSFYSgz>ebw z%t`+z`4D5rOQ<^yo9*lSfcw9jeII8pjF5gahD-J#uzxS$JMmcye{wM17V@C>fakP{ zQFvcZhx7^`pm>@;>HfyT{`T!V*lXlx9m^v29M8IS6MGEay)F5NLq|vB`vQ@N(g!gH zs}Euv1_zpp(gsW%pbfwmkptrInhzy{hos_GEHF8di3dAj1G|AeYZQ#j2Y|iCW*m(@ zoTw~0cUG2mGrpBw`w#0_9r53YH6Er-nsg82oAZDl>qM-Vax9a0{@w?5KS%K*MT$@L z^1Avx#$SmA_gqWdxJ$;)_K`yFxUMPC$H~Bc62uF_x-rG@p!R_0#2>obHl&k*U5`fR zo&E-U`Ei`_27c=YjLBTVzJHAI^m$M2K9a!1x#$zX-qZ2z}^RaCvV_B z8Aro|D+kI0ut)!@j!z>e_6V^$hD(1#?4AAw-%p;SgFe2D!5V+YKOSf^%Q#QuSa%j~C_ zxIiBEK^Pm@ye;8Yz8e4wGkDFPjS7eQ@-)IhaBoAd~Q%LLO)n$aShrswLO&+)(_} z{mlcXucuv+V`9(Pa{2Nlt$SU#aNfBWGW*zff4VEl$F_;13u3wV3l{#2!^#2U0PJ9q zjlZc$XrBx`Xk7w!z*rCq9^!D+z8U;bB6y%LVvS-;2`es}K7!LH**q{$GVy_2z&}0z zeR*j+t%saAeO7DjoTGvMDP!@^%|HCG2k>M*%DEqm1HY9EF<;F!q+h><(NR&484szW zXU<%fLD(C+l1F{igy93G0^_N`pElqFoXNu!2su!}Ir?I`M--N0SB_i$2Kf#5)3}fM z3e0cFE3xNZvfPKA`;5}xaKB;hJxsl4AMf;;(?a~&@8tdHUj=m+#~{R$*@y$02Qd!N z50L}L0rm%&kJ|YVV=?>1h6DDEO+03ej&@*jQ{@31xY~l&jO-Xqdob~VzDfITWu@ri z`Z|t79b&zd90bpr^$2}}1lRy;6UB%tfVSZ2kQYbhkv(VkTi8F!m|NavenVdm?2W%6_VhRO_liB% zGh}_^1lA}b_D7B!#`+(Z<=U+q^71fXHsv`B|6uqb)+00*GO-vuXgkh70?D;(p!C}VS((*UN{_>T}s`D2W`*U*c>^ZIHDfZBTW53I zvxWYNva^ijUszM7h0Rf4$~j}?0CVsj4CvJ>9Jq3x9p^f-PyB0fn6~kf_xSN=xLy|X z6XG8@e~I**Hdt~7!1pok`2yz*9Ds}Icx@VvV;qugXfBz(ImFg`Yrit?RmnK}Gx}8O z>($>}g}(vz7vOK8^Or7Ma>4$TjwKlEIlgcZFFc^p5WgJ!; zAP4kA%!e2YAdJOJT;nl)k<9~hQ~Dx}3BaHEDf?-eeG=;y+HVF2tX+@`j%kt)V;h<~ z6_J+HI-*W`Ms0xe^tL0=EOM{S!re;BwQz*sV|=XgGK>-yzu61YAD;|1`CGjmz^ z(*{hROlzaSKg`5q!~*7|niJt@>U6Fg7#?T~$^*EdJs6uXJTOL>IAQ8Z((LDvmP;VNz&VUh~)LH zF1Z)flvhKmS-JNtasd1(e&7N%h}@nf#D(EZ~>phSk1h3BgN)|wN=P7=v#k@`7}Rb zo)@p39AIA8W6UQ`0=}$`7J&Sc57N8`b1g2juWKHjGp5VOphXg|#Hlf?ARz z6nM?=9J^(zpJ1{q`zMRIoU3@UV;l9Xs?EHp%W~b+tm*oQT8^s>+_2+9p%avPK zB+pdn59XkFButQ-7jEdhDEb@LxAvo7vuDp+v=0Tb3qR(Ki{l_!Cz3(wz@^SO#9qBRtJE`FJ zuDlUeQ}QmVC3zRtmfVOlju2eG@6+fDIppKeHgf&eP5sRM`{}vmPguX`2C&z@toj?| zHy4rLAg@1j7Hh3t{z0zazAo=BZlQ6*F)6FO>{~$A?n%J9ou|~_uusYPTV|g5_SEf~ z+ohyz)p-e5E?$vQD<>ir<68XbhtM~s9fZIa(FQ2mH?!?Pb5lDeXq|$-$o5CZ9yoRo zWAnf~$@JTdU62naC**|!PS~G-oxHZNw2TXxuKAr_H}nPbSMGQD`fE?%UKYafnanXD zTlbC~rz7WoNWV{6zG?&3`W+%Kg;bKfi)%~XFiY}<)sbwo5&OpEl#XHDHK!-|j2Tv5 zZ|Vq{b4x4E68ozcucFW|(juabHEzIuv^Vs4f{F3XY};n$ zohR#jgdM3n^!H1QhF^5gidc*qwXp%lf($tkIe-mlOmOu_wk?>x8hz4A7r&%)Dqst% zz>6yv*`MzGEFVX~caL)bcVZ7eM*O{>k*B7;BoW(} z%h3Zz)z_y2<88p6eS6k<&3sMPy5iTx%Tdf-3*QPMk+@!CXrF75Syoq$aX%OL7|H z8}UbNI&Jju;fHhN$iY06bB0(Ca_tMhFm~j~>zC07GI@WW@gts||vHE|wJVqzlpn^`aM824C%e$K<&4`letF*=^?2ypR1 zPG1E4H73&^*&Hw?gxOp$M>YL5`lSq9fCu^}=1e>qKc#j;J|HH3C`b7v@9c8oJ%6_9 zpU$<$HKUGyvrwTzypOFAgmYD#{eZ9Aw0UpxxN&#b*JbW<^5iA?26JNz2G^1Nk#3Sd zqMqbiR!?4DP(?b#4s_~0-%q_~PJaV2-|A0Ub%gZ3>{&T=`jq@|=_=~Tx1{ZwZ%`wG z-p_>Iv(LbOo8r$SIlvJdc*Xn3vAxIAb$;_E*=S>*U}L`)^U~H}oxbfU+vLc(qmrv1 z^p$gXX#;8pI4TFQ1>=ht542W+BRNnW?AUC0VEu?=3FLvXS_S8{4bC;v`9?M;RxMie1@5L6;f%q!Z*9<=S+lUc_g(el(W^H|*D3wv zwPiJ>fD8UFEvzha_J=F}tP9cS-$uWRbp)$+b{YL;E5EVo2&f^TcJsrfALP#cyYg{N zJN5CJvuYn2c(aZ%4VasLG|#7Gg$-1Yjj33}4%lu=BK8|Cy-!##*q>F_u3aZ_s5`E~ znw873p5^HyCnRLkLd+w2201b6bBx8DuO4j21jb}?pgh?AXaP7d`4Pu(oPNoU(aMK? zPCrFHoV<{mOrrk-AIn~qk0!K}lc!FkF%KmNsAt~7Jt+Rb-}J+rwIJO07PKNF0!xD4 z)_&^D5bPa;%~*;+gh8Z{?q4B=UKO;zd3{alJnv2 z-@GRmZeNx%%$ue{@0qi@_T6Rze~NNI9&CY)d>a0h97x>{+&8MfNl1tX_P`x_AB((> zy1#1mDv6Gc#+sz7vF_M?X*lgeYaYgI;!is;N1T%b<$?JTeG+*92kb91E>K);f_x|^ z;DCK;?N5UT+J_O=H_W*?hQBUvO=u=tcW!;eekAia#NfL^^cx5Og+0_Rzf00{fg?7#U!W1ldg7`;9M9S99TV?%$BzdYoF!#oH&PGm3F&xaH zEkM*Kx!8j8U~|Fv;N%1NGiS;yh8O0uP600*|5?Q2>r!$;Em;;Dd7rgI;vX3v{;+qq zZrg!7YjM1%=~;+Aa1U+jt{pp`(2r1;2TT|xjRIOrp*0Pqa7+U!6x|>L2UGXWMZ%e; zV}l%*q@SbE2NC~k@He+Gp5?h~vOLYPDnDQ!g#3j4w%Nc%`))WY2f&?uXj8{f9>@j6 z$AS50&14tmlv3|w;csHs#9|NN)mWz+xMMBO=#|m39Cel`+%pl5wKXrEz9`)n_P6G4 z`RBAb03T`(v<2H9$bpH^#wVE=p?wGNVEPZ_!^8}pI|baZ=FPDm3c2H)4E#TzS1Fk~ z&-WgE0Ba{}N7+~XcI+Uj9`vCUiESi>S2dJE zF%WQ22)2-ac|FOytd98XnIqRw&$)Z^HrB31zKMOZf4K64Jh*jVez<#G+HC9sOo=<< z;T-l)AwkqhTV~LO3!H(WRfw0U4`(D-261M7Db)-Q~I(pZ7lLMiZ36y=A! z*nALgCs*d2?|V&N_9-Ysr;mC-{MnD+vUzhF?vXeT+)W>VwP=0x>)!nW>kh=9(q&9v zDL3yuDH7LM3a_>}D6AZihlY|59ORCuEpBVtNXY)Bat8It%h#{S)t|4);^Q&8=dvRN zwmBC%90E*3fW6@$m^nILQy%cT(-!cWsV6x(z-t)q$sbr&;@3m}vG+CZ#dg6y%EmrY zBCuX`1n>_F3&Y+wCuGh3bvoa|;e+3p4Gsd~hm1IF0rTsJ<1n$b18cWf2O{B=0x24GHw_yj^=QsvjfCoy!m52wCwZKCiskXYM)QkN>s;+7&xx>*% zW4#D{hUdb{z#h>?7nZ zbnL1BOP4Oi`u)pv4B->Z5z+e&{D430U=}!_kOy*Lgg!|*vH39e;N*jxP=LANM$h@& z2sq%p49?Mp&wVD~73t>HKaKdC9H@Vf9yftI*9^&w|BWl?s~SJf`)dnhOs&|uccf?> zIEckQ)5-&F!POobNCCv=+>y2A^<}l>^$667BI}~hP*3uszffRVeaW??lI1Vw0^?9% zJ{K|vJg6Pu+}MG}1>hfm_i23_=O!-9%qp)36qE3^OJz+o_P|ho6N#7$ore&2Bg8*U z_en^S%QvpbD}&HqHGU`nxKoq^VD7XBS3bbOY@3H5V9s-nb@JQ@pEIuM|8XSdoSVnj zc*H!htN}0RJ<7~~bo>G~0R6uO?0-rBe`f5Ykb^E0`%3;Lb)|U1yHa#5I9S_6iem1g z${KJ%d$4VS@ws3$@*~8C0#S$$#NG&U)&k4i3DRtg$$g4ms#Y-2=EUy0^IeSM=K*++t6-d#IGS+`j%5J<+rXdx-;71#)ZxJE zH<&vb4ygZyme!XNiSJACb?>Sj6f-=)9*V}nCy@vGB*bScHjoF{1N@TmfP7VXK;OAQ z1kS-j&L!ood?6Hgl83qUN3;c;8((B<+ktpZV>I5YJ_&Ig{VLDp6D5AtI`uJ@&ZlFp z*e`?svHcKvqCR~*t8Ka;Vou}_Js<~a4}5Ohh2eqtQ&`Jzo)ce}*A3SGc+FKfN6+^~ z$vPvu6Mx>LLLX%7KgVG*XWS4P)O~;@=I3Vjr9wwhCy4%16#-zR>F=8d>wdOf^&|?A!mEW2mWV5U-kdA0p>u!ng0K8@_)R3f%}0Id)6$wj_oHE zmo}4|=#1Et-Ie;%JP97kP3+eWNIBmy=!mF$}ZE_{{-54J%zhrZu_E2A54zGrs z8JL9PdKnwkCxHu%&p4VK$#7ueGjiHyi&|qn{&h}YV|>msTleXkBC!`9>k{GM;Pl~B zGBY6%bBExE*e~;g%{j%D4{+d19_(Z0b6;X@%S`hg3vXiXl&Lu-hu2H;?Zg33n13<` z@4?s|^8Bm7|8M%g!2js}y?fJ$J^fJ6af5L`W-BSRxtWyONC5{n56VUSJFo{!)E45b zIBj^KUov@8p_TAUE<9NEB={&((_2#2;$c2xgUtiufyt9JKI6Ia0A5(XKz#ODITP#M zuTy-Ny5JrWN$jJrC;M_)iT(kFbqcntx@QAx-o#9Nk1qv0P-qXnE~2(z@U@QyZyqVr zZJFkB1nzp@zR&aW;+Wjhcj92p|H(n>wry#>x^y`M{LOqgXZ;7fY{&faC%i`1>jzF8 zE$=L7D`k>Dlu}8+KdC7=fRF>kgp%uVOrT$~;{$vV?V%WB1LCyC2E=E>gZ7`nLwY}& zahfrKd6FCYb9Ip?RRj;HA%>z2A;^8^0CV!-8k-Fl0a>L)NL7hkgIqLXIeZTGjG@k> z1`&mQCDI^h&jNdgcMi!jqM*1>_q@ydRVW)16Q6wBsndSoUkt)~hMo0K ztmCz6?V2?Yi9IiWv@wafWjnbKDfoxs*-*NXl&fP)buaQEV>gml9og02j=aim$bJV86jNU$t^2#0U1@GVp-- zVAr_GL4l=i$^-jw*%y_9J)mE2xCn+_n7-R=;1`%v#z#+C@V0ag?WyzOwdSq3Q}=C|j-!!j;D0KfGk0Y_n&&FS9OuyUbRq6| z&ba{Kw(_w061gh!9><+1^Fu=Jc52&}bFnxdI>TI0)Ia+M%$RZ8;2$0pC!MDEm9jgV zOZk-MQZD5qDZ9nufn1a!4@nfp266zOMBfAsN+Ld&P#&xpT@10InB8|M63f1{OCOFr zFg`4YJ=k?_`XlYTfrkR&$d@qg`O4y|^3($KA2_DSxS%|Mi@>MlDfE37#)V;T%6M4` z>{k){HNYPA>9uid6??9wkqGQ5`*!V>OV=*TYrW7f!~9@p{nf+-t;OOurrX#%F~@Ts z7hxPH-kb+%j$F5e;`OvN8S$|sZ%cl}dvht6(|HT`ad93{hTI>|9jN~|m@s>C|$75RMjn?N`-ALfxpFp9$^noE|dq@gWAFeR(wFNR5Afv*g30Z6O0X3d?*H= zR1~qHs54h;VA+H6z+8!b3Go5(S>wY}9O0Mpp+ETA;u?~3VL5qbKIR+n-iu)Pg+PbY z3wu|R)^C(GtJYZ9L+3d*MxEz4Wg^CkxsJn@E!KJt=TD!Lt;bU(dvD~8gpKsffL@kk?Z%{(HM=lP0_;AVck+_~Y>u z)&{$_7vp5~|Ky?HM0a^-<=0Yi=ciJB>&K85wk?1QazMYd1-4-Pl5Gpjl}a%_+cCN% zVl?{?Y7=qrP0W>O4>k{$U$XNh+5>E%Ao|e-B4HEG_+ZCsa8Y0h_<-aNs|7A9%2S~j z`$m1O*UBN1l9;S|&v63kJhA6Ey<(q?{fIFijdLhcx2HeR=uaMNdopL?8U?}iqa!0 z>;146{=iYkq;XW-aU?f7H^V+o!O;kHp4d~oAiNg~_db*wQbD`|{2!VARMLhGtUd1p z_P;du0WUioh{0Zq=FNLxVnA5L8eJEs`u;DZ;*L+GVyYz-wtoyRK2g6^ek_@{M@)h0gJaa!|L=ByB#2iCeZKF}WEmo!GeCK#uc2hNGX z+@ySvR~J^3rpr6Z&ON(i7xq!*{9_8|4RPL9DunX^IVXza;d}P%);R%jd*bEUZitrJS~ma@3N zhI3=cL#_oCWq9IbIfeQ^$NbpmXYHM}7uFyTA3maUdRdQQP2ebm_cbj{UM7wX#4e9K zLQNV8jRK-jFHy|C9nMStl2grzl>9<>k?3q~pk5TFck_8&K2X zIp+YFV`fa3ucG=(t%L2P@~%%It@Nl|7@M#; zs9^gg&6f}x${}AWw;3^lJb;5T%$GKzKWFEyY7g=7OUeUmf;^ZQ&G@hyz6rKKDG~!w zzXUFfUxGg}eQENL4}R&5B{j8f9=|t9PGLR-=S>rP)*e{{U_bOU=E5)^;W+6zwDHo# zOUgmd;34u%zk>48v{Cigwn-(V%!qn2YU zhy5tlKs$O&v1dQXU~h6g=6g4E<>ZCw zWq^Mf$wBb}{@%dfyQC2R>|Q101CK9c_rAT4c)tVZlf=fvJn7lBYa~Es&GYZw|3V+s z)Mw(vd%X9Ew!?k{=l^#|7$UU~eI-@*ey$vlhpM|{$stVh*m@YajoT=Gnyk>JQeK(+}{ue5~D@C{K6GD>;Gdt3g%d zmB7jt7qcpfasi)Y*@Vr*G#tUhbJI#m{gKTjcKzD>oI^-CfEa{%hbI6o*GtUM=QV(5 zJ|Yhq5)v4wwIJHSj-C6Y&%|NUb-TONKKzwbKk$WA-~Xjl-`B?CVlT#hVGq?{4^?-; zKkbBFz#fcER3aC!hjjns%7Yan%Bd~T9xUHPn<%v&0xn9aJ-{a5o76vngA$P9u!mwM zMle2@SZ&)xUW~n!jBFyCk8RiaFy}D;m-~qt->TSSjxfh(IOl`+Dg691)||k@XVomp z(H}N|81PzfHRa*e*;OoifM0qkz}N%)lkJ-dOspwg-22O2_#NK2#d);Mdpfjf;{}Xg zg#23E%|HQaM6Y8m=yk4%&G^B5)Nk$r`8IHijBe`IVP@8~nf-O)OtIKY({gTax<(tR@awph>a-lH-aRN5M^Lr4QTn{eJ21a8NFZz6o5w9vCCaXpFG!A>Ou$ zwYG1Hg)Kme(H>S&;G19%lp?T&HzI1ufaD2s`}!@pdO3ZJ`}*~38sj)`o4E?(CHG#Y z-{#};PgkYfi29OkbWwRDq`JI57Xlt$BM;z!qP_|CP<(Pd>EyzxBXg5{0LX8+Vg)?s;vD1Hp@yNw2`+^2OO9QvL9kQtNPAZ~!ip z1K>}4Fg)yqJvcc47vO>ML1P4Lf;?10-l~4d&X*V;DmZz7P1rn;i!v0OgVOLzr4zsf z{8A~CGpQ}mCy@sTZ6b!!Sm!GhS>8zEj&GDZH*Tf-8|anJw}j3s_P~z!PVv6MC-yx+ zYj(%W8~w`3OWx%q_uLxthRwn2L9hu3eNyg#YVywL))E~TZ{0Wq2F@YBojPgKjkn$0 zssZcY<@Ymlf}GWN-kdoP=`VSm%$?n*O_ou~Go-<(&cMGN;z2v9b*L@+2jJoWxqvu% zfS)1{@JrQp(;h4y3>TGCZNG%RbR}?L`6T)!@<5w_Y$6ZvO_YtW2?}Dg#tG%YvIWCK zN#y~4Nn-IXyt+VD{Mi16F5*VT)~q7vVm*1+}GcNIiLX{O1z9FdXU5 zW95&&dhYDm_mT4q1eSlVubUa_UwfVfxzLuVrAr?(U!xtcb~0w>ba9XMk;Z4cNv)$_ zN!_DgD-VW?I^cr+HT6sCo9tMvc44?65AaXBaHK7$SX@*A50%k>sKh>mZ4cz4VlwQ4 zTx@|o&^IA2&>k$C$jC!!#OczE5wr)j3DjJfFCiu@IJR7&Re$pL)SKL*x-YT7HcP~;u2-Rl#$}Tcc#=n4eU>Jkh;flBoB}}#wH90 z^iS%WtazO3$+K!Hf3W zE2(#?gVa0GQR*EB7fv2v58$AV9V0Bi1TGFBPH4Vl~u*z&DhfAZ6>GJtGIf)0nv>kDfL zYa2B}n@js~JtZb?!xPP2?HVU)miIk|3|R#1=<}WPN`4K?|KaOdCXXMV8nJZgL-vXJ z`<&M@f5{3N>_1jUp74`uC)!HA)4<Uu?^-A4M< z@}AQFQLg!W`9N)`0Q%G?u;%=!ItwnFV-+!uM zB4*7a){0mc<8kxGjgOI^9Bc8x2c?1GpAv6>iwneps`$tbUcoB9MfSh`}344mR2 zW4;fNMi;wF-BTT<{^?HQ1}@xiPM=iom?c)MM$A^f1m6T(P#!XIL7SjG)POyta{)e_ zJRoKxHdIRm7q&fA*$TTz0Uxl3O34(Pi%pEx>0FfG2)h6e<-r4MuH=FCPzdq4Fy^ze z)>k^VsWhDT1^j(KiHu(Byg!SzVT@BfhAy7RUX#41`k#Wm;Rf?X-7uzh0dwYbtcJdb z@nGfZ1R3HzRwir?kS{I_le(unNQ2W|z(Z%L4-UwK+5~wxN}*qZ96`LMkO$^Vv_zjeH5DuSKovfQ4O|GZ3k>46|x;%Y=d2Z2ekxH2J4u@5%w~fWC(%?)NaM4Lcxqv;m8Ji#%M-V5#fpT%!=7RQcz>3wi z;hSpPJk&Hi?1q2ZMS*`ZJZRozaiKiGH>r<;Z*tni7Q_mtJyE+1~kAVQ)B~FM=#x0s9kg(X^qcA~ zlMc?2PcLCUHEbcB2k-$dEFR#Sj!}$FSUfoG;Sg-%pcShbBgluv1NsumgB2rcfQ#xB zaL;qkA_IJI*dL4Cz^%Wjz3-gyPm+z*Gmg$@4%IHgh()eNz#0HCp z28a!;r#3*GRxZFnee!^u$=HOIzuKH=tcFd{4s2Vfjo3h`g*Z*Axf^jp{gUmUc7PAq zgW8402>7RM-~zVLIQA=P75t6#95X}$Lc=ttFu1es&iO;w7xFIZ!3)q{_G^FlIEpJi z|BQ3Q<&LaXaDN)Eoy$Cpv6gwrNq4|Q!@P#)~qP$j$U)82HuBDz z4$>;5n{*#D2zzDCPJ{nUV~vaY&i>5_%%9-8@2F*7@6oAKH{ka#iL-x{H`a^bBe!7x z#Cr*t_sy8hxWK*w`_9QJyL3%U_nBVey*f~4omwhGulYJ{f_-T9Mes-TOZ876f3@R- z9?64=)yjkImkwAqQHNZpJ-`;|n+y+o+e)L&9p$6QuF}@`Tj@I_&S!>HNJvTT@Vs7-Ey0HVk2J00*#6F6b zFejWk|8Egve+%nh`#Ywi-4bOI!#wWW; z(<8m4#h%{MI;Ed{xo&`by<(trp7))6Gi{&@oIF}Qr};_fqUf}fSX-1n#`t$$3-h+^ z7-wCK{mJ1wZ(@(Zndr}Qp5VW&pZ_(yf9-YfP!REJHhB0k*x&yFY9>1Wk~s$Z4djA( z9_@lPrKF@(30t;C{6ZIrcW{tQm_0+r2KmS+thMhk$4flsPEv6X@sbg<$IA%piR0n# zC7ymhGTzT$rp;a`^TXC)-O$52pPP7_ngMeH>N@QY^OCtP4|B@vSfewrW81dH{*!Re z%m;XQ6@Flf5Z+68Or%$;~n+zejKXZb$Y`^h=SkbF^xsmt^w zv?<0K!z*#;>-6g!J3`-8uwUh4&hzuab@cw`o1y4SacjKX_hn@B{1vp2mESSko4Wzrm8@9GS<*IcCe(_&?%J&WOL^jQnuj5!hQA_s)Wz z-^1R07l-!iH;;2Ian1kd;_4s8`S-jZcF`Cz0r!Ax!Q7*3SgY=~uaD0yV0IUKQ9oRd zHIb9IY)RwXefIIpUaOqj%(acU#v|@+NyGgkPokGEe~1`*7vt8qf%R>EAMQQbg1l@Z z=h)+V{=d@m--CbV_kfFfu#a9i`r^0}l7jQYkaLh9AlD&3*+)L->xc2at&r%x-Mjli zdZBO5+T_1I-kAp^HDSchvZhzpkzHWVB zgLPhzZ}PCt^~2Vwe)zF{o&|5Qzec}^t0(BgUF5WV$}inu&I`Jn<4Zlv>o_;3j%;FG zC0}?-%uj))4Cl_D#SgolJ1@cEaCbdF?fia+o9p?8^w$fzo_nOfp6hpF>|L-Rbn#GjQ#y53c8~`r~^3Yr5yEpRRhFL7zR$MY!rb z&Yc$ryKr8Fdqz7lKTP{FKc+@&f2rEz2I~j#mCi49WYyncYGL3>c6! zbm-7yBSwt4Hge?1yYBApk0EKcJmzcsAK%0G@-xkvHS2@#ATGp&cpREtHZ^k^%OUVr>*`Ps#Py6)g z6M^eJ=jZ2_#(VVH-(mls^)c20*k+!yo$S*XVJ(?L9L$_Y_J7!CWnU>7_fF25H7jk{ zuwmzV_39P*)?072#cxt4h(k#Tuffcb`QOe9`TfM3wVXnA>(*`BzkmOgqeqYaanYhh z+HYXJ)8g`y-Xk0l6(Muxg~-5BgQQi@FQiHLrc$>@6RFmtzSQX1P~7^wFYonjDPIrk zB10z(N6l)1BqXiZJtfTiTjIyQIM-ttHEPt4z&fT{wQ8+#4b%tPMIi{UiP!eOg#qaN$C|Czmxha!UOT2%IHDMhulkpJCmgFU!iSJqyZO1ee z^9`=82IQ~2MhLI<&%(g8JzvkBJ;!@`dY?9{cbEK z_rMw`+$)sp2XIXXuI0n_a}79cKh|7Xfb}KAfk7nJc3z40ug1D*>(KrUXn%4s><3m7 z`*fDV{+z`mXL5NdzNCSC*uS+b#$HIY3;GE94f-0yjtd<+bnro&X%CE?b&a_G6xSy- z?Vk@Ffc`rov8L`y=)h`V5XbgoO`1(?e+le?Mhr>=gRnO)h zp3ppxwK&!;yuH0|_vq1MA=*vf_-9~1KSEo|3*Q?a5D@Tyag22lJ{BxqC?!5EEzfsG z+lHduY&-V`AC0zizXI&trFt*{Yaq<9+s}0xxi&A?+?j{=hk^g4Xnz#iAA|PC!UopU z2Cx0l8o;(jRr`-o1M-cfo+R zz&89*pUC&qm%a|&3ZFfD_9M2PYwq*WWxzM`Qk$1>Z##5+7}`0~Zolpe4Gg}+o^gX; zlCone%Cr5@UcQI?v;A1#N!RFR`xk@%rI0AtKs44QSOXhKK>IgB2ezR7+o1zHAVvqU zH>%@A1#z6MB+s3yf_pLFmVT25YyLnCSnuVv+8EFl=nv=<|7cube18dTpAA3vfNQ<5 zMn;?KIkK1J?1(mybL^F*qTGXL?prg&MjwFoN6-dt8HgC+CKD`a8D0 zk3+s&IaGDT_0P>aKS>^Uv}Fq36J&fK+P?_xrw>?08?beNHo!QLSO_`*JJ^cPr9ua2 z2m4?L27?pj#c`&RI4)I^H?~)kPu<(;+Aqcy=nvo%z0nrN#zJfpk#_L+9>gb?mzP%x*WcvcIE-(7M-7l%--5TXXeaiARIbUl;T>y! z~~i?(_b`$5LW6*5&cS=jPb$p9eok9bg=!4XgkLF}5F|9Z(01 zFHj7OKeS`Q5w!m}^uX4IJV`ZW;I!e20pkMK%VK_jHqjR_S7v|V@999cF=NI|3k?l@ z!Z^qLJ#tl)ywc?r$ub`HjlHyVe5&!ht2ATAjPqP)kG}rqPdDYwwuR(b#l4vl3ir4g2RvX0S-yKlHlDEdr)0yKo6uLVKSNujF6w@9m#?7AlP0Y&|5NpcIxv?u zKtI4(VB3NEflPL=0sdeU>_GD(+aK(NKiC5d=o1b=j#xI4{a|@1JEf7Fzj$8b0>}55 zD_5^x{ZllW{YLhke@O?Poiu6E682Z=@2R(~`h6~c8U7dKFlhS}w0APZ%NE)K;@q;` zQBK~e?`%6cXWMVw;NIid|N4qG|K_J3ZpyKXC*>)`M%{BY1Q>)uR0n{8v4besLNqW~ z!<-00UqB3!3IPN9L|Ye_A22rTp>Kpu5C`bQ%Udc*>(T9<<7c#G^qHd3Zt4JY!_0ml z%fNvHt0C51ceefUlgEk~+s=Lv z`ve>dH+z4x|90}!Nx6?bzelbZYxz&|Pnl=yz!DcbFup+ZLf8WHf<$5fJ;r@ZfCuP48{ngLWcE&^2kz8}4r{VACE?Kff_ZMXwn)PZS&yQ!` z_B8T0wjW2u0c{`bkl|}aJKJu?E4c@>rSH~$^OrC#&zi>hv(}sl;(GezY3RjG$vp-f z&cyf5wROPQ!4lZPGTRrdu=T)T5Dy%f8yH<+d`!XjP#@?Y87GMa^5*9^|5cg{YpHnw zuZe9#pEUyQW-MS%#CoE6WCQo7$vyj3DXCi}Uq9gJk2bUYyv~`=Ko`(<nuV z;X`X(7PWQwT&_KG8G8W#eC;P)2kETY^BVcOu33$^bnX0AnI7+NIBv`u3L0D; z!g`|dgIOj|p4=nH@WVw-Joq}T)&Hb*KXb7J^zSpsL@?U zY~voNkAHe3DQCCI^HZ!`>CIWiWzW(5a^jG+cAK@=?+&e%Y}&L%E}gn4L!&*dJURrv zh8VD4puWJ?17cv}g6e{eLyV0B?SlQLSR7R^Y~4^h!P;Z<3(1^_P}PA`s7WFgUPhZ) zTW8x|_|~J3N8J}_r=#bY&|+qh)I{)x>-w$^>Jna{z`KWW*r zWp}h)eE@WSBG-3jJ?9c?Yi@l%klZWYl9!fLkxGl3%H4d32886u1!Fq>rJK|;k_xp9dO5)7@CO2T77T43=zhj@Q-W_N4 z4T7Nq^o1elCx+r^Fwp$K_yxvD2>VP13)%*K1ch;v{RrBLeJnP#oSeCMR^u{qTj}1t zJJ(Gt3dw=|a5dLcW;?dR@Bei;_M*c6oY}+5$*9z++V)3}tvxxpo)Pt(ZNGTQ+5`2` z&4;q>(oT6b5SWug#);`@J29Y4#-4Y}+RCBbhjbiZ<0h-^-0zWl4ziC$U(jmKS62Tb z1o40|VGc2X9?YXa7Z%w<-?)TgyvK-6t=M!u9*% zGt`4%#zkO2p-m76)d%7LU7&v?7AnAieu9|LS2zWjpuUiEMgj4O^wsNUUmoL3N742& zkiVdAe}!{^X#10crb@}V4du;ftc4r(mK2L_EC;V0*R>sP>E6%S4-_{4^A)Z$^OFqT z?t$3I_=q+Jq3yFE%oz*@iUXdb{pGQ~#`fgxvOYe++HVhQr;~fGsm^-pPV5IaDtdyo zezdO3P7G|JE~sCyaWGggUeY#*M+N~d>{GCBz2Fsj&OeXz^6jhRPmFQs7yp2^bIdg- z_LsXu+ow+(;xkf;N1*+yuySbeNHXnPkTacxw` zIj@o9jc9v0NG^;eJmQ=$=5GVNhv{0eypKEoY6x(6bwy2iHL`|$p43k!?G2J)yM3fY z)I0bM#N7Gh1?`)Qwi5&93cZ!NkE}fus6NgA1@BJ}P((wYI0QzfkirpJ@9T1Kr)- zADQ;!8qzp#mNwpd@^?}=zOfXDYa|6?8!83`fJ5FG?Bx(uMV?<;NpdW$ATLE!mwecd z>E&hBp=Yq!P+$;>>s1WUcG?03YpFZ!!I%EPA)hb#T9V>6%8Dqo9pgA0%c1^L*!MiT z=cx3H7^-~?&5Hui_E~5mET?)R8I3%8G&YfM6|f)^(r9!d@QDN4C`bocE5Q{nUSrf7svR4)b=_ zEk^iz%3s$smEs$*Cglc5B5{B&BtQ@1fq~*ceQ=XEV-P11CkzhxqJRf*$Ptcu6!)7A zMO*0`=AiAS{ltI*J@_iTt0YFR7uS7eXbUS>tkiv$j_o@p?dNp1?7$zG`ci-a#o)kw zUU|-AhCLtfdK-$b0qM^U?gE?|ww*RhXe_VCh(J%~T*7Z}qi zz=Sq2%YiZA7bPerMAk&D7VfXZeMVNUTw(2X0o_Q5OOT`JixnDO%F3s?SCwLb&vS2K zgN4~^*z9*Z1MlNLtGWj_jy~BXhsTT1?E%U^W4#^!H2;O)-AA2Zy=(dUXsI67TuN-g z8p;qS4jZs%9sEKO;6Mxt0t598YZ}=$(LnWqc|+b6mR;ndZ$K?F`{FXd0eKkrM^l@C zPS_ZfoL5=atyw24qpUc{TtN5u;6BL64-V}|99}@A#t1YsgzE^K3SAx ztgpVMsgy_p7D-rZ2{;r34n^S`il{C?ADliiJ!V=s&^KTmZ|FlF?Ctt;colh;dz7)} z8-g~>0S?fEkHSBbO>vvB_w6dQd9~(73CNKWaSsD)&_A5HDnpjJV-IflLO<9J_gE(e zGa%FPocrDDp7%KSq2M{!RG)(LDL77kM(cRX)<&xSvkruscp}=b{oe%(7K~+ojQ;P& z&o`x|Uk53(9eea_!`eDqu@0M!gX#lpqWDG|hxIlN@DD{0D>C3<+XZpRqkaKcAWm>k zq}QH}V+QmgFV=Twec{>pC8gBjMp$ED6ZZSqfPP^j_GVAgc|Ytcr>1U`lUR3r`;i^i zKJ4sMGA2xgKcTRn&HA*~sBzR9E&k7XJtW(x?DF}b&*i`&)?fAs#&({d2J{8mZ|YwT z_@48eSHk*rY;wHRS>9U8?QAJ!ceKEMK`s7YbJqb^)v@%^*kkO8HPP5R*buv@7)`7( zF_woVCQ%a;YwQKPF)9kEAW9K?0i`Itic+N`y@(2SqoP>2|L;G0?=@*SSMm9Xz zn|$bvH;))%s`nzKCtX2&Ts*{15}y#SY(>e$S@3>z`ys4+_NYBZ)$aN}&+)A+hk$B( z%0^lKhH9uYzX7bAY?NJ7*4`ZZ3Q7Af?4Rrt9#V(+U)_0d7au!)fldjGQ5erW0CD3K zFFFY?qQ+?RSBX4aByenKBl19KC1XS|=ZpYtzi8plF+%!y3}7U`@E}*-+#q@P8D~o zR8tDe(|gb-j5#V2$HOpzxmtt|ln2EF%7c~Fe8>kvQ_h>BQ@_W&S&9$t%=w^f4n{B!T!35G zZ{hk??i+B=L}(X#%N^P$#Lik;@&cKKIcT`T5N}wuAP*R;*p9K&Z5cOx4|%Yganr5a zp~}v-X!dPa9657LjeBBmpzSZ81pn^-7jwJXifvZ(Ad!KMr*@!!)D(1MZ0@cp6BHl1 zQXaY_d=v zJW!u(LO#?w)eY;SZSdswW74jV>n!oKwR!9x(heclxj27RUfvwl4=`@FLl@NC_cI@= zkq>WgGQ@-x(`ajsR<=FvZ^*oNko1?0du5H!KMo!|*n#@TEwK^Gb?xpAOgc9gU9T|i zbt+>LF-CUR6y^+J?wqcP6WBM%2g*X{IQ9zxjt`wAx0;L*5u87T4>CrGJTSkS^bM^% zP$onk1cVRF-_?}yiJCIMV^ijxZ7gdn&JkXjfhf8EM6KB#+-EFt+8xE_Ec2A;YI0ee z{gJ*H4N=>fxg{J32aHf-KXV$`c1GI;y>RsGapj*Uwr%cz-Jw5(_*Vbk-lt*($3Z9A z_m#Dv$iSiClNieL?Zz3C(f!IK@o{3Y#}S4sGw^1Csg($C`qV|bDel0Ql1==ji@<3lUSfl5$0;wcYx-A!PZaYErCHt0XPLNYHg zw?QYo!#yjb)q}DBq?6ijkhKndm`Z8y+(!Cd*Z;|Y>+v92CyGw2;eQvdMB>xnZ_zt@ z8hT|YjbM(592yZt49VFMf?%z>iY*TAK^X6erUI804(e`DLcE^^kly0T0e}mi`>7u z->q-%-@Ws_KD3MEiT4pqGvp!UvNwKCpj~58avHs++D~bmjP< zWP?V7 zexdS81&=@@p8*&UW{%8f`M==7bG(3E)-iP0H5jvZEr4&JpVAj)Z;iUnBkH<~NY8)l z^Lm{epZ@5J$OSd}^a;;REGCax#(++FV=IsW?7#RC%@--pT*eFZ_vqV2Ey zQRLtm{T&jnrr_J~wHT88CHm#-`7mAEHTXIuMUPQ^o*HLoH2p1-et_Y zv;o5sW~2YrFO)n8AA|>evUNNVK9C2!(zSdrVSWRXvcADNRM$7Od>}8#hpvhblnKU1 zR(TpJ4<_E@F~oTy<~pswDL*&m<0<&a9M661N1HcqmNNjaJf4D(e@J#i`cMn>l&{zyga?c#r5`JGGSNGeGC_HeTo)n> zCX#c6eZn|NJ684&HOB|8)9{(&EG#*=7EWG=5qdF9*>J@sAY(k+qm;A!z|%T3`m{9JQM66 zj1}8IX*vc+&cLvsFEHBuOH4faHD)<~4-1zqus`DjkKl8NPfSq0xUwD=TdnLHT3K1; zllD#juSEZwfJ?j9wGmbcT?kG+LoPo~;e_V`-z?FYK&q#WZCrR`( zD7${ao(XckS2zbN~JZPaWQ6^aN{BuB^Z3X+PK0-*tQ`aT!&mha_vc}|}H$8~?G)gs9LNn=7&LUV#} zthMeg`|9$&{4USQ^YWg&FXjAyUQ(a%QTF--mu3W+Ke`k85(X275k?S3>hAJczL($S zIeESrLEe{gq`ZHc4ry=Um(tB6I5zQ0L$x^Uql=z*V~ zegFO9yPtnPBYyn&@m^+TL-)38*KR)FA4M2M5L%?28W2R@r2KzEu7o#LOiWB#Oqw+L zo0&6bonNqEVd1)U8wy?B+@Fj8yXcFe2Z-LR2hk10r&M$YfB!(NU1$Ad?%bt6O_?$+ z+SGK=?t1m=O=G!32|`D6g6v;cA^e?f@kaOV-Rn)8Hht#2dGiw(*C5}+!|U-Q;#&BK zaWx+np|JQ40`jBb7!^WJ{E2%G@J}<$= zf&?rLu*SQa%usWc32IsNL7g84pst-6_Z>&zZI3Z{$89v;KJ+2p*)tSxTQa}ncIJAt zAB*o3_9E~B&w4+9%JV=mFPAOb@?hGu&tp4u=(wE7en=2M@^=X$PyY=KZ%|GqEMB}M z%g@j6p4b;sZ{=XxnKh`nn*IXonFoDuf9~~|pqfK>RCef$3XW}2{$L9j9DX0=Pq#xw zkFKcd%jbfIpe}7@4SdI;q2mZNwEYm1BR3%6rv#L+++(NCm&}{D@OIz6{dN)OF$816 zdxXDAL-}vMnKOqxPp5wO{Q85NSn6+u8f#2YV{;$oH12^a%x(OJCH?ZZ(>Hflefn?E zPi!Ck*8>S$=fyNt7crazSX?z_3)a4nTV{ah1wBMp7`Pe+Zl^!?x7 zgZrq&XCr->me7w%d@`5O_hKXcN(FyA;_pBoP{IEM@po-aAN;mFpVJZLgX!OKk!Qc7 zyPE-L%=Sw%MvW9xynXp&G(5(AoHOP)_fxFeBU`J<~zO&m?XtTA}s^)vYVbQzDIJf%PU(%XzHvzb_m9YN-9k)uCs1I{^yOP4Oo z;5h#5%8hI^*g6`YQ_l zP9j5WgX3%$X#)?+(0P{Q-+^+(b_h2@#VGntU1q-*8d6PACw?UAAEjN?cRFGpXCW>r z^(E!FsCDbsGl{pTbM*)^zy0PS?o~NYp5{91)`Q}Q=;!b`s%`Ftin}_{r+_@)Kv-J| zZC1aB7o|V%IVt-$=cvcUPm!FNj5_Pc^WE&vj-)|k=qT}*HaMf}2b3cNfA)nC(!jo; z+98%SB(Ps4^+cV^Bbk471jfa!Ls7{+*x4T}=6va0xpHOEJ(>}Iw+)E@*sWWCR5EW7 zuoqP+@0F~Lc-Dq8{R3fBH8fman`e}?`{dF$Wc@Akt@!NA+WOI>r&xJ*1L>rkIq=+u zGuz;>v;k>4En|_$5!=Cs?GVrrUC30r!$LgrFygCXQ zJ3%gGU*ul5K5mlWEn)oU)1Zb^_it*jpt|AVxX-_5&!1C=%!qtYH@`V`V1(fTb^URe>zdC>}Ykr&a& zv^I)|xObcOi7d$jqK(ldcCK9RwcISajbV15Quf$q9NC7>q~Wl%gKj)>eWgF>VP92pM_U}e3hnELA>;;okhwSFhecP;?Ng zt|$L(Ii3m)2Z{e7X$R6E?QlxQRknl3lc&tly7urP9ljhh{5qh9_&e?!fnxDBT zP#?&tU%$R7X{b+7;}G$m!nrE_*^B2Ga^!1tIx-234)#a$9bJ%pGnaZWkH^zSrq0oF zzfENP!M%s@N%2M9UF0jz+OImdj(G|1C|i>F?8x3T4S4FQbsIz+zrbYjNJ3rl{pUjeb)Q@B=6`ex$0ph>e-QA-w_u&n6 zcQQv8S97%5-B0E8e(_SHkzWlYl1Ao3(_ag1#teOub&6#K?$(joJO0Nbbb!GSP# z`vP~KJm5K3yQf?)iGJ6NAZuv@;_t?@PsKskV$u8P7wF*jDOO(Gj2DXU&y=jo_;UB| zPs-2iOp+(wv17gBN4<+Wk0o*2SOs65{tg9{8|_)nSY?;Z;hFB^fk*L%1)tkb{cgXs z18I;xeUNZS^gM#TJ)})!z7zQpng}&c_CYiIQSdK};h8Y67u0P6iT3*hnFj>_M9#M_ zZIj$E&~-N2pBak*o|9C26&DNsJbTVO)OU)m!76Gm-m)hS;uF7@{o96kSrc}?g^HXb z4hI~hZ;0dwh?1OV%I27!mW|PSK4V*P?zZQd7JK?^3mp#Z6GDfyhtMMZL&hmZ6Xi?h z4MNou-O+%3()0Qyo^zJiBdfECwye|i_}`N;Wq#;ReBd=79o$Fb-BbNx9e}FXFBXTw%ZZ^y~KUDj8j5GWpv-upE8r8?4`2rCwn1D^c@Y22tkc? z#8IBxM;Zk7>*zSZ_7Ga6U1YuxnqGm5huWdu&cX1!dQth^&7Z#@kGQ|ee@>+ujP_cL zQGQF%-h+8~-9KP1MN@R;nSoK>GttNWGv>84#+xpbPY2?DfH>=Eu;t%-h?h+*l;e20 z)olwhGINx#ube-WbAg$e+4#Zj2kK6om+d$n*;1DF2?#BuL)t{zRRQVPuLJwWD8IiM z>d+5hXTouwV=V;r%WK5H89^`q3jaRzYy2c+HP3l`g!arw*v^ywnrG;Lc6uOVhnS+( zsUc`}(v0W7yP~`^agbO=`(L3$-ld;q_{9)hj!y*b+zKKoPpPSCFxx$veWj`v z|GmUt=ukj9YzcOxL%^1_*z(Tvc?Nsv$F|cHOC$E`@h>3mGXBVVK;&QHKgwqbCWftp zp)dEwy+@$KIicf2wDTB_HfKNJ*)%hr;Uk@vk5vA`&4%AqWW#;dqn*|8O6!fr!&i&ds~YgEAl;yMF~X{A^tx<##tm9m_#j z6KSvTr?264qAly0N;>=>ir?OXNNbp1*ucDC6JY4a+<3ktNykXiF+xj+J9BHFAswzm z(dIOL!q^s#j+vmk3+Eq4;=*$yS{iDhyk$+EA+bRU$I#G_P}L8_mp?n_Dpnm`MLDWO zI!UVy>9?V-Dqu~p5@1r`R4RhM*C19lv?7CCWRHXZCCl zyQ+9^cYE&XMbckOyY~^rcuR5~FFhj%{VYG=dV=Gx=y=wo!J2m~!Y=;3lXpuU?5K;% zcI{Aq*H8o%#Nu+?WzC#9-v$wPv7ePAi2S&7f2BD5b}}Z1t;fjlMd%tb4qbwoD=&~V z_%mOjFX@oB;2Ee6q@z9iM!U1p9zWC3@;Lhnb7j|cF+?>dj^9=_G3D5F`d?gStf(l& z#Kx$(;o5cPxr&cOqm3L3ws3A1+@&pc5-dr(rQG@5cHRk9?F`Y-dKkRY!{iLm)33i) zvFw!W>+s*g?+dRzxs7pQt1%;X3wm5&&a*J)oeTL`N5@zg`Ad5+@1i$pIZs-I4)zVz z9z3`Cb9iWbT*}`L z_6q^g*|!mXtcmJ-Owf|?ukwltxJS9~&g|J=uO!}O`ak(^Ze?Yi{)}s?2^ZI4S<*iA zy)+FyE;45r&s%g09j9%NAm+^rU>-@K!}keCRq~>5di_Yp>JJI-K|`+0pU8J@wBl>c*NA1;LmbXM@jTSHL8ad-j(mz*y12 zT!3MuMdXTfbO~g>-ru7`wFhY_qk}s9(cYMH>Kp3VjGLnKdlo%P)@`zW7-91-ytSzf z8tm-5XEu z(m!D%EYh9OFP45=(adW_I(kOX2ZMC4pS0-OL*%NXm#$6D z{!B*`$6j!WI;d<4g1h*Qi5_0U_+L5P18=>tH|o+h)5xwT8t&I)89hXSQrO#j- zPFnPI1d)ya$` zKh1T2JK7X`pz%HvG@`FKoyg8_F5+L0x^)C&(LBEP z^fso&ZpEIwGZ-2-ThY+>GUX18=Q%XioW^qMKM;VIl(gL zG-jv$2-9TdB1@dEr6r!UuswdJgY7{&OxPYhDObj9j~*dx6VlO5wFhO3a%Dt1I+2c6 zM+e~q^PK2cI!nv0`NseJDzD ziVHC-X&3DBJ@Lhr%@~x*e1j>>ahLQt>0pjE($V)abCj302iqiK5_;*|B#g2pbOZ|> z9E1HSTYmIgXCH6FIXkLQ8~;#G$4lBi2ArFTjwji!&QpTefU@8u1bv?rU9q z_Fp@8SjNkEn(_D=W+ZIKzN=oClfDCkuP}EdeT1YvO!aicNqcDN=o`)4lZqk4T-T=op;x1qLOvO_JCq32c*iw#jAE zB7H>YU|;WZiL_jtj9wQgUtyH5P|8>Er_>Rd$CPmY!Qa58v;$jR<{04)Qn6EF1c}3$0G0ZU< zF$<>jPd5#ni$Q_&G0=A|dV9^r+E@qVJt}0W8m{@HZ%RF^?_c`5|E@dB>?vcb%nvy^ zIgFH|K_PA1u0}26=#WmMQy^^i>om#WU<11 zWbiV$vC9jb%HtTiKecRD*BT2jpx)`uRpzmOZQUY zRN#x{sR!^`%m$cUSd331Ebx7z9qe&kiipTP5V%4GfR z3BtP{30?%5YaS9buYi1(@8x%SPM&Z7I_1C4GvYr4XdS%<$h}0ojd;%!FC^ZBxmb|9 z1xu4VZw6}&48;A&V1R+aOSv~SFyLz{3a$SBKt9vLny0%5%bhE3{oO+MS>3rB(ck6k zvek)xmGXDp)rz0x|N2fmEu>!ky{7In@4@mt>C@ly7)aK1wZt)zbiu1H_=Vo+R!hOIM6=)x0H{C$kMUeO`hlqzO>pxE$M<{Jf zv9tkZ&^DI)KHg)@hDBSJDchKoC1pz4{|*PiQJxc9gq*=0v*=?~TgdVy9{w@|yuGy% zOlLNj2?t64DcViFXln_gT_}<^xy5?h|x;$bMahII>_q`UTpy14!P zo_Nk!Dc?=L^(J?9L}+gi=dqMI77 z|9+CX3Dc<8KS@hV*O)krp{<%cXPlCA+1`q7(KntHm#CP6vjgV9o%?Ke3njlR$3LF+ zHa|&Qo$yQF4yTEO2XPR25Sa`jFGAQRVZ`N9T{Jk{p8KKckUFJqf{ny;@w*V9seYsr z+H)@;@lKMeTlVCO9~G;*7l$uZ@?hlLUDYcwC+^?9&%K}PsI`mzj&ZsSj<7!*leXXt zCF7Ft;ym#XxsZ18uZ4=6bb@q)pt|KctVk3sk{( zCzs$#+7*q|O~{vh%&(4rPrkLo%5*EOyiv?=KcwxL>tjWmw6V}g92y*Gf;+eFB8z(; za<=Hfod@XcV5-H@iO)C_4iOJMKSVZ;vyTXzsEi@>C1hMksb9^Z!sp>GQ&G#`1XaC^ z@LAM6Y|V5)N55g*Phwe8rrh@vghs{&oOslnaenS2D?LLSFZ=pc@`iNtHx*-1o_8cT zQ=SzNA7=vP#Bi6PI)}#k)%-2>4?8gx^+Fk=FQ7Lnp6g6LwMHfP&Zu(Mka)8V53(%5 z;{ZW$uzLe115V>E_t&#Bve^#Y2S3erl6(cye<;Ta1ZM&LXTIBUdq*{f>FQVfpX#*` z4I@nPPFR1`3+{`$0ew*0rzdKi>xmj3#wd5X1>2Q;6y6FBY>ze$9dUE0o*wx#eAjT?rN4lV|4RNWf-KP}b}$-64no6=^j!<(o<$Jj zQ2Emz&&LF{&zay&k8YGvj%P~!>un}p^`!_hQhn8Kq;6!)Ma1}lEN6GA)!x%c6x!-MTo)4eBsxZ0qX z=cjl?f1SdD8z{V9i06#w-Op~IHZG^cBosWP|MKs~Tbm#$Jq0|wq91?M_$zwOyzmWZ znK=rrQb(ah(nn=@yes^;L_ESx(SUfo9YFc;Cm!eNpX+I?d>huqSmWix=ju$rgKZPk5B2=}pvHM)RQK$P<5`}-6P|748ArKd zuO;D)t*m!9$NzmTQH^njyd(WJjM-JHpMP|7&_K~MISy$Sgl$Bd{IO`4^C|Hdhc@ZN zGhAaoOFDWwGf@I($1YX9_@)oJB7zsv`!fX#Si+YHj8Dvg{Tkk zZUlKkel!X(MHQben4Y)-F%OcYCL1MdH+WL5FCil&-&NpFnn0> z9SmW1{i$8mGZK448+*j0^Lh^iO>|kPl`0cWQ1L zmS^sS@vUj-QZyM|Z%js)Ym;G^Hvye`ejWY$6&wbOo+@o6G8vq832X9pqj%ACg@+OOA$S<&lP5WXhwy`t!n62spWx#Q zb6|h@C<<;A{OR?_D>#&`zZloA^w!N=n%IIwoXkFlZ5anJFKr7ZCNIY5gl{o3ay7QZ z+iFf+Ij4!qi`U$^c|#-pS>*h$tiSX)$X)u0^i>%zL}wCRN%R%b8D!oRkiW&hEFdVL z)X~B5$=|X5d=&>B9{i+gr36<(8lhMR^0#~^znT1rBGsdO zrys#~>5`>sZmw>*v^77zeeZ7Rz2{tmJbR3yd$&qsE?<7^=5{u3+0y0d@~ph`I`#0m zuNQy6I6f#K@On&kvc@UK9SeN6;ZwKo(e2b^wDS5CANeoFoG?r5OLj*{ZanQ9fravp zy!-F!;P1;UcUWG`%*`oT9=aD5c2RHP8dl|C+r+yA_4AWlD|u6Izd(H^tUW3-7UAp^ z8zkSzd1krYGE&O;y*i|BDLd!d)fWR!%%YzFb!z7FntAq1Y!9{MdX>7*cG17N_VA>B z62kRYd^6ew+H!r~1;&xzBI$O{iyhl`NFBeRgP;2eeL1jkdw;@{_*yEWI}ozN?09^&)Up0TV1DN|1e|F-q<_PM^A zXY36&Qm0*M08@wlWo64BH}Bm>rS&Y^vOIZ28azmYKkEo*9kHwTXvtS7oDsxqFFe@?V!*^*_MQZ`}f>654OH^&~Pep?w`T)Hxv4cCRb%OTDY-f2FN zI%I8Be+%^v$-i}&?JRV-vkqx*sV9WMJP-5Y_b}$s;pRaxF)3xb8Fats1p(Ro_ zAuao6L8+mqIcCPJ(U#A>>22}5w0g4Wh{ShWuq8?!Ggk^}Sm?>Nmb_sO)VG~k$05p^ z&~t=v^i9+_J^+{VQ#DdHp*Zc)RkS-d0kyean0je3riOD(=g9Z$S%$3NsQcHjX{gT4 zJ$?KXR|~G9+Ir$DeZrn=GlBiA>j2k_`$?C52SnXWgOn|hOrLkdfGKF;*AH(}->d3s zggUM!D0h@{;Y?YTdT1LnKRq2!9x?_Q=?F*+(%Q`=57=&&sesSQdVsMggRjNw%TLRF zP*^%LYAN0e8GabbhAwzSO(V=hrX@~gQZJxFc zvBwA>Mc=2sUDdt^VslgU{Bezqzx?Fej6G<>xPwi@8CNmX3{3*4yRn{zQV(Mh*OnOV zE=|zkaDV*tfW9cCL3~qcuA}@|XvS65X@<-ZXQRsSTq)+hw%lQeYu!eHFk!`!3eeTD17~63@ zTu-@59~1dBS+RUYM)K_(%*?fdVajJ{moOS_Vn(5L)Q4yhJ{-+LhB6jAdFN}2`d)oe z^MnyRa(}iTxx}0#4Yinmq7AA$48XbcaI9LfDoe`N^SJJ*~3pdX;*9fmsIy)Y*1 zE0(PF>#)i^PJhkuNGr;H!SN=E<(G|bx;nnzwbLpp_tDML?f2X<{_1KN=bFPXlW}p< zxF^nfBvxzt*fD6!7`1IK@$8>}Ka7u=gINii(DmF5%6w|+9-BRvS@ti+XDMGUe!tAd z$|gGdR>8|tPa`p}a4$yWEn>Vk>W3Nh(@bOB&*YC4-`d6S>=ffM)%6;VPa@YKxhU(U z-5y&h`*-ITZ4Ii9ua_@do)CWV(!B(p4|TX7fF(tan4G-{L(>+bcj9dHj+=u)ao=NB zvK7wXh(>fw%)K?MRtryl7jJ#p`a7Rf^ZVL07Fo167e=MTl_cKJ)%ZS4fX992-no~i zxs-Cb)!c}2|;97jf1@ZY5hcFu!ehKO}Rf*lY3v4xo`9a zyJI;8uZxHNd3jgLkg}vqDO>a~*&b>}(Cc9XEAYdAxE9P`FqE*JaEb6h2lBUkH}sEQ z=Wopj+ct09SbW&o34uQ65g!?$K>n8R3x^BhkXDEuOwCfyeCt4BcafY6qLs z?$sV21x&;75XPR-ma$E6;JZTwFL&C$hIugV_5QAmb;kir*F#+jTv2~#Gsbamg(`0C zF!H>)!b3-k;+4?0ieq2bV*^l9N&_da(>J`?!+9=*cnA(P9f-r>mZ);PHP&%Vk#|_P z;jLK68vXIt%M2vkb2N>ryKpJ zx}2j=o99QEn_!{%DSR1qXe{$%wZ^EU6JEuCyYRv~;Q;zaPgOoNy~LMEe6f7SpgaBi ztg@UHUn1_up^am2Z1LOrD*sgbd53vnZsK~FUZ#(c__1814^9Znq0ggP_!M{+1u9-n z_niZ;fHQhoRPszdDEaZY?1_1)8!;%6epj(9hkiYM=*!cK{$cy`PvCq(AlxpU{)PPL zWJqLR$**tddFuBr_%3BVMkjrX5plEeP1Gvvh}wg5Vea~Oe<8oGl<}APkG!wHh{vDm YzYk>Zn)}=qToDTVr%V5wyd&@a9~+FlWdHyG literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_Error.ico b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_Error.ico new file mode 100644 index 0000000000000000000000000000000000000000..4db814c65d1c104079e941f0e46313fb4db53d7b GIT binary patch literal 91536 zcmeFZc|4V0*D$`3At@cR%#li_L=qt>QVFRL8H&tP2}Op&k))Hvk<4Qv%9zYV88T)b zL&!WUb$;uj?)&?_pZj^==l6b|&-;1*c($|8zV_a0t-bczYp=c5zD^-ThPEPc@$FD< zLgrKmeMSiJ@@~{e$q|yLMu?5=cbyC&L0W{iZ{Mizf%-N&1o#N>X;AVugbr@S@PF57 z5bEW?@Hgt!K;KsY!{4ZzQzE3k4+exphImo<3_>|TYl9vyO5TN#1|RhBZuBPu-pUEG z-}HD9eltSR7s-Cp<3;A15ZYr*hV}qGAcKq`WAnn2=SH#q{P!=HyGt>B%V|K8yoM1nSa5XtXv9WFsD z4(#kic3fDH-(N^k2QA|WI08E)*1vXmKr=f#jzA!~5?O=(L5XGshr_YrLNR!DqRa9h zN*-S9(1=?{2qm)rL7)b32OLl#u)DIe69{3;p6kp4xF&%e2(330iLNW_glK{s2>Wq3 zj5dxC91OS31VS)joluY~ zjx_|2_rmxIC6OH1bqPT*0Cf;>!iLAM03jTHg|tj$XLs>~_7!#<&IOMT!X|+a3R;0# zW9>AvuI#R%E6{!w-{edQqpbLy*?XJ4)>{vS<53<%I z=wa4vX&4)c1<>Dr(OvQ1L}}mUGXdUAV0=)8*&bE0qW4a%1Q_WN-KmA85e*@LH_>! z9?*_)1qjQb><+*tLN3exuCRU})=*+tP!MpzzTye(G%x_sg#_HXIun5myMxQRK2QhY zUHx7C!Z3K}FpN15j65icKOSpb?{I~O&<%YR`D1(_J^e) z&)@AdB>&|w;vWQ$Kj5GfD`7wf`+%g@ncTpjCar|6j}7F4KzII;U_XXA`}<*X1r_;A zf?bUdBf|a#$^R|+Vf&qg|LgAE=%>NVgUdf*0SeN(E&7+zlX|^<4eNtEgOCDNmLSA~ zm7cJ6SP7&k;OiHZWKaV5dgJLqK~8R{n*reysi%zW>Z;eSV~k`C{|N=8wq%J{xlJ1aert1ju0}AbMcs z8i)xiNuKmrxd-5RAuB@ubIu?*Gyi?^+z=3)EARvv{;($a`mdccet%ng8fQFgQ)i46 zmS|j7@S&_OL4Ka=Rpheb3g#6o`i3fEmJiGV91H9F4Kt|h%-CT-ID~B|YCItnx1U`G zYrvEgKMOk_;0Yl_-7wf$9$@YKa3MI|L#~9-WkiF=g|cC%3?pft00`9n4!D&d|NZQs zxVkU`jUTk)Nt(f6kl-xv#DiUATM3%i!Q;WSvf*9)S;3y+Nnm_J*!PF}VfG6Epz05% zD0CUKa~K8a#u1na%b1;X#?0z6%z~YD*~K6BJ!=qHDVz*5j(yp~FO&!dCpnD+Z?A0nQCP^>S!v6p7^Tf)AR-g&gvvURk$VuAxDAuv{MYG=Kozp+roGjF_SI z19;3(1o?%8f&}sSurQ$MOmrc-Vup+w@9)21WSm3SH#Hu!N9zeYPXJ&AFd&77{oeCH z8G`^DiFI$R7aSh{ST9&We9+3@_WVEBn=}LJ=1E2ZJ@tS+ssQ@S11d@14+E8e>SEaw zRPawm|C{s&4l7H3{UxO!|Db4-WeJje7F6cL;bA^|hoF0NQJJ8@k<3E+(o z;6Mf4oF#;L0k{_t*4ZEDL2>}a0iAU5B81^*d4l}e+5AAiaNrGK=R4>gfe5+^r!MFr ztSIXW33d){*#!TaJbNA8h9Buw^?ye_VP^YvF43mJ^ zCr?;Z=z+yuFW?&<|BLJVdq!Zy@R-H&gG1QG1@-`JZ+1UVYCjhoVVTX|&p*hEZ6y@% z;u^LRJ_y_h7ke6)Fc2^hh8{n> zAGX^z#`!JD6&{58so}h!0DeJ_vHYKDk45o9dxSx*p){3BuXe$%9* z^FUl&HxM_sE8^pGMmu-9B4J@Sbp84bgcn(KqwmWinzk{}Hxrb=C1Rw^S zKVoGIKy}e-`w=M!R+uKz{)e7cE9&;u%OnA`AMn0j>Z^A1XpJGKEM% zF%um<`V8H<K^yvb0?p!vybmkuoGE_5tk| zs|21)k+e)D@KXVN)gn2$kLb|BW~ev8a|b%AP>19dYtXS{6-Z633@ItqA{Et7z)v00 z(yBnZx|K*<`y=p$!8Ai(8#;Ni1?JF+R8Mq5y#t*()eSH$NMHXml$`+EflN)yVGi%n zl`9{SjrB)Z+X~1ZU_I;5)hkWN%CZ?d|e9`g0|MLs@wbpL(;^7ba62M->hd-uZ8qelc39Q*`5c@ly` zL&MRtXA$W6^B1uH3Q=5KJW5Z0g;G+o(W_V4P%nh%LiFa%8}#;V4$8^NL%DhRsGy(# zm6sQw>gsnuy9~ywLl1+hfp!(p{s7~&!g#IF-VJ3h3J-6A@w#EGE|i#DjuH|+0Nqch zxVQvGM>nISFGBTiiH;R%HmVwV%;Bgj}m6f5InhI22SqEheYHq4R&CT_wv$G!f zZ$TeFHlwoAZYVpTy$RZzP*+zc8XD?Gey{5y3(He?1WiinP?!)HJjNLg@dNS0XJjre|syCPtd-Nq)Ln z@qdXDOiWr`SQso$f2f|CR#5+KVIl4b?SG09PV8A7EmddR#=yfTz$d`N!>m&MZK>ml z;=kuAxQR6SN`aYyk%xzmTR>1yQ%LLFP9EDvQXDPu-(ZAKEvS=iV*qe2E-r2X0YObo zt&11W?Pc|w9C;M{9}pr*UpUDC8cST<7`&jSmX`MU^A~rTjjcZUSAMnX=|U?(b+56KnndkLO7`l;{_5A1MtJWK7q4mVE{n5AatN%mGIX&1W%9PfHFoO zxWV{eX9xzs5H6e-Iyl}9S8{(+Wa~2LHbxAdfq`rrBiF_RUf2zN42(>yYUE_w*5TI&5VSnOD4-4LB5%bq;SW5qZxq0J0D(QOy#zzx;a+D* zz-?v4gNqwO5R#mT{(}%nI)zP=k&!nyC858AoQwgR0Ji|&t$`KNiU$L?hL)BVPtC$_ z_{i4LZP*+ccjh&xBqvW{2;5wJ+}tO7r>3S!E4KtOcp>-s@C^|KFBh=!0X&aPdvnv< zjSBY9vQ!K1giDH&sll1wEfA^B}f>%hoCkSmsUt1N^+ z0}+My4ob+#%B~~ud9=5#kIDs}-#m&VHIItL8+>FJuLF@1*tS%cFtz!UBd|d85t*xyv!az3#*}Ae~ zi^;{q#ZVj4(reu0#j)prlOCgb8N2}VaedK zfwWZh%D_w?AYdyu-A%a-bO|F4+QmNDgURz*-;k}9`PHi!hCYBVOwUa9_4fW|i5x?~ zxMF1F7)c5T_{8J|D>rjHJHRl|eNQ4SFHcWRPZagGx4;N9ofM!Nu;*akDa}LzI6{%D zwmz12SFhNa=m9vuFRU!sN@e%=v;kAoFlh{dhl?R~`L}+OYTUi-9PR9kt1z<(A?cEr z)WL%}{XN~l)O0r$Zr?s$URLq0{*4U~*}7nhcW`ht4%`4It=^Tod|4I{+Oc`hmF^Q2 z72PL#dL}VyogWlQ%Eo&;I9<8FxQ?*ostZ%UtS`MWLSH6;i%Rau|GvQvLd3pBw~Cui zPFEf*0m4#%o}DSc8|h1D_xHB-}BdosM zx*^T=0YaxIy({iH`TILwarD3LbOS?xG0b5_E?>SZCo6MmX8LaiG?Mhqs{-Qh_2dM} z(P14077^h0tA1Vm3w3OWMAC$JMHzPe2MNHP95xWlF>vLtq?mO+{_>UheG&iqqu&Ms zU_f%PuroI@lan|zLHaHEzrdr&>9soV@@hZVby$GLW?&{KzdvVn`d^sYKqK~$7PGxx zSG>OGdegzu!qVK*%4W@FE1ZoPd{%jTdQlwPkdY;^+o<$ z>gzb6kv(f`3q#d-TQeJ5v>w~@jBIqiSo$2@zy z?ms*VPy9#QUmn(V65OEwSbF}?{Ui^>lbEa&{#njobq|O!u@dBl-N*j--B13GQ#WD6 zf2Y61skXLu5SO?iIywU65QsO!p$vmE64BE?hj{WCVr3;l`5ZAbMBGSIJqxD{g9lb?a-Hl%c{3#qDX#IKqfpCNv2K{^+Ek)B>RGBYbhR#qjDKSBIi zid>y5kh@zI@^G(*n6wMsa_vGVPV^)7GlNK7V+80AA_Idj5chrooB=4ukc;y$=+77A z;aLMQs26(pFlaqS4G9TBF|n~IIXMMlyp`Q=M2?kq)_nRO7;)DZipwFP-|-o>gZ@epFg)l*#Yro2kPzZMFRsJ5My?t{{C)=C;QOE zR4*zo8%9;t{iyom7Z_s{V$yNc)cghLjH2e&G1Sm70W`(|w;yl^ARZltas-Wz4x!=U zNi;t84dT-YG%+y+G3hrnI4}dx^XThW5*md(KK>KU&CNs1x&S2!egFP_J!S>l{Kp!s zm&6cqGBWaze}7aEmBOk!=70X2@2Cz_`VSxxA<^^W@8ZuM5;=MI_1F36kchug4vn6# zy0>>T3nL@=!Mj;B^5&!e8V`mx4xQM%nTnF09zwwL=Pwy>oE&caCqPJ7-rmhrRM5}J z#0LPnmo8lqd)M^`Aha=$Z8H@G)=v*n;kk3Vx+W%9xbl8eh=?8%+Du6W02n?KkAQ%- zfc7PmD`LaZ>(dCCS7D)~q&kqXm69HZ5fCsfwLf?1l7Y%RHUcp^m5rXBQYxx%ek&C{ z6A+MT`T1Q<;L;_IDvW^AqzVT;y--G7_2fKIU}W0g&_Dlk-c(!reEj?qgu+JTIp`TV z(mvJIOfDRw#EC_IYM)&As;@0@UhHcakgt+I!Uq7a>gzsE&L7+tUQ=D)F(eCY?qYmh zO$=#IQB;&;WTfZLuLlbA;jz)xbq$9xHu?DOc7%}6`zR_Z%JMKVa_4`ltFEc8j*iVZ z%*e#U!^p>Xe4d=_r>D8OsiNF&0C-d1SXW(Loqrg(#4$0^GfMp=Bm1doWd%MLkYGIB z*a!d%>XeLdwGOhR7x_s>J|Aoa$->-XkNr?z8vsmxKL&z=etLS9dGe5sR7YzJK+b7q zVX~vI4Ve6X5LN;bi&sYovAXJptF?obsr%~Bh53b%g0^~~umQl9T1`Y@8g&##{PAH&HG2fK)&-iey-Mc*1K2T<>c%Kd)gXjzMmA^zh84+30t2p_}i{` zRsnm}-OS3$)PAtHv90Bln6&ik7;J$<=93@acMV*HZcA4O3oBE{!Tyo!hmRc5m=D2} zG$ML9>EV6XN0pDPT^(E<92~AW7CFf&D#{N>Z76YQV|mfT0DoK8+qZA8Ls*!bTPUjh z(JzETC(BC+cLMI;zkS=q#l^wJ!NKaZTHd!m`UxyFel0D2v<~5hfjHVH4!5okjxhi! zGp*r=f^TBc`|xBrN?u-=7!_ zw6VXR{%!OAzx94;!%tEC>wDC{_$j=+caVd<1I#1<@U0cfVc`3$}bJJz2GISWzKgp`iHfwMjnsjI(%vp5?aQz}9l8reuwBOmfRbm2lV_%QE)hf>Iu;D=N~ zSp)O<0J5ov`X|K6Rf;${-a~r>IF31u(v+zWHNG9M55ww*S^03WcmSoEbO@se3Kd^Db)=1R&?l46Y$)C4$HKHtUp74JIKBl z?%>;z{E-guxq5+*F917?9* zcOhe=Qgp?n0$sgY0r%xK$jr1FSydF;krV`DAgPjrKi06xfMFWiNXfFCmq{>&(i9#QzIILTu89k;TQ44@t2J zf9Z;?9B&UeDkXI^t$(f(+w&VKu{Zw^8yBa5koxJ}$Gb-U#IK3tcwRPY1_lA4Q|Hd> zNMtT-bj0@Jd8w(W88|rwPN|#079os+0HwPc2xpK?8p%= z2A-31^c0)|0?u>!wCBzpp96%XVi`^b@0PkbdMeH%t)p{q)zwA%lTiGJ7qYuKMRS^= zW9$36xqiJzSh^Snd&{98*l6V09-LJa5AX2 z#l(L|zvbYd7Y%FD-`?5`Trn{4zW5Lie7fJXEr2DOHZ|#PYn{Wf@k+NRVe<+Kyjrqguuwi@bFMK7w^2@Kg~cYd93|4!S~+% z^x~1q4I;l+@}KMePw0)Vf6wGHheB)|0q2!J*zOo;djb9FkY6JTiY&0zIq;m11b4-teS4E2UQB~HxDevucVNGY zknY9TfK!TSHgCkBEX*Ge`;J<~&C>>FO({}PCX3<1BQiH@MYeWb@Gi3(IXZqu?zftejSa+pw?@!C zj|vpv?+#WDj6&q&RfX{PD$xUcCA#NT z4evN>z*c@jPab`Q_^|=vz6ON%X$M=`0`Cf&fo3Prt3xjms?ocgQi$U|p~RRb^fIXx zy-IC>_l>P!PrISL5p3{R!1)SxbQaz*j=_7xFOa9;UE(Ne_)v|is@lMwb)#W;Ke)Wy z331gB*vJX6bIWLPVGwN7FxaJGxVIWXOG~3rjzOM4D=RZl&O%=Ov!ee~{*MIye@WmU z=a~E<3W`JWe{kicWfcq!6=bD1T4ZI89NfjjvrGAij4Xi2%N%B+qo%{LQ!}c|0EDz6 zo9bmUY8+x z+QR$-4ILeeAq9ouUOpV|l)3pSpaJzm3I{m(F4^0dSeziE+^uj(URF!;lD)m;UJJVu zw8v!Sk+g=CnY|7NhlIsdF&Gc{(U#QX7U1WS5IT$TgJfki&Z&usil`{A^9vAvpAR;N zf6f>C4NX7w|M~B4{58~7w$kpv-sx>Usj95C@nakKB@Pv|=sPBxA;gPLDj(H$iI^yK zex%>#y8FBA^3AEpsYqgE#G{h}<1q6L== zvkkI)zxHIe6=aK^%Gz^3R`q`To?waN{yR%g`z!CLH4-l|5|6oUcG!=j{>PWzVB2M0 zjqUvE#trV%N0#qRyY)?P*)3_m%i!e2rjQ%!#cnYI{adn&O$iBi%gY_mBz$JkB7Kdym9D#XWgF;kS3FPUJn65qUCMGWni!YBh)!%{^)2#YI|wOtZ5Nbcp@1SQ}h$_9h3=A z&!kv%U8s{t(}TaK`-atGbY5O%Wwji;(OG@9Nl!jXmZG0CVL{mQq}o`#scsTIkG$J> zU2bnI8l^sww{PrmGc#J*9uM=~hhD}$N#A)-m^#DJ$Vm4h{H(CJuFeFTSLI*lOTW$^ZN4%3mMZG3U!p~WIG3l z+|=l}T7}7(4@SIfTd3BG6vaJ_#61;xQE^|85idH^tZ{&@#Zrn*kWrf=(Ky;HOnfV& zuSJQZNSN>Dnj9nDgVtTE*F8NIn`v(JkkJ{m4J`jKP@LuKU*_LFQ$7vfG&9q8is@U` zm|OL>hNv;aXV{TFL5niShUja-G@svHRy%R}rrX+8i@Dk{2UN8;LFG)d+!8Fm9N2?& zROTmOK<2s3$HmD#MP(`0?{_^|T8=7M*!+jS2&s)Zyu<#BMLJS+t{s*R!s$(7hnNBX4h0S6k@)sxKm?M&fLn z{kGFm|xSOxe(e?RO}yZXkB!Q`TP74{!MsgC43d5s^Fmc{i^K&Cp6QaWad38FH>U4ck4Y^ z*J&acOl0Ta`Vc86vvfFNVQbCn%RlSy(sP$Hi@O*$!RFW+Y}ISH#i+`6k>jQvcXv}K zToJSTE5{P-@%PG&N8kFYC48im5B(IUCuP4^aAlbMUSA8d&i9VhE*4tK#-_*0J8>!! z1jR#~N@jO(^YdG(&8}zZrHzan7`x8D`=Ln04u#dnHeIhS2!$M@_aOZU&LgKP&IW7I zd*$#UIkzJT3%*4~zs^o~XTHfV_K4p7nJGY}%$OnYxT2zlaEONR(?@m88ls^_;k9u zJ<)2<*;>PLfWp@}RxdS1FC|7pDCR<{f%dad@=Z!K;lZ0Fa|IfknjT!0c(}TH{Hg@I zaP3#~>)bg;$-rohJ^6Y?o|f6;w9NK<^)9sC*yMd@#a({o29KLOmwePV zgElZ8G<>3au` zk9z8JS8B08>14HG&S+_2I`$%)GDUmK;H+T$fi0>@2dal1Po(HXaPjcSE{{BWRczU{ z6p)}b_BCj&pSsze<$wX1cb_=y)c{p$KfhOrPo}26eJdt)eoLPopZ+!-aDxBLtP7`? zCr^kPWrsfZsvBAB3$m^pq+k8+W|5WhG2Z^WebavFKal0I<*|ppg6d{!VH&dJhh$t? zn!hHFPE2r)u#OOFMpQF(6cehGLVrd3YEt-6rz(JY#+(f_UKZ zI8_0L`1}M)8ylO^si_gVE0%1diU*tna*Rz z|I*%s+tRl0Mtak_amCT`)Jag>!ZQ9AnH1ksl;>8*G4x%K>n}BTngU(CU1ZT6V_v&)CZ13kuYdzCN z+l+DgWZtJ#FQVw9ptkRVwZ6-?UB2BjZPS^RFB@X{&Gx>u#el~4R!inB0lHvK!g%@;!Mn$*{c#a8?&0yx7Ec0>-{?9>Rc5?UVPa12(-1#K zL&n?U%R=M1;_jJ#*ZeR(kt}`eY|6RJt+cA?eJX{mpEaiJ-?Lq5d*F%2){ciu51IBPgb^c;naN*aru88b zuBdz}nxA?VC2?jxiT>BT0#6w;Z(ckYq4*p2E-tbO3!gdc-mNx2J7_m$Wnnvp-#sYM zzswiqe7ZBBbtydYXqzNB0kJYyg=Xgyl83q1!E4XWaAP?g%k_#&V$x9gFA>PqfGE` z@;np0Mt3Min3h*eQ#49ZYrAbLF%KVkDIj^KLGR3q=1tkB%^UYv4v0J6QIL@5srOMz zt~622$%=lJ%X;yZ!8dYpr%?%&X5rF7tuXW0_y7su%LF(kpQ!eaKiqah zFqlTAZ07it2JfTotwOa*WG6(a-)MLmh?b{o8$GSb*mquIoN83#Q%_bY>&LjC_3j@H zFB~Ov%keZgoW9xg0Co7bm7fh#Tp)~Hn=(Y&rOL@DYsjU}C^j2ag+HRF+W&QVz*>@4 zAlUrdXvuhMYNk^S%ciwE+xIH!358~6JSxv8%3K{`9XGE{*L@jXc*G|?eVYK|=Gyv% z{YQ=*n_pe4t)7hwF8kQqH!?ZdaSL z@RH@M1d(?K84JtxYO{Iq2lHoLWsXV?(iTnOcf|0bIUl*p9+OhH+=dQ)IDPg?TKbiY zB^R37T z$IVZ)mg++225$*4Mc7@DVS-1cb)m6Bw7S}4Bzeq?#wFQP((Fh)D*#tM+z&O>ru7PM z)wS8a9UCz{QdmggudK8@wu9x(S5~+5Nv_syJ4$$Yu{ zn0BjAwpH8U2#4K`&%9wz8Sh3Pl$Z|)J1l*-BmY55<@XXxq1FeHQ?>#OXTl;QD;H`b z^7F!oZr|#p)z6%c_}-UvHtNpY*W#7qWEVXZPevVrw*_);=dNF$XO&-+&F#*(wHSW> z!_}QkGd~DoOqm%Oc)hxQSB__^%DShI8B=69tgXcCRb~MyO6TUvO~!?W!|uG^CwY*%~y{W9p>ue^|GAa7gVS5i8aVBzqE);ex?@b;n#^8gi`r3}nyu=cydMNu_%$Q8`4Mcajv0C=9JK3w z;B?V&>&{jp(Xb+)s2lMt@_4r1xm4$G&Su;68oRpg+V8<%|7s>4TCZJy<~f(gVr!^} zjI{Lf%rf_#6-xB9ON}FHX2G8f({+j`O$Ez$#+{2YoWAA2gkQ_-2#f|NHkhcAW|pVa zTT<(HWtMzO|DBa>SB_8A5z>KMD>DTZ($aoi=|wv@+R~55=Ca<*zTdQR=p!SeI17u> z(0oSf`Ghk{p^tBoUEe2o+P?ijdWu0@BymFd)vn99dN{YTm#ON#QTze%`;;o99AP8%fw#8Y-4eR* z_+rGE@Tkob7ZL5D8(Y#|Rn2odbj7LOUASdHza!@ix!7>$rH2&c6S6d%0VOt3-2Tz+ zOjXJP-Zw7M?z@;)7J20MBTE~nr@ITTaYZ~MRt~jD-mlc6NX3_YZEoyqyK7qWouGbA z+;xf5K&Lvw6%_Ej`oq9q%O1a`oIN&CZ<5cnEv?!CZvg3E#XjkEo_1eWu&PomPt`vRGFkDYbosh`(RvF7gTpCu28 z{ZQGpHNe@}Uui0-n*SaCmb70QM{I-szI(6V)EFh`Ifyb;x}4hbHdL&tPP*qFb4_Tu zgosY!=H@JWTQjO__3Cjt!l@#Tfgvt(zQ2CSOYUYoBr6q|pPxThQIXPUxVE;c;+Wq} z&*L%Z|3$;ApD|cI2Z_7&mptb}AOPKa2G z*MZ3!Yb*P|&xv{X4_0hi?b-S*)3xiMvesUvhnzw?>zm%yKSQo@>FiSe5*Yh1YWTrP3I7fqrmAP*4LOdxZccXkNTpsZ z&k+ur`k)$oEy-bIf+^@rwP(!*7E#0AAj{U0vF6}v(b}_xtDiY`tDJcFGt{qWxiG1p z^T~Jr*HrR1k-fc3-ZQQ5#2*Ut9X~HoQNIEg&S!4|98*(oZ>aQ}4unc)Y(M!W>X3tX z(aNBhhU|fpQ$=R{2PeAy6(#RaaM;D#FVH-w6n?2je3fyTC5>}^4T{nCU?ZEfvS^}wLO!j-`-^kySpc~)nGJlv?Fc&+-cP$Dd5 zF)X~bSX?-t-q-cHtxa}2-QiQt^Q+{t4Ue}Rp+GshzLTB&74K_n=^}40=??8yABYU( z$aMIszCunW%z60U;OrOi>#ps-WV=0gZGL02v!Js<>KG-Dmb~-(kuMy?)_Wn9n=~1m zg?ez|Q9@4QG1r+gswM<&*_kqW#Q9CnxoSCEC)1UMeto;kQLL(U2+a!!Y!y8gDBQr% z!xR?BG$*mU*Y;uTHl1&?o6O=gIUh0X-bc zI{7BZ*TUFjkWPZQK$JH07*5L!zCv0YnD!urZvR|Tbt_Sk6wP6u-!$Vz5mhjm)Ag&l zXSur|E;aSdu{I~BfJ&-@#!aW*OukW%6@MTU=`y&P^ZVHKytINXQ3XG27t-~7x>H~6 z{MmhdPvFBcA(rQ3vXyHroo8;g8+mIo{ z((&VR4WHC>O#;adjCD{Gk~s0nh87%F$~}3>EZbiBX_1|tx}BwWTp+5-v02IC<~9Y_ zZz8p#q9$M72ciTTN{Z15a~0n0ikUjz#(HYRN)z@s*RRv~mFpC};|WjP-Pw7#Kq;pG z^V6pz9}A|7ZeQIiN7m2Hta|`&XJ6cjagbKYfxtd^xdA z@??}2quAO6<@c2@K?IR|{UwFVCYA34tGN%~TR8A3TJkW}8|?*g;oHycb7L~ur{xEx zMY&2ZM!L)g-zqh8AH2S5YdiSsQyTg#A^Idx=*B+2#|7kx9n1wMbfiv~_}dd@_6iKe zSrfdpc@{q#P=~>Ld(F%7MycD$X!X*0!)uI7UW1aGeLVzGXGaRPzaL5nlEi$i zUdP2&E7G8q$4d5(&o6b~e4Jjk%EqqY&gkY&A7PBztiZ=q6~vPi0%(R5a;{BIp4_TCJl8Opmi-rrIzlIwLh`J0$jgqzgb))yEriyL+k-Pdx7Yi;Xo|in z*PBaEcAvH<=KJ{Xv%31qCR#1p$XZt!FYw@UdDn+>*6-WNm~tXo<0hHK%J!c^YKogL zE%Um$Jq<2#t+z^YY<%){@Ep10s-vv7oMWxa!LFS+H9na*|0-JJr(P6n61Ce`Xek#i z2sN;>&Q1{cRlm-+XBbn^cxs4y=Hy(^$+@z%y5As`9j;queo%l4u;UY@vU8npthyI* zeYk2eQcd9h5_#EOxJiWp`Od~c!&+MKq-s9w|0I! z^;M%^(GOl-yDql3)ACu_*?d214^+RKxeoDz#!zGH#}_BRH9oFLiNQH1JD$n2tNnPR zbC+MK{z;2?a?yBnQr#ig%{J5qtb4nYclsbKH&UN7ui(q2XY}r6LemBGD)P%A)n<88-cqt+u z6P&N{+~Yk7a77ZUm10ymXG-JiU7DD9)#`QrYPh+8w!GWQOqHnU41pZ;D9_w|CQT}p zE}9MWD7aGfFz`-sU)7y@ON#;4lnbeYU46d}s=otY!>z}u{m#$DH4-PgJ$UfQn(_87bK?R;}uNq5EdQsHX5_RD)s z2@+a9awZ83zZTo~*D}+}sj>x}Xz1p|yxlGMiWQ~+Q(;lF#zumY1bf@DQu`N4NzU*h z;2Xi-WoV*B`%KDr{s?)A^^>3E zSMjiRiuQhK>7bFTT)XCyc*01w{!O_DbNNOZPpP8{J$h_iK|-^VgQ;A^W#K zd^SIoP9C8N)MMA|ofYs`*`@0#U7x{3qnUsGo=bYG2~!*KTHKo8@>s`{9j`jmh}D5l z#zTd-vezlMZqicLsAY)0qrc-L-Qs8dkZ*>?vQL$Hj)o<`WvP9Ci}e<( zbiKQteL+h(Ox~qvZk2)V+yqs&@D}3g@lE7+78Y(CZF8GVua7k4)!_=f7xeJqLs8XM zH-V%5$LJBYuWx$()c0?sxh;k(Wsy&xKD`->lP(k6nx%Bhf$)iSrtjBMF`vC2#v;QWZCu=xLgKy@0loN#*&SM@ z#(HlOH`i1U*v%~Srh`u?i8!CRzs26!Yw>R0(`}ci;)^c%J@37BbzW(f^QuN1Cw?#9 z>fRv-4l(t)9FffAqXq{jd*9e>nv+=w7wnZk;7=f0Sa;=YZOOrH^LvDs&R1~J8>sBe z3H0$f-u}eID4ISzQKhT1v%pQ>=86D=%wY)$iCpDe1%|O>Td}$3O!dC`YA64rbam9))IZw9pJdK#w)L2a;IER! zPe*u%%x|-^JsrWZZyP$MI5Z}e5OaUCSkH}lAzS2hiJv(4j-J6=13gg{A>2Dfxt~l; zZE;SQ%Bf$u`|t{Lk|Edm9UtE?F=@}9&ph<*OEk)o{G6q&?3{hSyNo>Y$So$W=g-Zp zY`hY!u!B^bZfMJK%1d*razewj7haCSg|m`~NJ@@kNwEkU9VhnRYxt69^E_XOq4cCU zc1+eTfAMp1A?eo-X_c}89rtZwNr$p>g&Bi>^=rPHiQ8T6C2}dlxN6%~!`oZ0lja!1 ze0D0N2W+9b%C(QFwdvX{-mWEeYko%lWL%&cq1L?PWe8=bRsAU`2{y-rLTV4rw9Flf z-aaOBr)yF=^hV}MmDdND8s;pmQp&x}dYMo57F92%zW3J_IsbBxm}={;F>L{6{zC7w z%mEKBSm8xPcV0*t?D$d@q3egXr`@%#5%IGRo5b#-YX zr5g4s;{6IY-L77JQB=kAYawP6Ho>;3uH0$6sr;{zXG#@$Cr-?bvn;rrOVNH$TKhrr zU$|s9NN-!rm6CI?mNaoq$8G*hyYGiGC8O>Sr}d28qWX6BCoM^C*U(I-QQo^lRn(xD zy<&tZghJ-Xb;_T@(o3Qx))4a*FP8@Y%hZ74kzz&i``b?s@9Ns-i*=4b61;asn={ZBkgw z!>=nxyt|a8{em~NE-opFqtvJ*>a;-cfc@3fPf0vH4vPJ>Xiadeq@kf+c4_j*Gt3jb zUNTKDHF8VKS@v1oz$?=CR}K56{lt22i)ESM#;!#kb#T*<@S83w7-G5|w@;95t2KFg z=^oC_d=mVpJWB!|M;LazG@CxPH8_+kf9<9DrM+>FRRYtm&nuEsX+CUM6?nxT9clIX z#Q2ADA=77%Dju5)OFE^ORY!W+r*}VBsYt_CM){02ilM(SZ)l}Rw0}nZ|r&ykz z89Ax7-ghsEe|nxyd+#fifLiwiMxsZEEHOY)dpWJWZ(`f;8jJ6~^Q^w%fL z(tCek`dvUsY8x+6b?5dOe(r#shI?Z57^xrc@b&WX5q|sjFpk#8?Srz!)bbDMvA0X# z8XGka%Fe`4dDBxOy2-xc@4g&%YpK-SE=Je(Fx`KCc4c^>IqKKGpT87-@x1mZr_y(y z%vL2WB1m#5Gn_(kLV_DSU4{=dv{5SAFs3R7FYRnXn(TK?ILwgKIKk<9_-VmQDrwHY6%n z4DVp0FQa@kNnSd{WbZ-#U{7rgnGzLw84J7SHkv2r%Y=2R(`g5S-r0nPlI>A?*`T;n zncs?x`wh2x=@b0+7friZ-Ia-RwKOm77hyAy(iOs zmFYOh`)QsXcNpW@!_;8grktedwLYri~Gb(r_z2*0C` zmZmms{>h?@>Z8iWy@DB5xz@*<3tl;P`8@m1FiJx{Lo0VGCGX~iw*C9}GsF&cGU^x1 zNl{%s8am~AjPJ5d_sX*_?$5S%T(q$TY1iLWHwSXB`3$B?8c8{`J-@@UWt6P6StV#^ z?`PlPpFbODj_$-AlQ&duJu>oqJKW;N>IlUY7qi}p5^L{{P-718aS;u5zasiPU6t#H zhF1wpb=_Cb{k0NQ+zJ0&zC3K%?VNj#%@=Bg6~1jpmiGKIY7@4cV~IdvGjW)*(}SEV9YM z;+0DP?Zc;+SVQ3*0oRkbHX7)5_Q7O{OLKvla9HrkF{`xJ4z2!J&fBMQg+{zf;WBFqngzHUXJsP4H$8T-P1LcQtFRX$s`5wJ>4#RIA)w*YRL_m@FCUnc= zQWXmYr%XUvAm?ad#!dcd4xk?CeKl z3%P23{D`sI5pJR>JQC4C=F3rOviYe^Olm4cc%sze!a`bBt=`mVW1NZr`JLBfn6;gZ zBCUNTeOa39l2)bKU*fITEA{Qkp#Sd33NdbXCd2$y!K|g_D*)_uWtY-3{E6Hly(jfpw2Cw4lR*tTuk zHYR4ro|qH8{(f)0wcc9y@9w_0_dTa}?W#IfcG`BjM~gS$xYa*nzH}lxzHtA6BHgEp z?e|=V&i5G6+?w-}Lyy8CV&t9!UC027Twl~#p?iH~!%nF351}c+SG6R?m?gD33>loF z(7hZvStTH3G9W`X>KIZ1YOT^CupqvSw@=MP@~E{^h2QZmnbk6}KQtmaisUz1eL&b3 zmVlVitP)wdA&&9k_*^Hj50!x-6}_($(g7h(V+!I?$aT=yUP&*SmC^o#v@p@yG|ZuE zzCdZyPFc5>GY%cmuPM0HjxJ@c5aZ3m6#AVprLeIP3p{QI-*oy5jM))oDk~XoBw4zA zoHQ@N)61I;#J|gv)m2U*38|Rg+W$42-di0H{x@qN|DAu1blB|7zkE^=0RuQ5hsm0! zl;99J(~}IFxo>R1->C*-yQ?=LZp~5m@;1&g2RhO-jO7W`)VhM0lRq;>V&KRy@Ajm-Am`DK^h!~|?op&~C_I1HzOVi?&S zAr>Peb#7Z;O`NpxVLT9I(iTTc`oWRfO|7NiVg0=X1%9=9W%rWoOY?Z6g)k=v)D#Of7U+l4a_-fxQhyllzfL z)rbE5+n|)kI7%#XJg0c~52puu4CIQu$Wk41^GJ)DZwxq9_8;*X`ERV@b*6tOWqt?2 z0`?Je0Q}l{Tl-V`(bLIArB^v4^e71Oe7{@C`j?k}+8cW0B@_lp zxU#&Od?|#y$P$Zipd3u{)}2%BhaTShC0By2QxAlO$RQ>kZeGz3H6jBpr%=f+3=Nq4 zfCv!F2X1fMKl^-$u*b{i;0dY-IvtFiD^~;2kfFDE0C+-4TV|_7x()pB5`<^ zmTM{00a09$)!7eoQh!OrQQb)LI@zS3xw@v+NjPXgn0xFxjQpheE#NsMQ)@JxR=+MC zGhYHv&{A|pQ(E|~Cd>)+t>-h{aBobs@obJDpg64a7~!CJf3#8qYRMV}?9QL#Wd5@@ zzvY0pv{?_Pg*v|b=Uw)_LjKp6+P591fJyCWp6$ALV4PDitXoK~<}(8M*m30ZdG9~D zi#j`7Vj>CV#QrxV;p1L1M%v*jn`>olSylaEQSG;QJt zY(`J$E49{Y3G3>o)G+viCD)1198dn5_V)Q15{~o9W-Wo|@ja5Re(XAYM20|^YlUxm zbw&0Q6NDEl0mbn)+erbDqV`RA@SZ9T4ep?xyr&GOq^?7+U$L);Ty6Fg2W=!_Z`UyE%CTgh{ zZ(4ncVe>t|Vrn0?jJ9EGj^yXyzEuTNXN1#Fh~5rv74lllO{UXcxjvFsng z!B*~&9wvBM@APdBlhtq(R($E0>TyuFKUo9{$h6%n^-cPATcTxC5+zuLO14k24EW+Z z#|+~45o94TZPt#gAns3}%+;|v;q z;apa-?Zse;g76`e8|ilSGlo>T+U)F%iCw5S(LW%*|K4T+0fD#VSyz{))+AZ8#Uf%2 zr@q+iyQeYASfj^>mFw3|H&IIH##uo)j@&0@$+Q~v?sH@QiP7{rI|~ zGagTYRmN@H|B`H|0PG7$VE!s2maW*<7J$oJ!5Y%0{f|@!&>XWj>8DHe|ez@XJfo zlMdnaEZa+tsIx_|O&d>$jB%$G79jrmRBO;_|NiNG+{53BUU1s3N0M^*1`h=V2%SaX z6pI_5+V_7S1noO_3!a>jiu|%gZl|2NVxtp3ldZZVk1pdu`cz!%G&vx@f>+y4Z01Rx zM1LYQ3NNZNB~?rIs`=F|r=^eey-6k`#H4t?0P#@~_!68au4$|!IP?sQ4Uoc`&UIJWG(cNRxD`uLLW>J7!?Xmeh@E^TM z`UksK=ZY&?Eo8g^B*TF>kB9daB=^HXe)M*dtfsk&MCRLzfV`}y@?49ZM4@rf@s~|Q zvcOJNwpjHFoOo$1rJ+o5saO&g5-?ci0;EW^Ji);GG5)WJueN=kxcdRx zp*LFEYteWIlsF-+H=aKzW0n6t|8hECW(FFYd>p14r%oogK>{8CisWI+Z|%iV@;5OP zRDt37ahoq^_Dg0wRCjabD@$<_)&QjozifDEP`E|fl62dq%Gr^H(e67r6|HW!!?{bk z7jVqX5&^|j``DKzx+%ZZK-(s07+GCf16nPa(*xW-3Ky~Xnid9$Ibjh1^0eTX_|%Rg zqygjsxXz4SHBpI%PTknoY6{4RdB0VOCRqxkIc>FCNrZCIz?btW@~pKsF7lv=yE~ju z2WyrzRcDlrtCy*%DRvD0Q_nQAo*Mvfz1M&3Y{}-s2bAq@M+yD!ZGhsF>xXNH5)^q~ z?e+(b-^+dCfiodD1!gSe(`9Fw{5QC&hMSbHIn)$roCL~|5L|g|0mx*?0t8(Q`ka8D zAqcmySn${Rh_vJ1xh&yar|oA4h%VvL0TM)iHIDVrRdQ8-LUHJ*GbQhtK*i%u&}nOf zh8{&dyvYH|)`DNCG}CZI0{`HnPIdXjI(9~pu|D1Glvox@@Vi>ib(dJbCcEOrtq*Ll zwqx7xy88aQQxP-LtUS4Wy&hO=Y_lHpYAV)=4;xis(JacPrKL-qyoP&|rrHaWD3}+^ zpHpK=HsJSuynx)60$l4~f<<<(_u1}S%|f^+aOUP5WlPq1i{XKods+|~B>}30?RpSO zf)A9Ny|(x|ULDFAywQ8BX>?JsP@2821h9XcLzOnWByf0(m0!##wl${_+x^1H>CtT! z3tks;C7-h0`@cj6sveT8Xc;TX82bk|H7aOZzvG+sO#|kJV$Vj z5<_wJ{%-c?qhZePbGs zIq8EVB7o2PzYhDX9~ZMC3RshH|LW2vDN`A*-Q?xvDbm9z)1{&9yLL;Gdp{m(FMSS| zG)E!QJaPjAQHEgw3Ow{7Gw$Q-AIg|_e#6xS5myV;uP^BOt|7w zN@y7?wV~W>fQ=G5g)B%j7W`IQXvfOYqBgq(pgbU6j+%runSMXzOxwS2Px4Kk>PIeS zFfN3WEWKDUA}$ls&o!nN+jVHfzN;r=H${0AofMeKhPkyhRItGZF0g+_r`pTO*7gE< zn^tqD0pdUWBMnyC^?L6FfI#PH&rqlLkn&IN%LgxhZ~!2Wfj`u!A6Rsz---(Ej$Q^s zRVGb~w%H|0Z+RJI*aD2iMrOo3y3WSCXM@$2-HZsmHr=0ZwT?T^WBBWiGC{$@=?BB% zAUbGHg`g5E%e5ZjWO;%YELsm?0%GaY#r_m>j+rEGQmz!<*tc;4;;i!St&~~uo%bV% z@9DnZQA{{Af>JmbqtI!{tvgNca(XEysDlf@9KpTM%jB3TI~{K1n0aGbcJ}b*CXsbB zK}Sc&99ZyJ=Y!9X?wO<*9i%#swT2tl%CRyZ&b}R2MY(52hrsqc6@l)Ec--QMZ`xx@ zlde^6y@9*#LL6#tKF3vu4E63SJ(LM{coY>6#4w_xhR!cy|EIz?H8I)b0UJo<+I@Ng zpCF)F2>*jpKC|z+o;y2d8jPJs$6r*+lk^)&9fLu{fIa!&V2MB4{>Kc93ks9CnG>dG z%V4aHL_Lc7yk1kx64{jhxK7_66G}$8E7L?TzUb$PV8fezeDO}22D=Tgx2dD1lPpg3 zaft2;+xTJPos7g$xeAkYNaoYCKAM#8jE&7dF*oYqPdLty;@1Qo=C3yWX4VL>ZNJEv zV6F)#0t%zcYRusPP3;4@ilty+SV~^_Qz&=z;(|%F92l#tsV?Tt8`ZFE0ggLAu-3FdC80OddDN{A*z<0D_8iV*M&hcR@zbnCwmi%)* zA0bkm7CUkJY|)RQFm$vLE!)I!i_7px#Vs+~kAfi=5?I&VyNIMq1Oj#j-h1)~PGh^h zOuGY20Tb3%C4521@Ov_B%Z*03?l0(m8}HPm#Ugp^!m)d&2&ke=c~+f&4+F=7eD|c) zmeD+CVUtf7_=YBcMIJ-Xyc*+U`8h&;w`!AO6IY}8?cb^lI&s0i5=-j{@J3Ro&T{7- zIZTm}C=)DBE{JP$8yiKGDeQK!T1y5H3Cx~M_4^3`FXv4+848)7`!!pgH7vNYREBiY z0m6<8x#-6$>Ny^7p>5se2;gj=vY9C|VJ}Gaf2S;Fqjc&*E&YmR$vH^hPch&qZVHNI zsi!Q{+NM-o{&qrX`rhfLQoUWwHZYxZfE_>a>-EINQBaUo{w6iuH)RtaRhA69@(gQC zu2&mHA1uiTlL(U3JHePvWkJ$0dV92eVG1vt#fVJNFPzO%OK;I9Gz-asl}pxXnPBuL z6^aD;UN*&=$GHmxL~gKU$ZkT59q9YK2~%SzLLYxKGZLZFS>(ugo?xOw8)%Ggh=idE z679+vH=4cNs|QG#(sML~(d5p~ z2dls5NsSg0Zf3TeGYA&Fq_@N>ukL0qQaIH0fXxjB8IV-K<_2lrlXpwiry>FmK$`h= zWh0|H$5(y41j&@k_KtVG@kf+k%l%?d161+lLsATMlKur+r`18~TlO!gAZ4mZgof45 ztG`)QFVvMH16;rU)aWpX7vI&Qf@Dwe-Z=CSWc>`T-Y9$4>gH7tGs!;$H$%rQPbQHU6;lq19gQ1{tVnMHa zF5ZQ}TZaD06hF%URmy(Hxx@3*ioW~b3R`X^**_7&eff{cSw>{^@(NoA?2N!OM7@@KLWsVU{{DPc-_uEVn4o+|zHAjg z0ToMs$c>ikdo?8!GcVM0HF~XLOvL^Dx~=bGSsF_!!Oy$Wu}N7LUh-KNgO?aesPN=K zFi|cl8F0z}v|HiecU}hEK4uHfK68C$_RcePKAX7p${$Ps8vH0Ns_VjLu=j@ z<28?&44UY&9ouE-FT5TeOjxrug67%q?$cJT)>qph10Z;S$GkeUdiRs5J5U$$?(zb- z0YNgqBPLsZM%Dq zn4Sc^-4Iy?pRhK!K(W$t921Ea%IVp6mMrnMEGW0JQXS_zTLL~LE0ib|yD-#B*=8u* zu15lnoS(%={@H75WMyV}uy20CZ+^Wt2u1Ov#LoB(N=G%n;udUJy_^;TRp?!Fvv_Jcr$t(K0hLH{n8DN8)4I^!DH*+F)^rV zf`VmCOnEL|fvuv->hlb5ER+zmc9hwBehKuSuqjQQxgnB-QWhlLUm16#$;FP1NFOu*~q znO%dh!o{eFW)bCNJTFg6_HyHo^LP8S)AMcVzXm$bvr?szzhF$=^T0fOc6K%k{M20^ z+2K*o`8wN&)5iEY8R`@7R}M)$=#6i z8YqBPOZ3zmg~g}NvRq+F zJRwFT$;bqk4W5|!zcko@*9~8YU13o7-J$*jCRjsax!nLm{RNuHJlRcPLgCQYEv%1J z9WRlgmMiGSir=o(+X1UbT0(Q1k3CS=fc!sXA>TlgLjwo zbWu&sFJN?Q`-rk?UtB6I#52t~rB)EjTu9Wnn)^TB8KU)#qc9`Rxm2kWO`o2pQNM4?IX=p26N-rL!q3XhzUe zZZ?w*BdO?Dz0qp9r4RnXl%|KNeMxYQ`YU<__q(#B{cey80xH z&bX0Y>|F~G%3$C9JttV9KEJdC)7VK^{NkBJqsU)PDNz#lM`@YX4L*VlzU_P8X& z-hFywKro*5=6EA-803%oU=QA?!QYT>AQvp#jSw?6usN*_89yZ4hz{)G7ope<1A~zG z;lk0FZq%=oj@lwS3I7}Gt-GG{yq!*W+8bo+PbG-uj|Fkbzn*8HqDREXV-UT*%>J^e zz{!`uTzWySIOXgM`J)mZHV73S8I?~hSXExcM#9H@*@^jRNmPP@w2+*#Zlze~Ola{AGg~sU>Q7g$ zlL6V&3-PW))7Y`RAtdiqU6inSUn`o8E_*4xB$tgJ; z_|toNS?N~)z>({76wUMbhurpUF;CM;U;Uqf6#Z2QE$jfIa-c5pSqIjx`d5*<2x_VV z6(V}v`q!gOQTpFj+G&Pb2h9W_;f{2{B7I7M`Egv_ZWO+6&%avut{Z@T)DV4OnAP4` z+j=Fu>2+Rxj`X`AW%i4aPD{hC)QXEG0UI}8NTIMlL~BzE8G3X9w{YzGUP0<0VC;FU zW{Gv1r_Gbbq7aB#oq~uFv|nV@fN%3rD;&t0{w5Nf>uW)Vjtq-|3>&}NwHA#K^(}g7 zhk+igREE$)t4?k!y#qUXI2|F2CWpD20vBrB$GnprACZHAU&3yq67lo*)SKi$ulm8K z80gR&EKOfnSO62@qVDcI?8%6@+g^lj)ihQP;S~15^rb;f&r=%KfgD>OSX|3u`YAsz z#h?a)WEnjVA8@|vkMb8|{;1WBRcH8Z)CV>xI@cAE5)>~=vZn(<$7l))+0jSN?S?bO z3*X8tV7rc8WB_%plPUZ{cj<6K8(UjTPWE1~&DPUjq4h)NT!}LzjkIxd-cv2=n)Spq z+29M#%St%v7;)$uAW1g%gH<=RHH7O$(O>HhUw1%Og(uCKTQ{Wv0ki%j<%AB{v8-Yz ztV3CH`njya#WP}H2Y84wT`>4M*vaGg&dYstGfnRvFAb%*zszvAqB4um&f-{-IzIKL zKTea!vVdvEpp4E9Hnsc{9PqCPIMUyD%(*{mS1vhTZho^}t%C@VfJ_H-5BsCL36eWR zrRhUbwg|P8bS(o}>S-@;EScJP~ z{c%BKja9|4aO{Rb%sZap_Y7tE{!EzO^ks7D_>}`0DqSA7#jdct9O1n82E}F5D-!A^ z$xAX#_6eHY^CF|eE2sBh`Dak7SUR?25qcA)y=MUuG`Ddtt&wvznr!@f;}_r8r(W7! z!wJmmBa4)Nuz=`w>iCY=1HWnynlqQdNsZ*fBqKj}9AqQ9sr}Z6a04`CkBY zx!cBfe6?@)4f+J^Cq-Qf7yJ;#Em)s>R7I97xLrtc{lVY22L! zSLAy%ml2bCVn86^%~A2*+SFaorNi=n*lh5x`^5%M>}b%7-uAn((g@vR_Uj7Rv4KkL zg|CYs8mDU6fo5J0zfndnf02+?SU24>*$2=J!5>unNO7KKf$6FMCB3<{nHldCv!m%eGS_!&?<- zVvdck-5#?vbHV+^VlrLc8F-L~*b^7lD)TXuMkw-{(|xi5^2qrV@?DH}vC!UoRB;`jQ! z+F5q&$GbO`F3!8o&MtD2F4yXUwl_DsPzDg^98XgOl)gOdfr%qQU*GrMmGunS|Dt3< zs@@@h#P>2ce^?ENGE5*;CLwQ5*^ppJg5!67V9)FWVq{pyy9&0_tR@%_C1CIt?%t5M zsGXI7XkZ8IWp{CNxKHi;yBx-c+5YlewGa4CZyTAu7q}Aa z$Q}pYNq~t``9w+NFd{YUnHrIjEQ zY6Y9ArB#uf(S5N;aNKtMXpOOmA&bik_P} zC=Plh0pv9b{w^t@Gab&EJj@ao&(O_$eT93hGVJa7QbBl~Qw5BK1cwRLbpHhPkSGNG zpu;xGfW6`^u6Zm48ZSD&J*((pMFu>-*D>Iv9X1sGrv4)fHLkoiZYpPa_OTWnua2&< z{A1691_S-)#UU)m2mJ{xsWGTS+^naR*nmN?UmDeOv@Zjx^2KK zXlz{*aqM%2Gv1q*da)mlT)Ox&F=*2*UDt-rTW8r~rfq3&KhoiU=P>sx5*yD{;}#!- zf$t16qGRFr;-e+AA}RgqaQLwS7NRrGJpa!Z&1e0I+^WB<&;@eCkOxYz=-{P6 zP*Cu{4=PtHbv#?MFjni^gJh~k&5s!X%0t$a4J~ecDs5%L>bj|06oA%Wvz(80HCm5E zshfkLrNt}(R1mNVVf}7xlzPuFZa;(nT0pgY<=q>O^cbn#VlDV=?jKm)y)21FaPK;9 z;Wr4iQm5t&$OAj-sNzJ#t;#yMG`C*1IdZ#KUgO(;)NER`9d9NWN?lbrKW(>jI3LgG zfe6?&&Do`Ih|Xe>i9_e(uZgQ%?Fl9E?Jk?QHiv7OSdAYJWZrf{g(Wgd1g8L!)n_gE zy|)vUZVF0Dz4)~dP^&I@*M(>T*CDMv4|bm$#I3!5BZ?1kY;DyG>pwXalv$Gdvi1oL z{UIInbO%3F5v0|cR#xI$zw3tSvulS%zhPM^k3#t}@hjpni0z+>WtOOL7IYud@m8*= z80rk=@Lv(ZADBFoU87BMN*d#N<`jZi5^HNjFcwW~KczXQy`Grl(@2&Vx-qQ?J3xQ^ z3un|RaL~gxb>CJ;Gd_5naC^Q&s_apQ@=gB(J;Me3KJ1U7lST?`=-eS4h^St3Z zPKu!q1Okwgyhu8ZN`#_`E+<(P|Hrd(p4w?)0=WRD6^SIOxbK<*oE@Q-)AGi(UA8%t z8b>3qLU69TKTr^*w6il6?nDo3TN zVmBbj6HT~@#n_L`m~lnxX%PVQIh^%>p!2(5o9*~c5YQ9MT?I|b{XzF@Smk6YoudL_ z^P0am2rOJ7UDSqtF;SpjcEB)tbxi39Ms0@0A3nN(_jy9!Aw435+nQA2M1Tzdjlh^( z8+N!LD19y&8h?yCl&wIAA3UuqueLD9_JVAEOjfv+S9Uh#9;Km_bC5KQx#UUV;|G{w zSP#(-_*TmHUygGYX8Hs>hmjq>HZX}-|A6B-`A4|j!WwUXUK*~%cTCPA>>={{b8 zdcloN;gbDJ{ipIZl>*@4x&Ns*)F1q(R{elUi{~P!p;Zr)6*8z;*Bj(+`ar2l7F4S< zO6gi%CX?ZysL(SLD8L=W7(5Ln8BohXh(rC0tkgAp?avT0Z_EAb-@TQoc1U~sH@#2( z-e}*aml)BRY3uudw&oe*GiX%}V-yJ3rpCn)2>vGnq>o86%lAIksTw?cOLRcN%z$xU zZr^mdH2loLol}s&)>!Kx2mjp&*+;Ta5cbOYA4IdUrk~}`$EL}QgLCAfyHF|SzKcic z9BBq^!M&do;B=Nww@Z4}4vHu3`IaDkmWsD* zv_xnve#_7p-!g%j@dH=xOadwgBw_4rqNGt(*E2;$Dz4)-@s&u5nJ+?9t~voU(9cQ= zA{s2!HTLx-2A}2l-zvNq&C{VB%-X$&kchpgqOtM)RjYzKW_)MN$H@Gm{mDS@Wj^+d zhB#o!yIFRd88jPjpG3uv>}w+3^p zO)K#d@i64Gj+7btU~)zXbNdR_AD{Gdumj4Pwf-zzgfWc5H(E)*<&H@IG4y;oe4xlu zw`%Ow{jsV1TbiO{CBtrM>smQ^GG)m~5C%$YkVVh++d1?|X_OhKxhz zwJUa)sWu@Ul@qsN?xXbIcHyo0jC)$Ebxjp10dih1DG>gjT;Z5J!IZ~JNU7`Ehgho%bK>}+8%zfaieORs_F!J5$z2Ql_-qrbDXyK^nNE;xnM}f7t|voCM`|0 z9D$dgSCELso5kDfdz*nH`VSe4no2ue=68~`^ZbwQ2$8UWkpWXku8MDSZ5|N(E6dkl zc^MFMV5a?VM^g?_v?Lb581w9bx7U8;2O33LN?7w{hU3Hvqg{G$b zsB7s7P^49x(PT(grcdqnjG@i(KyKwGSiR&5?3x$JF(Vm!48yJ-*kv4GEvD$+L|$01 z4&x>ui%V%7L>9D*y}q5>os{khsrPx~tw2KJy?$(cqBeT!m`2zRd5TzI-D0!i&qiHd zUIwR^MW(0Y%j^4hXNufUFn;XI`_@%EgeclH3vTxaJ#IQH8D68^p#)v>bdq43&w_;t zU|yN%85~wV#D1=M1T`IBgEfqYGoOE{p%# zZAWN8J>Y%W4)+t>;HRdjRPqemK79M><%MaLkTjF^O2=;!9L_j7X zbK7^N)7@M<#;eI zvZg`*lBVI`AEWQjw0+2W9`|3L@+FKlbYnJv5ZTz2k!Ba$61NU+!VEi75Z!{{{}J!a z{~t`2$8#F$618Uxb`&SitJE*lNAKtMEB6c=7HG_1u8Rp(Sys0t2J<@7Z?aJ(fLr46 zkI^I`);uC6nT$Rk1&A@+C~`tNNmxm}l2=eT*1Yn!Yw(I!Y2da~i{rf+V9IAfL(`zS)8J`FSo?_BBJb`4|67jl(P&%6 z7OaNu*yu>S1-{eGQ6egC=^YT!=*STPNMRJXh00TbFMYTX&fph$+{a|X{$+#NC1~wC zyZGP{8I@5I9YosK&pDNYskVoOUQlsF48<^ych3^r3l{-O*W2x6+fjy1odZbddQ=$I zeB@=6M0_H>@)rd^d+}D0>VN>;D!Qsd+aFh4pmB)K&|9G?m40m8g15j%wEQSmQyN&DLVAtW*- zL)DFu5XUEaIvHS+fSUB~Uo0|(xwPETN4t&d)&1Cgs4H*MBR5+$FU+-N+ZJUOrJV?I z%}a0_?qlVJSz593sTFeeiJpr~Qi6nHXmTtkL6u^PR4{_n z=duy3f{GvAVe3_nn*Vc;c*VtS@BiRM3=UY3>f9Rncz?YaiS;M)zUoB77cXsQxB1)d zj!yydz7o{mVRh??hWrry#f*Z2nD}I&9l|s@cj^*Hh46T}6$yq0P#?7vW>OE-Yz)_Z zaNnq&Td0j6Z#j~Tze~E$0yQ^WJ=Rv=5&{+01)i?<+1z1}9WUjBn4EhR2{&y6&lU1? zptzU&ZO;477{Eu!cQu9iPSf;!4w43j*ZmyjmRC^t?S!E&mzj~11I~8r#l3Mf5{7C! zKN$!3Jq(ie?8fk4bs5`MC8$?&aq4EDwCg?(GF$lU4tNqtV^S3_YAB}gzer$l)#OvO}^%>b4(5uNm(xitbCwUNekK z>4IqI*0N#ck{I|ZoEK?alW1I9WD8FOKd~!NtbV7P@vmPP!q5A{Bjcex6?-*9B=-lL zKz6-Z;r?jIlRDjlm(lg@8NG&V*(3N{IeY|_JVsBNkZun0E}dL>%tW>~I=?V$Uu7Vp zw*vJ~TSMK!xA8>9T-t#cyT-aS`__#yc36?*%G&nFIlI=aN3S8`09^}!RYuS55f7-L zam}{Cz@hA_mD6(En_)UPYjpLDVT4d)1#0UI*jNQ{R|CPELZ#sY6C$+t8%MrQL6JNY z6{S}^n^JYk3Vr$+V+)CV`zB>qRbea}jESN6UwQdmI+uB%jaEzFO#8jR?MXrC70&k| zv38+<4d{N_K2HNUr@z!acqf7AUS4E(-1_5Kz1xy=P#UsH&4sA z>85De;z03G)c+LqS~@yTJD+FbX9sGkb5Ld!NtmVM2#ykakvO#*lW}w5v?`bri1ox2 z?}C(3>h)+!m}Cg{!!vx%-IWHb=;xV1M@Yn6J7ZUUzcPIMNV12&zdf&65JRmB5gMyE z0VsAdDr<9cGBdr2cX0A1&A^ASv^jkCWH;+3aV zxhMk=_)v-egyy0bS8)zzNEg5bY9N%jTC7Et=_QopZCZ81;V8<9!&mNzaO05+3!H=` zDiZTYlztp2v2k;AH+*BOSiBe|3z1o|mb zE`v0JXi8p(^nvhTz3Q39ixkwojy!PZ7Uplx9fJ`5HPtcXm;jP{AKF`~{loY!hP!cO zT2|O6FqXL-el;YHiNr7+1+yfCglIpO(1*q<3mZN!7p^zzV&jVPnu+qZFZ@B77Vvih z09nKD=bSC*{p66Dk>x|&QYS6V3ht=x|D~s&hFdrPi2E=QRMZFUmcMusv7{2$r5Otn z-2Yf|qWpz3RzEX5fi6KfhiSDR7hC29-Dnluht4TX&OXjV)dX_`a~(eR5W~--ItqP6 ziYPC#EYwDHDqQCLt5TkF)_L*VRp4pU*|K%xKQeUtx<1x;w)=_VE@Lsrn;WhdsIPu+ zK*lQTpqpc0Mu@$9t_S^zCj6?M<#R&ru)%+%2m1{Lh)>U79SyXEPZvz31(D;W9AG)Z zS)ouU@A;S10+Hwg8(1k({Dyub(kFF|y+OXq8sxYT8^+%ctuEQ_{oWr{k;R&tnKAOR zRyBcgymLqk7#|-$1s@_)iOvs=QVin~4f%E!D(o{o?a=drvcJDCQ~hHh*+1>Q!O$u& z7(P3yzO5;&T>uW#0#icV+}2>W=O10eD*2KFxB4IG0$c>kZ=0f1keLH3He;!Fw$5Q! zt`JZ2Yig+do^f9>CaeNq3Z?o1_8$kdDzz)Gfo&cjw7$Wi^W;*!Cw5{$oVs!j(|ZR^AT--u8|V zq~qC2$woUjf+Zb=$dyx<9T>Bh2u4)Wwwn>cTCc}7ixmua=n>TxN0+ZaDj5U!g=rp# zFEyZ37YchV2Jo>NM@l(EF4ZBbohXW!7Oxg=H|1><8XR?8@#3k)=Fo0N{WTSW7=hKM zCTVr6?ca0i(_hR8666(gD0Ly<~RR}!9kt>Rmt5H z$A7=#*YmaU&QH>X_xp_L5=cM1zb132MZ!$5gSyuWYT40`LMIkNJmmOr`0E3zY%dqi$G^_uSCho&wXci@PZz%gpmglC}r+suTMNjQn6!EdY%%K{x~#gjlG8B@4j3qi!73n|Mn^j}Zs$ypy8jhe=3CC`el!#h@Juvu*ye zVcZICwZJK1ui&q2*0Ec7a`-XgcNljrY8*7vP4($h^q6?Q_oygjABd)|up)>p(l0Z5 zafJ1N68HQLw_Zma*fAGX`XwJm_6(go1q}OD?ER zWviUO{`4-4D{rj!c~l-U^1^MH4QNwUst0a(=L{B}jBx99RYWgRQ9f<*F@3pYTs)@U zNJJ{qo`MJ&&&|({{2j`qH;_hup*!QIhY1XJwm_vq0PmwAr6g|x;IrJlVo+^0_Rtay z0Ic12*@~rC6@00>xP<%jQQGaRUzIs8g z1JLz`higLTYlD_$O-6$>DC=5!aSYD9(3w$=Kw^GrN`VJkM;AvJ9vv294Q;^>&0L^e zI1bF6?Zjhyvt6c1+1Dr1H1GFwLw^_(Ltucp$PnNUr=ZU}VQsDzx2`3j6-_a7^5#fx zZPy#-W7EdiGEdU`cipLUacT#0`DWMhsvLyrv}(_p0!2sngu2z=^FCud2^I|NZfsX` z_rDZHz2n$~2?i9|i<68#R>eKe?$AuUygFF19BV;**VNs>ZLbCWm@m6!fBYJGyZ0Ww zV4<(Cw!1qkTMhNR2hd3qnQ*WH@-nHrw#<_G z_^Mcfyx zIrF;_Nw7h1|AnKgfY-bbb~I{Pvjrk;_Q$d61ePl6qA2M-#pH z{0(1*;epoC^yG}pDC8?dpoBY-@I^GOqxtSL^3^{A#F>AJjgBeSS9LGp0*prXHg1&7Tbuf$p8z9?Rx3U-=5m@-GxiHHQU7U3W{V& zo5bn4UcELem*L~(<-T|U5UWA}iURSCR)<_GP6G4Ot3ENg9;oZh7w0w_1%1n$*I{9k z5c0MLGAFd6eBwDkJ(h16o1e- zJ`g{+{$OaxVuE`&So4wT-q%hoeSM8)yGo-(5F1P5`|T-?0hmwhU3sBeKUOw) zqe2A3%lqxy*OsQXD1ljMaa2c%8E9$v$w|4@c&dN>WMs4Q(e;gMls`xPi`2d5A82(H zG)UrL+SOB6;N**?vJAh)#`7X>Q@AI*(R2EsHiMdU1LQa9K+4VZ5Lq;7!fwdlIP71x zK*JLgvP!}M#{G=k@8-@h{{+wf|9hr*&Sl?ez3ir^rt_qUd*&hxmWe#jKv|f>^dtoO z5LPCp%O>`5hH3lWWEY@o$=EZ=e|^O(u*73tyg(4Ch(=`QC#PK(J#eKf*AgBaB@d!> z&#`ZIG%yG)BsD6`4 zC{Sl1pLMRPt^HZC5Fl-}(g%^Wn;g~wSA-dk^J8_a|af2RCBo9Tn(h?3U@qNF> zK5VXjP$hjW#ZWMIhzJlz#ruB!6%fVq`FK@E!-fb|hh-KrkNtn|w(&`~o8)m5>5aA! zRrvPqWvl%{!>?Ygy5jFl_@5l)@pwDNCkcE%yv$>dVS4Cj5v^!8^nhx>g4a|17wm(5 z*H~aZt2;09DFnO?RJI)4LvH;#}`7sIwmtq9M<$NIo^+pZD->LAg z=FGZPpeS*7XpQObMKERmL5Ehe8Ba}mx?(4|$@`FeB`$Bbx;&75klmlCWc=zm#M^M6 zQx)iJNcR^#N|IEd5u?$}3@2Jr{M^XIXEPO4%tl~hwbAkyoZ7R-5t)W?FL-ZUuDNvy%%$P0itp2-=O?~GP#K4aVfZl?-UU@ll9sw<2hwM!r+&%%~{<*$<` zmsK6|)NHAFpLQ{smJ(=#yng5&ZjjYMy{R6}Q!~TL@_V*Z?-^&mFF$Qbxz1N)Unpc227p_bvrO#pK^|^y1g|hR#zuz5f^%yhCWQO^^AW+_l zY9c1fRVJs8qqawJE9}fDk=4%r9?a!12tenqCC&m8|~`m?S&e1w*2@hn3P^< zsngkw2I8fxG<$4NEFZXH7(#N-)%|zo1t&Uj36xUh%oFvf-8PPy5$dHZQYu#K|1jae zF;|vRU7}L(7cBim`uXimzvZE&4u0O!O|=&~nGNUDR&7q;g_?)Vgx|6&{q7CwJ9KlwF&DtC^^5Kv ziP-RLfEkudh{H-#+Hc@aVLr^#tA{N0p6??M&oq1GAvVXMLNUU4&*dnZWy&1Nr5Fl| z2N8W2Vze;cNE~(KJJ#l-E^cho!^$MMEt=GR1%y^}pY98|lTno`DQ4D8VS%Et06OVq z2q8E5KwyqF8{n`fn~vnS~CKy`Q^n_znd z%5)3ysP6u^5Z@zTX}_VUsJ0Q&N|yZDR;6R3D+$r`x8wbYn9-WmKYcunAT`URM8v9O znJGL8h580!}iwQ>}+*R>>o`@ z2RNJXz9V7#gc%us&yT`^5*Lg~Mb0d5kyGW(6XNoLNElP=F7iij72)MF(&hYzFJxqn`5LY>XLCW1WSo%i zuz9MjzHoHwM^x=XZivy=V6FJwcSCG6GIwADn(g@_X+$m+tAAnW{Kn9=>8~l3#g(*j zK&Kf5RA6ILa0YZ+ow`WQoLrT}eB+h;8pM)96Li}mpaIlB$Z1C}ngoUOa09VBG#(9xo~5qRD+ z%g5Qrpp$z?gyibK+qn@0*1U6kEVh@femB74Sa}t6#b;u<`dsshvOk#%)yuYG#mLhZ zCTp5MR-Nc{crBF6e1XfsdVb@*nWEos%#s?S=g=r_%E$cDLF1S#`{m8nNP@#z7#ge zc?NGI4L&{_w1anD%QW7mmEaKfh#7-cQ27lNW(NeSS`p4PLCwiyikJ^r$s#D62 z{3C_ls^zT1hsLG|e+PdCSYoG-MTY6nSftkzO%=LO3fqig6|ppn7_N;7l};4rnt!tu-Aer z|M)X0Hj48?zC3MZyS&x^^Hix<|I>t#T$E1KGKx&7#UU2KEpD`)WJ(`m$V!dX7D`Ir zNN5J8=6xOUTSgxRF-vRoJ&FMu&Begjg0?g|n-9~D&EisWirc$mkJ;r?IK}eGO4hg$ zCkP0T==bugQ>p3ap2VCNc3^g+g6P zr#W2Dci3c5biLK2jFMQ_MPu^ocSEOL1NQX)P&!1IdhQF`f4B9pFI!j}E4iOR-A=(p zi_U-d<}5EI`kD>#8dXe6j;<0wijrw1v&ugX&e7LDb|9HoOSu|bx7Ah5M`51)Nc?;gX}i|KSnQ2BX>XZcvIiNwJEUF90f%pGk!QM zLn+XZgAN+j>ll4J8?-+j{9WWK(lD!MxBRic{OP;=liA|H077;5t1r1|;A$}JfNQ_& zd&|S41*d|1!I<~T`m0p0d6+~|CeczbM`#wJRtCXQYo3EXQf1Je@$RX=TrM6oL)_%a z@{)+db@D`9!8r6RcvN`f$pr{kP!mtd(XKOmXq1&KxbI_B)PVXhHzX(00`x{s!dH#St5~+D}1rzJxZ%{s&OUgzPp4@Hbd1O zm2{e_^)lI~CP=>`+}{TAVFs^d?V8GA$mMivMe=VXetlmckIoT`J(6mOu|8-`Es*%o z*nb_G*|Y_zHQF~a1rUEg4CJDQU-bIKfHX>AAN1sa(5srbonHm-I?^2KdGwI&6;r3u z-|_jI0iN;Q$*fG=u8p#1E^xRGATHpfT$0xOvB`Zih#U5;;fnps7I8?zG5XQC(O)(> zW%Y`Aogq1sdWrOTLD~iUI|YT_dkW?z8(IBz}735OsYKCpHF}SDXDl|^& z?t|&mR>P}<7KajN9>w4a2dT_~D~m98~i^^mOn)UZ_lA zFc2v6=J}~R0ig#NQUoN3=8tb5?sw^~`WtE@KSoEaD4il{8=1ltL7A}GZvNt1escN5 zby&~6CpG~<5OwTQIgVdRgSk=FIZ)gXw=-id@^=+N+_kHjDVB`PaZl5u#FHM@McxQBOuIJg2e- zIp&B#Cha#OKlg1H1?7Iy@Zooys?dJdO~B7 zzVm%0=XYZ{#ygd@F4A?o$$gb_+bDXANjbTZ_s>$p;fq;AtNjCreO>TbTB9H??D2LC z0?BGZE3lyJDHFb6-4*)SwV+fXx5Jm9Bq5(saObLD3Z zRAM4w;mMoKUl$~!1`_tDUJRy9ckwu1GGsP(+csznlEP^S))6t?Ca>6Jo9aR)GG~Xs zeM@W>3bdexWq((k?uLe#IMm{Wa?K^h>a1vBMCbpi}is-xt1CCGg)w~eb_gK)Rj7_OT8FlRdg6NkHxJ(Z+e7*RAGp0?POdJVbGbX`44s%uuA8;CA;6LpE^A$3h!} zGjR8CthdPpubE@>hIK!3zB#YmMVNA=Yj+1PE!7V%R3t6W8+!H!hvCGfr*N8SI!Zr& zcM@^lL8*Qjw<37Pb0RqGUg9Au*(JW{$YiN)YKn-Y3M2+l3a5Z$eV5Zxk??G2KuwJ! z2P$3s@&1|OT2j*e(Z}CLzGygdPs&kv;aDUf#35?6i~vLYM0(uW0|q)&0_-gP2#a3Z z2I3c)rYefkT8qYFET2p!L}dvyqW)+9^hAN>^|FhYMhI1=z+;P>m1e^Jm3^e`kS zxIam&uLIY-JSE*rt{L&XWbDmY6g$AJqy}^{O7Y7hnW)I|{x}PPdp!JpxAw*((93q= zd6;W&P4SuAyE|z{=Nn*|t#@5SN<}w$I!Nw5XVxqZLaUYsQ`JjOepfM~&Ij~L5ECmp zZ`7ZtwyyHRl4fxH(Y*(0$@d?9Pp{@&N8_w?D0!3!ItWGrX<5|kd}(B%&fN`jjd51# z170zS^qbrKuaJIj2q8~DuLB0btjSCTTGGJOR}}B-9%{gOh(G)zwwj)Z=6r3BdnyaU z0ofj$SZR>%Ce!d>VKWmETlAnb)!Jfwkxwv<^M?CJRH zt$*wygYj>znol8DBq>lYG4CY!4;3E74H499AtJr1D@;woxLGVaU~Isb3ZIHm6p^>y zC$}1BU6Mzv2)rl=lJA9s_0hOiu-_0+21*&tGsWQ>MAC&DnC4_$XMNhvLUQFEAH4zzeit$2d5;b+m-60>Ho3Wb z9%>qKCOqDEWEKafC&QCEoX=)sq13zHX_o$gMGFj6D~+ay-S+4&2+8!{^t(+BR1g<8 z*fDcRp;P0vf0Wah?3F_(a-Sr2JT43KV4=~>*!DsUu8|NgOinq!$fzEMgW7hq#oOE9 z`gp*vj^H#T!X-swn8Zcvz>@ojCqVz;H~*18n>aOY1S~t_1ynuh6r{l-bOIhmC+)J9 z6|u?L_o-;#>;#_Vk?yx(yykOc?uEP=8fHuBtde1Mm&$WV{nsZ%H~a3zrreHb0Z7?Y z7yDw|-(}xMV>?y_giy%BBS9@8{eX07=)@7}Ww^9+p=nE$3_5T78+pCY{j=@?aI@I7 zsLZt(mVLe0x9QJkZtRnP)BjgG^;-d=VrEaa*LpOxmMnC``(%2PVCVZ=wkh04geZ6i zfyi<(jW4gYW%mf;!z~>n*vDklDJ>VAc;7_ea`~j~X|otl8u0$w9m_K_OtJcS(TJ)? z{p3lOa?rTx!^@iVvLF8ghLDxjiQt~q4``V2VnC*kZ}w_2ObSyhe6ogpja^$*#$06( zCtyN~>NxwRO4P=*{(hL>eLE5mNSj-TZw9J&SVY$iu(GS<-ebJz7e0vF+0A9A}fP+RQa+;Vn(j5z$IHe~RSdd54Z zZM<5FvN0vj&m=F|B(eCQ?UEDSE9|SP?$HtcslQImxNPj079*RuVv}(YiQ{mOyy?R7 z!|cD4ZN|O5EN1v}e7spnK^n6yfUdSRF@~XFs&#tuwkx1u*Y&qJ&m3QQ%A{6}tbh~Y zUuc)H&IJzR`RiS`C?^=sHsRymit1bLhS2d+oJ}GE&SIR3YN5%#mbkEdYoUi&l!y_0 z@pP<(e7STHrpr$o|BVQ!KrXHNC4}35;4&2H7O9@O+dSiEFq;C`0!VD{ja7 z{=i>dVzGiVi%5(YG2@1k@UNxb@zKQ94D@4vbN+)nyOCH^8`?o&Krk8W0waQ%`sj8D zl6i)CzUNZduGAuoG`M@CM*CTH;(Pc_JCx`zRL9u(cR#jhtY>?iSI0jJ{__hJlcV(~ z2|xS_`Z+`s>P>7;zADT~3TiA{&o;*lgw0HE&Y!pq2&QZz`S`m@{c&0KBH2IBf-@5p zV4t}TA~=7`X(&hT+7VClxBp}$7+qmc;}qb^R~)e`8$W;tHLRR^GL7*<*e_3fexmk_ z+f`ZCtG~tI8}?v2hFp=)s?Tzo^z{567vN_w7t5O+vfdk9_Z1HDMwT%B#T z*c0TNVkpxEv`AHK@93(&c}(dVfjQVi^f5!dIZTTz3MPaCVj_MCte}1*Rmc}E=%W;N zMOeUez9iZ0S^%bGsuQ8rertE=$6hEeQNK6+HlB<+uCk#6%^5C~VmBARHNPh_G>HX^ ze6gbb)mjycjUPx{0I^%SIqI2}2xnxo#W;KMbdJZUir{Otj_|fP`0WdK%N)AP6v1Re zIT!j0%2R!73dr5E*(BTXC(&`9s6fkAmZh_f+PK6$Jwr2yubDorS~YxQyRI}}6*mrB zKAbc=Y(&JZ1~4BtnGD7MdK*tP|28G_AD+weFK}RMggl(AyAcI6pR0C`tLB$aJ^d)ASXkj3L3V&TtE!5RHSOz}1ydRZ=+qM#71tBG z9PTk8Y|__2e3+*`zY6N!IF9*u-{-PBc*66Aqqwj}RR#pLCwRnaS(9mUMqTQoopKDf zy5vGyZDYtNf5dwEHppCv`ymcjhS`A%dDH(%lxMMdW8qE?0`)Kyb{hJ8;xpw@^Au?M z5>I=-+tJk(FH03L#~HlQH}LW9AhArRmynuT=yGzo-ED@HT zap8x%U9SB2Bdu3#B|Guwby^pk-B%r|;zZF3_{0+fY7scob@5;y@J~F`yE8+%=&5VP z$tB6ZD8T1s_u=~=4-9Z%4<|%;k|>>!$SzHxb*w!q6ToefN?2~8D+y`Vf5bu%qhao0 zA1*N=4bhE8hA2W(T>28>aH7@+GJ$@z$uie%l7-O|gE0qe>~v0z2FyfbCJneY4jhMR zHf307bRKa1-~j=-GDKt%Z-j-HEi2k{#TU$qN9+pRYXxn8%at17NNZaN=&lWnMD(vY zzPa%bzFjmQuET)(F0|L~^9AAKd#zP1YoFm3#)}YopEST{&h>v0J{aai6>EJjj(`LX z{LTdqz^jus5t#U(WACOCAtEzHEBxku08czDGht+>mpvsyE)ywI+tUt-krG8mQJq}a z85kqw&D+Y}*dKdYSQKm4ENJ7(t;rppNs<6OSOfl`GkZ7t$^yjNxOLlRRRA*D-RjrD zl}ClR$t?B={3Vs*7D|*Xu26mRynt@b$tJ-7r-AQ0|1R^+g#8AoE`}(PgCkhzR7cOv zTig9Km~AjLop5I0sN+i~IA(q%7G5^qT|Usn%^AB8)qWmfk*#vUgTs=O?LG$5Y&!T9 z7l&y92MxSy|Mdhc-`s0$*UGamwykz15wTOj3tYv&NgVMmmQEIwgIIqA>Qau`#Al>u zACzVkt7}3C%S7qtCXFhG4<=c%`U|QxTZq7e+^C^O0&$_O2DhY;k-tSox_aXae7xU& zp`P!4-eKq9F#gXtaTx#;nA6lWS&A;c{~?Tm0L)xcvNW{hLlzEcij?U=L4*uLDf~qB z)FE&zoa>mzyI~5h3@+q(`W8LOz%97Tc};5c9JSHX4>cixDyLHgR5LDi$%_Ftne6|u z)FWj`5!es%uQ+)j!HF0t48(r%Z~JHL>k7lSVGPkfI*e?HsGr)(Q}$GD zWzIr-xTXKPmUBw{`Vo6MA@IJm#QF5t2pMGESXr1GlS}V-_&QiDt*4`dgGAkJWHwfu z62sK>dNa=hzzpM;v8-umcxy3B6o0hFD&9N#ZQI)m=K&`A7zz#CD7uKh)A~a2#mP*_ zWJrg2xmVBpUeP7+%C|2hED{!mQ*cxEnaC@nk5*l`-zQ{-vResy+5>}#d0y+Ffh!;Mn+c=qiadEK+2xh|s#1%l!4w+EU%L3QMnU|eD zs?KQhlZH`)5VsD>897^I}{p)KFvJX?P=zVBD;Z-7( ze1QCMFbSAA+_o98d)c@T@&iR*C<5Hwc{YepKL0ky|8k@UA@Cm`=j&O!2D%#@J@XjS z6Hc0t+LmE$wW?f+e{VG-Ha{9g=obb~)=vJ}{*JNzB%HnwretJ^?vPmIFg&pjNVH*f zVoC&0hM$q9GBSFa99DY9fAWz6tCG37yHSq)RJvx{yrOu31luD8fh_lU=Jh&1aB;=c zE4M|JP21Csxt=UHqO&SE3tWC8D_;l6xW;HS?xFM^p$Z5O57|vWX3KY0ntz6EsV&+ z=smn;RBrHDvBmYh7(TfS&NKFxZ%8RnuHAY)#f&r7NjaO@*X^4Q61!b)&(qatPbSIE zb&MP8TorcdP9wYb-~S+jGGV$hQ&&;f&%%?FmDSaMfmv%}`2fn~+8Bv8WfvZLU1MYP z4t;Al;ju3`xaZ@rfkYhHYaI*<=9o9(!lbU5PcrNX^EY2h@7ETQ+}KLRo_?!yWx`VT z52?C-W=e^ZBF{$J&YTmA@?rBEJxsK?Z9@^h_V^aM+KL~EMbWposG}_`@Cy6<#Agl% zWVkhhK>)=XdoS>1LDgrWy~Fc>gcBY~LdG_to3^ZKIRBs~m8{E95*oZ$ZGvUki>LSp zp)f5<3-sMRSsYcr@>uth&;f;~|t zApug534<2rzyLE>xHg_>dE**BK%wls=CQCH5@K9{c&w1e3Ym;kKK%y5GrP$>qb2zR zM&WH0f4ArX`fE4LZYb5%byOmwmqS;jaIPmlO#3-T_1a%jUQi1Wzod{w<2D!@={%t> zccXT5!T0SC01^;;V6FDSN0P4GWuo< z)L8i#cwH1JIJqllX}%jx{xPR~jXp9Xm~W~A!`xAvg#Nt<2t>qgU~R8aL4<1uBBU^s z9RMBOJU(9#B{%^TSz2XOndAqD>?TbD(WQ}k#=aw?ll*bY0NM2~mUHlK)BcpyO zKIvDu|I;Iia$X35$zqE{0T`{z(IVILHM((6Zz!_n|2BfSXnW;YHJHOs1rPV=MzHH? z4H^>Vyb*9``Xnp*b*6p2STd}79?mf4or6zM-&*pAqpCZ#Sz82DGW{PWmxP~@DB#08 zVq)p7acLY~DvV4&Q%eOP-s-m55&gBa`p=gX1hQ@PO=S`r1+g3PZy4$62_`t+1TiB) ze&>2`52&lWn20Fj)MLV#$xlM$N<$q2@ zcOH3(?X;3maE48{8wrNZVvGC~x=oF8KC{FAHz*2oBjE+LJ?mCcHD7`_&UR{zlNK(~zBB)ciej@IhgC^!IDNg@-I6GW9vO+CD zIdGt)^Vr2MY`o54=SmT=k9`!9CbKp=vA?bV0O|oxLWXWelSVBs0VySF@zx)frJw%P z6ZO=ro zLa}hggo29d9}+G+nw2mzTFsP!RC5o1I6z@5nX~_Mfh-3c z)~x8WT%}dGWS=v3)e%}{3j*;^UTFhA$M`8JM(`*$SHiN5TCzF&|7rD{X__$@-+u)e zc6~U^Ku4Ib-BS@?TfM``ZXoEc;;YcWjP0|U=| z$@J;BfwoxeBVsR>6}Uuj+#LNtyx`#B$gX87)dqsZ2UY}qO{p~bb|jG z8?I{}w9^I%Ey_xBB+4}UUhXy$GLb1ko&P9?STvxgn7ud5I9hh_4bLTuAjHQGt^Vfv0;B&8twVppl2(PZ?9;CB&lsc~N! z+`xVNt>1+uySgI$0o1J>KPQG@%1g2OTO<-D&0Ge-Y(?^Irxa;!W``ftx${N;*Ntq_ z{h((pkmO#BeNV!IJ4&t5!;D+_17{R9Kbc;~cL(>!V@yy?z|-x`7r1`Nh7mUUW1tC# zE$ADn@XPfqpbU&h_1~eBTMsNf#`!A%6F+bdh?LWYzXu6Y?d@VGWx!pabGhloX2KL;UP?*nO|H#Dm0vdbAehJg^aARnuE1CK5#NeNMGOBSQL1X zgY;)Xwl|N8q5)^6c04@laNxi4wP8evh5oCDzqTQWcMS}lVb zk%1JKFgw_Cr{Z{+kg)gko1K03`yE>O!mwUa7_Z8k3#~8Z=>yAfZ$^iAnvRdaf!ajr zPR9vokAXJrJuoJ$X9SK1ROY0WpY;-`qe^WK+9W-rg$bME-A`VN?Osj;2uA4V*miK& zZS35^z|@NhcK;jL2ydw0Mod|PKZ5tuO6YCr+peTqPUxFAiT*#>56?Cdysam!C{En+ zDrrY~MUIo9*k=Nb-eeb~ltU6x!GCM}*r^_Bvsua=DOMyB; zhY1e{3fg5g_IaR!ZMBR3ArTf4DWL-=PcA=3w3`ogb^86%VrhrdcWSMU?@bKdooV6_ z>lbblm`rlenAX)1TelY@dyOjb|j0TkI1>w+W50dESjAlinUZ<8& zT;6L8D(B}HF-BnfZ^9G9h+uI3``PPNtI2hxrR<>Z zmu@=9pRHN@ti5O6J;V{jKN8^}az_gT!I)Nf|SRhhgZT!FvG&Pb~RYhlP2)1fnz*$WfntJTq8&~UU zgZ`M5VN8(A(L)zuZh44Upgiw<0TNEmF3;hSDqj0-5jtny|_A@6KJ&#>2Y*ySwjcBAWt4do#<9x2RUOG~TQ zxu@;&+|)opy~;Uh@naq4%#!0qvGf;es~s}3;q>&i5K0lXDAJ5zKjkTUVl&8qP0{D1 z4e$WH^R9sR4$+gsYgPHHej^|oxKVpj@i}K22nKsc8%LZb;;DJEWdz)1E*7E+m8dfI zJp$78=b(FRzJ`?+fM#-| zS@sbsfv8n6t@qXz{TsLdhY!+(z9=(nEik|aF(u#1AJWhGF_0FC&1$H)@qHkvP(wkV zqwD z@BQfXO{OKeQ}i*;CQ`8JgR_iL4UN7o@Z0Cif$+d&Qf%&F#o4a^A`^UUjcdb*XAki> z{~!H9q;L}%Nzu>m|EnkhO+NxeJ=wTFR25GaoOotwo^`Fo!#ru;AUs0(y(cVYaR4TE zd5tk103rwJ7(v&6ksdMc;+9u76nCix2$oNIjRI~ol|FsiwhFqnQhnVumhpT#o%%pS zO>ad^8D<|ASQ))Z-ai~dSk(EntjjdVfT5A8Y!6+D?=i{_nPYn1StS0CmH;8KvpfDt zvg(Z+f=BoQ$MgDc0A|QYYrBOnlAWP16MR0BUsXeWszL ziBp`1lis(Pzmh4BJE7-1ga5S9AAnhw-XB)9UJIRzQ!;qU9q=S&UgBSdezp^Xm`pWP$vyli?jrNrv^=G9SkJKEQ)ivGzO0@wPJjgj_X?CqgzvBeRb(}en=x|1OMuK5xE&++m}g14 ztWidEl<4lzi3gmUD#F1rK@aH}S+0RJp+zs2*?}*_eLsP2ye0b+a_Oh+zPUMqz}NjC z%3|yQl+)%;&1uV(oLJ>V0*F$GLcVqd7jYvsM1YqB1(AuSLP6>we21R6{VO(2+Ks^Z}j|Ydj&pS&@$2T&5 zo}Ng>b6CiNm?jPZ@Z+)nk$P(OTD3F|qCaQ}_&G~?3Wf^E8dV5rZ)nYaWKdm$SB$oV zCUJzpk)!w_lY;uPi1SZ&v)v3gy(S}$59%j(d_OPN?u&1ByC34^_@0aZ5cXAy{Mk^L z(6NU7)1B6}5Ih=A=YvDcc$|%+b1tuf%FGmY#Mc$CX#9w`itwv}={yERrMXL`c?128 z@F`cMN{RYqDl$=7MRr{D=SuJ!K}zxU>DaX*s)EnzNztDZFS*kZw%SdP2aBSE&T?&u z_m(Qm&0B81>GzH=F8(xga9A5Sx3I{Yw|D%(e{tjnoaJ3nJs^AJ%@SE-BoMVz^NOgT z+wI9^(`mh&T190`RUcuxR^oo_6SSMEl!+Mi_D@|hQH znpGYRs3QJ z)Y(=y;85*X=35K9UD=2izANZg@OleTE#f6%AuEu{!Z&#H=q-YLL?QYY&z{{jR!o-@ zyp;2i|07@I(}tgD1_^7$aocGtdBJP$M=wtc2ZvLOftig*ki9R)7tp-z%^@@hO2u)y z-iVL?&zw1ZhIw@65)Cxelu1I~cJ#I~Hm(d61Qz6Sb+zp_?59GYw)!$pdU@l4W0kMR z?7l8#3G(TkJb_9g(^M=E?&Vrjnf|2>bvZ~6L>(I&3kbG{{;#Jn#ky@nf6fiUxx%KB z?hC{7+X!?$>UO*F5M?mJYuv!6MV4puz{vP;)Ocxt$tbm)aI`lJUmW(??^2#E@L{ZN zXp>ViphjADBagqc8ZZd@kHJso)Pegz;gyFeA#06p8jxE+vp$x?A$4&_aD-NJH8B)7 zgIM^1O@MJyIXa`3lP4xr+c?gFho{`;cjVKA8q44XQEpAPP|z#C84{;EGBsxg_+0z- zI4I!kzq7(C>yMTd@OA9gWm94RDqWy8L!<4Z@LCN{*SxvS_V4Pmi1(b9r*oPEu*Z<^ zm{HKK_qf7WI3RRc6OLaxMQLwq^Xq@{u@dgV7tPKN*V)sbCz!#-+EOkaJC4ApKat~a z1Y&z9YQuuR-ko~ok{$K!k{pRQuxowxtHVF1lMA$A+Sdu2+7JtSOxft!PVW}}jNY;u z-=(^J-NxuT784g22gb)A?&($06co<%yB(IDSx&}76#AIcO-0{gt)iDcs@?vFAwZn~ zi=2w8ANa?&y7IN$MEGX9`uxR)>ptDI?gu{3#Bg+Z!-D?`&Xt#Y5QjPDWIP8Nf|+&MBQek5{^7j=#o&p{CwOIkP@ zwu`ftHqy;iiN*uN$OF_84<`CKe*VfbS}%^3yj(Jvr`lV}16Y%P`h0_fUbiAuFOx-M zuloI-5SvvgHnbQk%rLbEQ;W;oUl8do#0pZ8KD{$>W<3$yo4p_6tG(Xk2+eG!zlj9j z=e2}ZpLWhUM3Qq^QS-$u#%!=RQku39tdGBa3oW`R+8g%`mQFnO+xGvNn1Jz)_YV5I zI28E;@KGlMfdD(S;kxk--Q{#Z_>!5HHa~B+zcED#am6qLVNh=@F5a(;`rlDaOrEX= zk3_qqj{Q=fYP|yf(C6D$oRc^FL`fO#{FsZjycQ`>dz|oJtzKQBp9hq?p3_)sKV}IO z#3=q^J1>~JCOKnIB6gHB1fXW$+(d~rncZQd9eYvE?}_@Hn99-*$VH?7dnOQmW@c2A zuHza8sfGx*Z*nF~DDPY%>P2vpmM_1OH#A2|U^u@JhnH`W1&5_d&Cls_BSbB6EdLt;m=>q=I=60V^GN(37oh2d znsMrQdA-!;E8rIPpAm#L><%iJoxv<2vzW-k`PsVanj2MET8}Z9^0r&^#q<(dOhSAL zn&t6!bjAB`IfA+o#c7&sHI?DqxYX!3O)G!mtb#62+yKub(O^)ZD$JM%36!g=RkP6T zwLOm?Bed^Ht*mayB6sk(U5p5@=bKkO$r!8K@a8i~Ad)Ny8Gxo3D4A^@FM@$&&Q9qp zTW|`)5?wQ#uEn##;IJHt8q~xhb9E%GAjkvk2`2t9Q*5o=F*XesA#jJDlIBl)P9+pE z5GsuLIT(6jE$Wi(_sq;!C&mi5mZyglru1*=-;BcGJFP)~ z5r`ibW5Jvde^b*fDoUU0BsahoR9HwT&b8Hy5qTTiPWG#fZ9wQ0=_r=ZX}44=lY zmGiNnlM~NFc+S=SgysXi07Mt)-wX3F!@z!X3p7Ohg2t9Gb=ZUGzo~r5QG|%bn_b_z zE9Om=E#YaY%l3GFiA)j(tcn#mr#fpvgfdyYF4DI~J(EU{K5=6Tyj3&>J?a53s5GS* z+1?r<<_f1y0q7O53sEz3b9kRuSmWKEsw??j<|a|5u9dc?w)Tegwg?I($QuGe{W@o% z`c0T|SJp>qq#im#IaXJdlykD*+|;P@mnvs1v-vo)aksg?zP;&vlavB2LkORo4lODr z2&_ggPEOx8EmjDvXsal%I3A_DO&E{5m(~I!Kr2Go+%+kaaFZ?qy6FOOw>m9sV3tK9 z<`~~BXfl-w)XFxuBB^9vTK6Hlb#ukMJN;E`i_OClQnoHA%T`XYrX zUi33FA!~NFfE3$DX6v$!*rirs(552rNS3PE^Gcb9A@YreGSBZgLR)h*wis|BHoMqi zNkcTrigI?Nh~i=O2~wn^wPwsh={zPU>wYfVqAyI9MxAZNjAGs0n&%Zwz7*%8kJg*^ z|Drg-oLub*Pg`XXmon-Cm|Mqrn?&VR{8(c4jx42GV=`#gQtsC#^Q1QD2*xir__~~v z)ESXIp#4m%TKD~IATy4LKA5lKF;@j1=QrD!1dzK|tkw%yjr}^G&Fv9!mBK3{iLz_E z!bYr=lL(0fWB##%D}Ec6oI}-GIw)Q6JofUEp;M1!-1ZL(Bo_D!va4|13M-y5Gqtup ze~6BbCINXItizhKK_Ckxa^J(^^wRcrA>4%DCWu`iQ?&8%KTkyM>_EyyFxNIl7;_rn z)IPQuha?pX5&d$|9L4ca)<9&akBhLcP*4FW*b}TsGf!({4aV!}xp=zWz7Kkx)ams7 zVD@W~EcxE)?-Ta>P}pEM%r92Bjbkw-XXHTSAvj}(b)0?AucFwUdQGX`s#QZJTzdfh zY~itbE+Di7^#P@*e9WRk(%p@VjRYL|GS0)i;Xy=5NVwT{rmywFah<(xmsNuFI@lhB z_H=&ry3M2%XL2AJD2_m-x=`i`@-c#HXN7XEhFQD3YmF>_p4;dApaGTBrX zeNng%xw#7Lm$q{pmOZ(Pbj!-T8686?^!(}Fq57zF?-ivb{YnlNw-4D`kU*=`s{G+_ zCvjv+a`a!OroPhzFQh#7?Je}cW^?-lE<31thp7XYRPTG0%<>6}n`V8J+mK;VwI&Y+ z;z3HC_&yv-N3MT@Hv>r2a1JN!+&#AsKiHk$0JA}Qe0es)ul#(xG?R7?6Q5h}*8PkG z&*#*!!8%Bvkv@YzhpNCiWq{aa;5WsG&Sqw2)U76SvY}^ZAr_fmI>n5cRVF8b{U{%w z9&2q@c*mv8@uF5;ddA+In>e|#O5I*3uS!?3Q5EB#R2&dI|QDpNRJbZLySX{>V8 zi~w5`4R_m#5{(R=_Q1`+4&;(lyKUMuCgkVyLBA5yOYv=9*& z;O}p}^|W991%xmLY_3WM{t`QjV50*4_~^%&JGmcz$}tB+S}%IU?f_$gK*t9M%q|H* z{*!TjNI*td#llgogDkIFqn@mnHWTn+t9bEI0?Z$>cleHtdqS^Y5zix(El|tsK*rI! zj6$^L3iAssA*)P+yixG758z=;@yI=c$%6Z37L6+(dqDYI+tI=HyE&N8X}_EOo{9lW zbSPB*V+2C7bc6p^u(kt!B5~55do%*h=4d?2yulV34lDdU$=Lktz>C_4Juq@4h<+VA z5)Sv7VW;DQYjF_n$ZmlqO<`nEW+R^KRcn*u`Pz|xQj{Z7p)eLPH%}R?6R{Pkl%i)x zB}0~&h4Gc1`ndc%+*@iz2AQiwhmoCQH^DmZf*Ne&hZIq9S@uZV#t1ia{BvQ3;qXVQ z=#1Nc-K(O3=bOEqyRJUqu5056ju%AK4s!$$h?s(`;`a8ssCuQ*&a0{OV^@m~#6hU{ z9DB2kefxrVd1dzC__%*sz0_oKlJ1)^M4P#i1{LgUblH>b)Uotpwe!`0SBnm2Sr{>*M zVT@^p?!wd=mtF~B&aP2n_}Wv1x;Mv^e)yT z8+W{T^2di}E!|30WwAHGt(g7CB@kQE6l$zXg?+ zbO^JDnNEE+5OC*DEyO_qjpQ+6i+k6UE#XJ1Lsi z{vSByJqO_M!G{%Ktj4fN*a{z?v8uDd!IW$V4m4? z_St)_cfH~L!FDjjRw1IyeCpWkIn~nwoRRhRtg#B~qG|3-eE0uzH6~%}v ziyvi@DbPV5M3qmBRNO2A346R~D3Oj~ruKm}Ad&q>wX!XO+IyGIm)6X#kk|;bU*6u{ z|2gueb=(U6ceSPetSPyWf{1%RY=0MGwTg2tNlN)%32L-ND&Z&5@CdG`ZuGs=2jd0g z6;TBK(q;|l@(6ziuc~jCQc5+#EE^IK7uWj^|Fcdb+VSymc)xK?C0v$6nR4`{{22vb z0lgF(y>JKjcI9(bRvAAdYCvGahjwKyzVe??4bOj2NzM^r5kzu?UPl9p-{0(e99CZ> z7h+=;TSB@XYlv4-(o59eGYj0UJtOBpU+zoS<^3yOqCj~(DJzU{AXuIIu?|o6xbM+H zrH555&m7L7!t1V0SBMPhuBQF?>vpM9VDv zbvn|q!w+h0-&{(nG+1n?QDf&SGeCXLYt~+f*37|0Mj(G-IW-1|xQ|d>g6ND~$*=X5 zJ8+g5T>p!|>5s)!T1To5|{5^kx%(ly?PjP7!SvX`@PSrKe>oOMkAO~M=d_2;n3}zo>VjO%@)OqYqsyl3mm5SR?>d8 zQkBu&y7M2of-I;F59CO%QP5YxtmRu21y)>9WWIa`;)PP3E5h;*ps@k^evRHQ3aR>T zywx7Q@8Bf$%8N`wQyB;mh4&XOxbDD`2(jq``xJ$ktO%sOJq!V21{C#+OdIEShjP!g zy~?oF{KQp5s{PX%Q&S|JcVvNT*BW+H0(68rg72nOE7aHK#**m+QT+6e55*tUa(nDL zy(%3ZC${TEcAiIf*+RFsosCZ0Zv|ZTCi4fUn4U>IlUAS!E73?@K-|*doEO<*EXhwj zFEfjlU(um<$dDZ#zywp=L79L$H6-R6x6x^LkhaYiM{|oHg=9VE89yX!79p)c2@J`J zZFrIwMCyyU3m7#Vv)=53C2T}l4qBpsouJ|5hyo0BQfWcD;JeOS!PWIaiM#JA*R$_C zoXg_4*{dK{o`^kpM+%K(=>Ac6_;o<17A_((EcKg&@*;*B=F7GB`Vq`)5|iFN(%Oqj)jUJ3)6&SD-esp>oI0N&;j9a2u#=RlyGIE<;n zE46NiVG}m^idBwb+Dl8A-#ALf*yMb z8H)X5Qu};ZOEt5ryL-+& zDN0bMjGh0^spC=QleM>NFi|(Nj6&K`(Jv#FKipGXCGlVK{$U;S4*lryVM8%XW?R#G z_S1g7pV-{wS%plvv2k%IZ@gsKI>7REncw=q{AkPdx>@Ts5c7Ijy_lp>bVvn(U{zn* zmt;$)eSofGuJMu7|(9E>vEOdQN5EuhZsBOiY~rOSEY~-5-($BHs1XBbBGsi5j&bH zTZ!h|7?8zjXk|5=_Vjpz_;||J7|4P?<3F(F1ZRt;`voySFfvve<+B?*dD&sbi+bT% z&23G|O^dT>1otNP;n=;~eD@}USZoD$qOCena%z49rlfm%R zT3k_1Vo87@!{UFA{sv&sj$g_h#}OhKL&Dh*J`*|*6b-BY>MY}?qu|3+6gKwJ<5Kc&>KdN`QMIP zocr_oaq)$^oerLmm^d>=ih7Ym*nN83wc?{HV{#yf*udW_2YHyKFu#cLA#IsTS{Qyf7z4$6%>d-j)!9ikq-(g z`^c1MF-l{zS?n_W_KeJyl zj8_7x43CyIlWM@ixvA%{agLN@ml{t{8WmZ=vZ~X>jkCrDB?YhQ#)@u2`ny0DgSjs{x5MJM3|k9=Ke(Yk)Xk@TwV8W zal+qwZPH~z5LNF1eRuV1>Py#G8W6}30Rcf{n$`Z-&5}(kNsJUWnWeb8wN-hvdId&= zCnQbJpAR#aAJL-)-o}+_Nc2hko07qvxNnLGUEY4!#*Z<+p4BRB>!fJW#VnTro5TqO_P#E^Mn0XJSbwlL2aBus zfDKtO=x~VC4&SRdjz+r7PH9gv;~uFmIf~LpC;uc`tA9|KmB$hno37YRrvzqq>o)hjXbB0G(Z@tStaH)LH;yF z;g1o!X=s!WJ0E^``~?P7%}%-g2N4k#SmeH}xf9Ag$gj97=KEM>upc~`o+==V*O%v- z1`BrKhd#iZH|_aZ@Hj*a74Q?wgavgRo_|u1NUu2&kw@CFlfNr);y8btu||S9P36F~0JzZcD%PXH?c=Bi+*$Lh z|5JK|VO*fdw@7vH3x`k?Np(_ELgKLcdrS zGt9^PZ0u79c*3PyFm~}Cu~RYv#2V-swZA{y5`>)VXYJ_dh$6IBsp9_nE%O%Iaiz%x z?8odD-R{e~oa|3E$G5t18a8g6fwICN@kSj4Wj(?19XBd55dI82Z}OSIGc_ z8T5R2W6>5qoj$$0*O2V!KW|L>D2y|C|IUZS{9K9rDs*Y%NJ{YI(yPTk)RzWg_#0+a zJHYaCJymCs<7e(ruAbTZ$@DSmstLPmZ_ko1NohIFzWu2cgJiCFWZR7MAg1fHD z+f@EQIM;@J@;K=$1lSfugWUsz-)cvTX=$kVi+Hk*c7syZ2l5biBw9BloHWV%-C`Y#2pZd~C&&U$(ax0MD)dbIF9_L#6(Manm5zr`KkVd|Sf zB;_>|6j%&=?Dc`Mzay<~8Sl$jXsAafNfDG%M~uZDIMUbH(G<&S-$UMlqeb;4Jd!h! z6K+*gFiwgqN|I%1l^4k(O5mhm6arx!6t+uy2*ctaF?VMrn8Zbi4O+ttnDH|zb#X=8 zWZsZR(mqxDln9Wc$>DDAWB^g zO}CD|6USLdMV4B=cT3i*T*XY1DA^2`9)zEqlEqLW)?DrX=!nZ8l7mYhQesigAATX< zoUm&(Z)HdQPQhN1zNm8&^c#lq6eAbBrG?vy8ZLpC&`1?x6&Y^(nZ-$$1T6&9cQJTF zM~wV${h6)-#hmXt`rX*-9mWg^_eB(WlGD6w`f*4P0@in0d-kY&%@`Q!{q z8)cl>HHwaV_ZwM6lUM|%U7`thasEB8iz>@Azgz@@?Gh4VVbH<;KtJpfB25~Kql*{K z#kx~D*6;_VGDZl8v0S+rIVoGsDLG!z6a!i^vcD^8tMMm6qjW|;Xzm@V$9~saT!N|z zl0aUG7E#pH_$bCOFjU3Az?=B=h)h;x}@~y1ZF0D=jL@FcxKa&YQxw?^kPg zR}3rkubOYZ+N9xkVXZ3bi)));=T1LA6Sll~KW!U4AqvD5YSuh*n2~Au7?kW|CGG55 z?D{`#e#+(b+?z~NNi>jw9z6Mco$gmc?odgjfd>%-0~;(s$5(_Jwt-(KC(M1DY$z;D zYb=!B=BAJ=m*&`@3FwIn;lZi6?;|D(*T2=lxFF`+F$9Nl9b{~nwwlV&hg`(K?VOa! z(n`$pJX+EK7iCWvDh?}{VYojFC!QT-Oo(348=gl_=VcjQeMHG_0I#|4fbxPt`jA*E z(T+1oc-x4HvoABM7~E{GRIWdo%pC}07T1Y`vY1Kfnc+|xyCULFX^NWE=QTd(cKZdY zhx0L9qK%{G2AryBE z6yI$QwUSY$z*W1k$ zOO}qRNt?jZJlz(3j!5m%`757GrFy6H;Qu79i(^!#TXFL8v)0x2T3{&-0&0|i@7z1= zy*7AZ7joZ>sU<_cyo^fE%$|2PhOjC^E877aPD$Xb>-o0x;h=IbuSi%A01WS;%hSuU zpn5+g49wUCcbfLyP?DO1y&8~B!3cOa=UhJa_Bz3?k+JM`y)}=zH$+s3pQ-4|B)W2p9bqWMpnfQnO+;zNJb&DfFc3;!|K z!Q;G>9Jpc3G-K#%;Sy}FL!r^B43b$cdSUOTuvHu+ETOJ4E_I$;zbfvPaA~xg+e9dL z_B-wI0ru6tTkCZV%W#?deF`ysN$GlP#VLZ&9Y#>Tini_@h45V|g0kTAm5B-tl=>j9 z`sT8O0c1zn$&vOIyl_IMb-c%=7^Lx`k&;^^25p7}s@o8L3c~%p4fukQC|@wO`kFmRmEHx-O=T9R*Xf)+ zEzgj6jWAoKfWK-If9nC3e?S=UBj9|;NAfeTNzqm0o~cl@6&Fq=N)(M0uL0w-9s;rB z$}h<-yjk;}j&RnzZ^w=$DWWj`?--MNNbO@oK6zWxs+Es3e4?fmq`mF!ynrI-Wpni@ zhT`F*IXyj7vRHK%Wr8!tP*hKU^>v}6t~A%*+96*hUDRf9^^@`AX#Fqo`}(P=DPtz$ zcbJgx9qyMqW5+qW1)2_EqaIL~O1V0mK>d21fX# z`yip*Eh;a`^C&5mD=SqzLpZO=aZ=`7aG-Z+K3a{{TgvU^+t0X`fAZj|leg)+5{V<2 zjlRlXWGE5u{y!JM+!%FUlIDGI&f5+Ku)iXLp{Wvr7qn`8Y{&U-9)skp5f}*r9X80& z*&FE|(J#ed03t#C;v1G`;BV!7x{|xXn#s3jYhfy;N7m@Fa7gxqV3lA~FrG~O-dcgG5^{5MtPHiPAdNO&ymkw-!w(yFE$kjseyhffu&;sr-7*|?iv^VO30s*RfJnfRQP_;*nNZ&_zS zyLtSmz?(mB?=q}SD*VbssO9W~)rU%PqSl8ygucK2e8vB7AORE)6|=-8CA(|Qi+L>V88D` zg6gcRLcR6I-a3*Zr^sOl>hTel1bj@>kDQW2l%IXiDgZh0s;3+3`!b|e751n6wCV{3 z#Rlxpo*DZN@U@&_t9(8q^Xs#kcTSJM27MF?dWp`9Rn?>4o}2wrpNNYBYOsj>wWo0q z*D%N;0xAGUr=|%>TZ8$* zCra!5tDe)-)Kx4V2$aR=V!m|wcd112TaC_7d%H*VV%6y~cz2lQ$E5d~i z6J#ZPw6*G}fqg2z=eMA`L5($3k?fEc$qn{bx%MP^If7e`w+7gl@d;22eBQAXMnjM% zHfvEbHrQ^Rw1kkUWgW=&%rw>!&EWgfr zTvYU-@1IxS&KeYX1c3-aS;VBI@6*z7+dTf&w*Rd8WX^MB$YsF9on` zo*QKuoa&eC{V;XbkZ0MB4f6_iGOb(oBH7K4lwcQ%Lw4gnF#P6^&n)K%&(2gJKEa5*-V zWcFsB?Hb}lvFEkq9?b=pEA*A-yNX`&QcY5ze)S~V-j*S2=rl01@ZVMPef+c>WfNk^)6+GVxKzPjSVljR}y!*ceOCq4)MhzNI$L{KP z00tcauKZ?m6BY?u47$`Y`Y`cwTlpMLaApvs`}v-ewd0P;yuC zCPvEe3x37y_Q;A4^kpdt8S}5!-0_R1{wo#(oPx443rFa=C2f<-;apXV1a)@>9I7Mk zT&p%CHF;eA#|)8*k0C3-0F6^P&V4|Ig5vFBxgTO+QI@f5Duo&)trNJyCmaU>P4OHB zH=n@PgAP7!JLPx0;8gB-nv8k@b=*!I^t=|Kw5wT|2@ zG9seTiwE@CSG~qZD{meYSW>60sj2C>TXxIINlqoV-O?m^j0AkCAsH-wi8N#bSGAnG zui*24SpDJY;8Y7=14kaWP`-B}2oFTf&`?7y2Me3Pu`0sv`AnuCypE_F{KS%Wjh`89l^H&0vXs} zqMY7eU!T%xRQ=cNGw&2x~A52$Xwp1OG;7cZc9ryQ{wo(b8`)0b*;}(yA+ex8twM5LPYKS zw5WzqYMjJeCF=Tv)-3`vd+$);$1`7l*nTXgz%TQU9cM8PhCtpQFwV5T<}caZ`HUX= z1MxH4z~o#ixQmtB+y12U`6tx#s7p=xIE?xJ>+#WJ0u|`Xlw6~?yI0F!uk92q`;)`N z81L#JohqbdO_!2Gw_Gs)5{F@EK!C>co^~VJAOXRY{g<+s*dXy^EJlM|uqkU+iPuS9 zOm38e*mkKYwMb3*wMw=ucWH&-G>z$Ov#-9)2@zEy7_z`5x)-co8VrvTMz!VlCOVn5r*oS_CmSpF1BheM+&gE4 zGw*oTxn1N7gWfdGt-_A;|8Dx1F$cM`c@hkTi5)-z8DYLVUsv@Jb%1bZ*PH-)*ZX?@ z7f)H>T%~=AQ7m_pMg8^m%~MyKGN_^8mp0SVwfD0^;nV^!xiqV6YvunaEJdjRkHM5O zI@DxQL_g^@OvkJLp2`GRbB>L7xGxLU&InmDatfvJJXnFxx# z!IsyP^4ttZH4 z8PwE7t1vB=U)$^o%o!=5cL`z8)QMdS$90uekAEkn`+^*B5}DcAdexehrQP>tY5J{= zJZXolWP_sZbCdW=-+73E3DQ)KY%izc)%BI}?1LNcmvTxg$b=f++(oj0aM}!oz$*C8#yRA;nJ*B;z445}((wiWO0w zBwV7TTjR(o&X`i&q8xX1h6V<6$(qOes5j#zl+;(1KalC?VzVok%LX4z&EQ}8mbLfZ zT5nrX{o9|>4<2V5U|pDwVPNSbHMsvF+{>kzHeH$pwel#-W>bw^dL-_vXT;hWy(nH+lZru1}8NO>85{vg#GTM=t!ZEC4;cy|Gc8Z*W;!OsUleFzu(>ftFOtVlKMonQuN zM%kOU5>pcs`_EaND$9@f{EnGFsl8{#0{h+UtA<#jbvpvuKjwAx88W2PEF%pAZNw9a z@@@KA&G8oYuQNj@A^!0e;Z0cbdR|yY?V4r{{tvvq*T7>R|{TEBJ7^D?4D3yVqt}a zJqG_{>3Yqn0J@Pha31P@-TAq1i>?q^Tz}1Cvz1yC&9XhfGSX?!0HgI&FD)g?^qI(% zsx~_hVnSvQ9jS37@Clw#B~s%p%J$&HMOks+u-AejQxlhVu#K83ct%dyO*2s2 za&TcvY*hx_Thxf04a~Sy9c}eEF z>wKn*1q^!u)SnL;!v85rmI9zx6~7G8V8y&{4SGCZmaCO2tv{`KoCzhobotc4fr_Z4 zq@{OLQ{{T??Ci8^3_7WnrxLgX=0pC~ZkuOCvn@0Qh4jO3)Dg1pzX4bXHozD_rZ52B zL}r=0;_^}mB_w<|APF--f-YMG{wqQo(p#@=s2ohs3XNa%PJ}yrFCj0H3~*RRQ;_0! zMG1#>64GN3CKkejf1ww3b*x1H=PsMYCT_iaoO2<>)bn{J#Kd~$2+R!lHo2baI z;VHeNN-L>i73?p@O?^5kxQie>MxsKDjG!V{d^Xx4G$Z`@<>}hvg*eqL&?Qd=Fu`NS zTAurPisXAXX#5!nDjX<$yop(Ln~!_h-U9MggUL5vJI?QZ%AIn-O;S=}f(i=@Ir@!_ znyadgD=-e{f9^VyA?=D3u1vajN)+})JMrAY%IkISpGeT58W7o2LABxw z!iBBWAyGrGf;2Mu-hOxM>OGk+5C9jp+XC86H_-0W^{3JvM_>9RSG@S6%pm!_`z|9>yw^mC2dONdEpaiTMR3&TJs-jIA+rRON+je1cWpUAnbwI^oj{}A8 zmNl29%ZuZy(=&v7m;xS075wsP~xCzW$pe}<&Ey!wwiRFVm43?2#He94m z1I_QEIU!IkO@LYp_L!GTf0hXl8I>5^ddp3eut#kmiM>J8fu__wAj3D?zM-R2qKT`S zk`R%ZaKUzM)!K2-Bk|H*rzsyleAsh5x4|zr68-c+A)x!jUZB-q5O9HqhO?~re-aoB zIP^*%Wie*%lxa#MxK}&Vvc?khe7)22cnJ@LqCO<9z(1X~40dXG3uD7%h;gE0W5?g1 zMU_&gHrn+*U@V?gXIW*^ABgtl8JmQP)dd5jN?Uq_iOX8|G3)P(%{aYTy)yJTm70@` z_(7FH&OMYRU9^dX$OM0C`QXft|2MP6XH0rWh5GpEoJE9YAYKri?;Z2 zH#a?xM;7N4uR9Kt8Kd1!WI*WZ?`;B=YV{#9e|AOmeOI&+E6UtlgNOSGsQbf78}y+U zK-G=HC@`+_KRkZN?jn&%1k=;gU)+a04R2pKzlO$;JhbwEDjYV2kC8%%2^DvLYYsT? zXlrXrFyV{)&|{4ARsU_m(0?Do0s6Dg37B?!##Y(-l{Lck{n<3Vv>BtH%a#d*O9xYd z?7A^)yHE*g!-WoGWGo-D9K$ehf&(UL@y~S?b-3iE`JAbWGcX;U=n(TF8S;*CsPT1> z7}+V$;~#p6`x>zArW#lRCKD;UzT@@XlZL>Qk|}oyK@*(kI?7n&UpmR#I-ksZuPY4@ zv82)?i|K%6f38{1i(sR~t(%;iLmGgU5101?g4*#-;m+G#VR9iCDadtW0ESw0Uq+UG2&L4{6?QZ6UU4sO*?GJ!7obozztIo#)@) z&}))f|55yCSYeI~wH;v@B1xhuPj2FYL;)Msv!t}y*3W~o_-yTKbEyl2waSOdI9ZVh zOe{3~M4T-%Vv)W~q|7JzmyTDyFDlBe>{5OT*(&ayirHJE zzAOLkx^)4|jta=wE&d-Xfq&CM(>#A+!VlBJ{fZQigrvYOZ%sE~H1yBM{;pQOgndSE zX=x+hbICiN#m8~0{Cf3D=D)Wd<}U<%LN6Mn<>uU=1CT3~zc(jY*F49HZky=`m2v`>A^=*QVjkgNM5^l0y@Ni(DhKhk~)_YQ48s)tx|BNM6_HBg5XcZ$YV+PKOx>q`?JDROsA z#uB<|irH@%fzBWZfH>q_Z)+nvOta+G;y^3q#gbl5W47y3w4Hvo8=28h3tRp|w}l%O)CNYUepx|vG} zCdl-a^zEq{$4~sB>=E-w8ee!XJi8uf1IhToKN#Mw>|$Y^6BsG1T0BKZix)D@g)u@u zX#r}|5eY(tMfivYI?(bZuwx$wy=jZ!-D7+Bnh;j;7{ZC7vlF6#G;wva(Knub_fPo6 z_8@5Rz+E61(fImhYQ=n7Dhn(YUeDrz`MCytw3trE>co&NP zJhtbWx$S7W@7;e^0*Qo!L7o5|S$Se?LP@$HL4LmaOWMg$)3*#)V$c)afXr6jCVzVN zt%ZHDs;ndC)y>t~!@ssV!a7#-FEVD!MjtRJrJP>LSzUy%2gS>Lc2bYC&BKp(OCad(2dg8A+`;Js|WGLjT9`idGALwWP;zJyVS%QuSnpNMsKf5HJVpMX!T}zm)tUHOPSZih`9h3yPP8)yNKi@z1 z@c|ce0)PS#(&H1L&my0!e!2m!=c^yRVOYZG6nnc#PczG}0U+VCZc2~{1=$(sEFmFb z>gnmJ{LdfN*H*W~HvalWzyU>606&C6>_~Y5JG-JmeLyTfSeq%*wE`n&&}lz)OuNmC zgI*Cm#1xloA5vjbD8Y|dEe0o{)KwfoFG;i>tJrVzgVRjqEI9dUsXcl)Tzqyt=y0o~ zbmmfNbjT8?II@}(4lQr;jnPF7)kwY-Q{N`0-=O|1r!`}e+`(BUlD7|d@LfXic!t6( z%P;b7Z7qTu4-XpXX3SlXgD*nv^Y4#m&B%_iI_&{}F4(R6rlh$NB*YdT$$=7+;I#Ep zy5{7c&#AILpZgJG=JB&*@G3IqQx|d+2vmRwIvZf1-zh06jqP~)6V(V{-mP_&KR#pt zVxi?6I1rOo#hHL|#};6e1jxD>vYliG~em>6v2?w3^g^~V#+KQ ziaCZFNZsk#KICD8CP~@$;La}YeZ7F!d7C!bpQVS$CuguWR8#s$co5QN4j-?br*t-DU95c=yk3$82y z2VJ!8GVW`6DvBw|AiAOHBBm*39XLcwj4b+h-|xh8uucQzM}34;A};|-TJPY2KxOG0%tdCdUp>NdKAm8IP7I{+X)*hMZijg6%6?K!s7RP6Fu_ zsnh;0_;e<2vikZW47k{J1q_aCU%=~NU54*^L3k3b5GmIEZZzGz#8FWy|B{iuqwI~|ef^@nkCR5JHZSk9Dy%S$c#8{zr^Is){MDSfCq9-? ztH_*~T!AJj_YkO5Slj_dVH70S;gwvs&m+zYfw_RM)#kt$Nn2}c z;;=;4wW~+LM-+10D86tdt*TizF2N|d#!v|+q|y3#nZ7!|W$y3)>JeS)7)$VEi`rV_ zLDGVh@Jb-sL|s0VJ_sn!eScjM7pMM5<+jk1B|m+4$xCQaBk!Qw?l($QJGjeQJ`p(i z5!zUkOVIj7Vv~=cok-bDu#4-*;4Q>Ng0WAe^t!UejumYrj}MRQ|6K7pF0N}ff7-WU zls9pAa(I$99TwQPbsVoI6H?=#51aNF)O4yg0{7B+1P~1T`Y_6XMd}H#sO~s*Xb{-uk9%gA_5@^@2$Ml3at4FlGE<^ zd+5>Wz^%~)pkxlBtfT$z!slnl+oSGN|6`lG?9~@LR}T;QvGHqO(s{eYyJXJIb3%Z` z!;35>J@NMBX$njFwDoZOF~{p>(V!!C9wqJ@JcS_) z|4Zyi2_fAHwLr~eDNF3C2r@^LHb9A>C86^O<-ZppUmYGt z9G>SK?DqB#qDcUO&?T!7TMR%rdlOk4-+lyDZlq(at)OWCr&r5_7i!g2&-8ou(sKjw zI0BNq&+@5EcXqmzbEVAOHIsV$yOWF35}OcZgS$}^v1U2?9E((#z?9p6L7eh>-jFSy zQM2wmcNW|tDMiFFFG6g!!#cl$1LW&j8e+Gq(CUwS^tkEc=1%MhT`i3^btZ$DfBhei zwP#l;ybmGdPh%>4aKg`+ckhKk&DEn}fbQuOz=$FSq4%TD(tyy1)i=t5wG{-y#*mc| zRd3XXL5W&hSG$mz>Q7@zu+ZT^6|dh^mPAMcxc^ge0NfSZyWfCe)#}|w^`ZL>a9-m9 z=7anL1Es8NTtU_vcKZrsdJz)v2+!@n%u_;uJk03M=N1^BN&|ipb(@2Ajt`vt=H~I~ zIX!^j$nb|04$~HVIvz`f`8=&1&(7}d?!dllTKOU@MMBxbxB03-A=WDaqW+xJ708Z?3rh64 zIchN)ydmqnZxnv&CE@vQkQ*UM13B}cCnwA8yK3m1mj4h#NgR{cS%VBb;k_aAhD!zm zzqit{q}_`NIA=dB62^9MvNNT;?i%KX{UYQpgyLGO8<6z;()9i7@C_$Fe%nC@Ejc7W z34MDAsPHM?Rz%syg*75*m5%)US&~Hd;*aY_1 zoP|><5men=p%2|kT_4pQg;65HikP;LXy6-2Y26JtV}FI=A|#p1|3K=ZOryrx5uc=2 zm&X~K;Y6{ZZ|61lb#O7@dbDFt`UGm z0#13GJPu~cLwrs;e0KihbP9W4?Og&EonS;)IgruUSMkb=u<5WA5XjOm)*7LQNyc{Z zmsf8n28sR4pR^8NU^Cp8zvwcPaHV$+j2q_%M+{s29^W-uj-`dmhQOMdxPg-^pCe7u zhra4<9?)z7y!F1}BnCD?zKFdoT7EgYJ_7u;=(uiu9qLG@sFsuNA6p$TNVl~lHPgHJ zNrlcFIsMnC5DoW=B^uwDC-4OO)hZ{8om37JGD4hWUDlW}eMX-nQ)tAv66E`rpvsyK z;-7z=(d&td72yIJcod;guHv~;#UeEwkK1Ue-nY8`Cx0!SPTPfZmv8q9C$h+iA7=0R z`e>792)YPX`**U`51^L+`-JgeGDdckf!H`l3w4_#@<>3s;`8d`^TcV(dgzL+4}DMi zYCh19D=3ZqSBPAPc3@?_>LrL)(?qSDFqk!ebFj)c0Gh1VmwAulrP=JUBAQSmm`m)1Gosq`51_Uz_@z4qQ|5w)b=NCw)qinybE8aB z0vsh6L5K%00C0SEF;&RxvI8;S-3_?+YG7fZ(fcChY=t_|Lwztk{b!xw?Q48zSNsIS zw-~wjC{b~EPlJHT&?A`UQkXrreeifa;o#AQiYr&skZ@tFB2^*d zMegieYBME2DNLAVj>%0F);!D zB-nb|BCVR@CHm4|8_{gMh`y_fnNVR3%+ivwQ3!t*1m%BmtIvW&S5^&c)PDXT96*f) zAPtK2pJi!PqNU<_KK_=Z)*dpAA2FSr2N?P!+-sSYH3K(x%f2wQOF9{6adoP5A_SAr zD`8#R3xT+}*jRiD|GV{jWMI%<3_NnJ*j(Q8_r9NmAinR<`@!VIBaaCP9WoSLz`{{@ zjPOxjVU&Tqus*JNT^9|g!Kz!Q*I`xe{S|}o?DX`%Y+&w#gxQ=ECYBGxjd{I6E5=`z zKrmv*7LRPPMapnRv$K<>#dAW{9p{7ef=ytXyuAJ!U?nUp6I)->`+KkdoX4%X(u;9b zn_`0PX!dz!nlTHSV#1HRtQT01khBXiS84;K5Pn~R=C5C=RepXPMK+{`$B*cWl3M$M z)0~R9T(8o|q^^J`9~zKoRq!Sv@6TMQr$Fq@jk~LxyYYWs5CB4<>vBEIJ~V(Z6FCeL zIJv*^p2TKyOpeS~ABZ-zxr{oDY_e-B4GTrP{Re&R!HW}q=>b5Xx+K7X0!^s)usbZU zLn;>ilL6>e{CK@H{pvFvNQ4L7l9mdCRt^+y;MD*2D>D&cv;BPazub=Fxn-oes;|>I z;e!~UHFD`HeQBUNyAOevD`wYKuKHZ|66ose#+(seD3~Pn^()Czq7yBy)0hx26EH+# znvVC%;`6}=IN`t@AnNZ=9%78MT}-F`;q44D29WOzZT~bFu zjMV0g1lH`zA9G`iua~Vys689UWiw}ZS)w>{coMeJO{>ITw-$QnC2Fc~$PT_I!F{Si zT@#}P;vCeW_uFZgx2qnjJ^%S?nY!8@-JPAC@iDH==gIpM58=gbJ<7=YWeSaeDODGQ zDM>?mIOBD?4`wU1?EcmoSx8F{#@6_5fB58KyE?U)U>BDW@OXIE1{boS%8D@6 z+n*RvL&niShbKdqBtyFiG&kXc1>u9n;Zij9lS0jYtnAY;t8{0MsWrIFcE5G}vzlwV zMhewY$(7$cGz!Lr%S{N&byJpiQP%v`=o6P~-sF(pV54^JL=dUri5KBr`vxw%lcyWbg`92^{%DqYnfLSjqk8p20wU*UvgKY;W8goMK$ zP&Yuv^T&U^>^wYfZ}jGmTklnHy8($sbq(rL`PveICwZ0TV1K-5Wq9A^Yq3}M>1qGg<-i32 zB>^}O=3q?=P)UG3ti%d9rZbRDAlt>xetTCcMz1DuDLI0kXES0#!ko@0e{Iy%)P76` zu!tB)|7b9Pdm#aSk>kr7dU$?c#!zf7v1Z%DImPGaXDw6q40+*ao6e@=(0}v0npHZp zsS31AY(~gg0Bp>}qE$zFWUgMrGikZdC5e!tf2%nJ$R9#9bwq%FlsE=)NscrA3Km|c zt@B<(Iaf%}_vw5vE$5S~WwQ!nRz_A9DY1}?`5Uy!nHFg{<*@Da&A!mI_(iDdIwQNMMVWg%36@3h*Uv}AP5ME(mRAs z2qC?9(tGa->5Y)kOYXe?d^Z<@Wfy(xd-wO7eD{9eDbvo(oSAcPtattGxyQdM+>oA| zd)OTd`7Zzexv01}guo-Z|FEeI<~2AoYGL54-gjqT30+p{bN{4eR@tNXj&5+FWvtax z{Tsgd^6tkc@AJ*cEBmrX?{&l5T$|wVjkD^1=FUv^q6<% zy$?VC{Dl7G-bm+B+xYkMFYF&V>C>;j{`w0JqTSc$wH>h`LmWL`U7N6I$0(OtSb4x{ zfYoOoG`-gJnI~TJ?cZ*~?uD-ec6@Sj%JIso$ik~555GD4$sbDA1W(veJ;!TC?bQq3 zk93=MvSGu9Pr64R|KzK$+H4*E^s#r^PaCptN!!DI?9ewNId(UO8TD9t8X2p98rc7~~UKIJaK3%$WPdQN; zJkQRBf^7}I~@dCRaT-0)X_Od&=)V{oU+VbNMF8aWsGA9qLtA>9%xS?HR z|9LxFcqiXA?#nN~wCy>=ea)LavN+=Kyu&A*@Bet&a*Gzr;;qQmIkG1dc z*3l$>hG^vU@#FXKJ71gje3Q_6VcQjfBl})=zbE(Ye)8P@mUql4zQ6UIFEwqmHR{`r z{g?VCw1^69+LS~gcU;arc&@?q0c(8E?eBPb%#JY)F26K-Si4EB?QAzVtsfPC%ZEnoYvsk} zPxR?I-g&AOuVI5n3_3nw+>&Q_-w_xGG_Y#LU%r&z+PM4~e;P0-UsJT=r+=&(0Zo9W zfOS34&w5{S=0iA(fz(C+dU^wtf-Bmy9eSNO&w0$c;`|CJ5-k(i}%3JxR^F7qB zU;iO*zWLVt_un6T;KL6;3jOlSnWey`88f~V3-I~M%$c()Crp?a%dfpV4<0;ZQ`@#} zr_+A~FaS_mR89{8s&6{}pP^UEo5nUaHcyQnJ!bO9AAjQd#TPS*mn>PDXJ_YlDIpGapOP!{PXE?OO`CjbaZqsKX>k;skr!@r<0eG4YuA1r$i4);0Q?$3$9(eZc0zD zkRN{xlm7j;f!BB7xJB;1dnd40tgR0KN2FP^?;l*Wzycpd^oLPIn%Ns#;Q zi<1W*be2aR*(LMlWlL7pWl2gZxISyv!m`1G2k!*$*Xw9_l&jj=-?JVXOq=%EgL1F9qLq;PDf%3D^v51?Qc>Zg92*4uSJAzyZ9S0S{@^$VZws4ixKV zVPf4pnla*`BN;lJ_L)Yh70!GdKag9Z)W2F~g?+5-0i>bL*x3!C`HiWMtjuUxru zJuonn`If@l@3|_@7TCahg)Kb0iGQ4rYFZ0RBG|LGx7QRgK(I^zm@T*9HUkHK5Rxd#CCZ@+kfdlUSm9bfCtIeYek z^y;+}Jk~JJ7Uof0Ro^YRZ-95}c(#l-E4ixvTkzL4V8Q=HJsEf!>!4AiKtmQPk0woA z7$;utwoc}%x&$5fq#*};dE<>3DJi)un>OvQ!e6>IYSc($k5<61$^iUdU%7HsJUU;y zXpuK#!~3S&!D}0MD-9Mp)(gLhB$Fl`XWf0l{e^XO?xyV?-YfnG0i{88NY}B-zzy&M zJmmG)!({kyeZO7)@)sAzh%=yh^CW0ULYLwgd%tYhP#`rm7fr+>lpm^l7QvAKULDC=?cc% z4eSLUTLT}(|KW#i;X|0j!~}|uk2kTHx462xN?~E11O-`WSVq6~^wTwL(INF^M`heN zPh^&4v@ar_<2N0N@va(j`0&F(WbQ5v8;3~aCfKK@p~xeYwcsvOr$kClPK~TxyP<;k z)fT)hI%LEZ;NE8T>^V8aiPv`Tjzd4T%Dwj;01w4ML21|}Ha1T9$5?E_DfA`)8hoI^ z>jn*>p-J-e({pI6H2hT8_Yl{EGIp%1B*cdp{gaZCBs)8sShW~gRDi!p?ClD`-xV1I z0J^?|uzNws!B=|sbzzL4yuR$BuT= zx{dn&qs*Xbhaf?bSaj3i`{g^jO}~O>WL`0ktP7N7&d3$?{(ok5K%jYEd>@z!J0cZ5 z<8Lo+-kczP`#DJ0uI}LOB`>_-&3i9-`YENs4qhk?3c4;2u|J8B^z>MGsk#(&g9dkZ z56REZg)UEUb`(cPCpmdiX>c;$$HWBDC&S>8*+SHD)8Oy#Z>(z%4|if17jbrWHt<&5?d|Qs+mE%Aj()mMSq6><#|PcRy(Gg9cye{DKefz2&** zJct*SH#)wBhQq{(F_M}ZD-jVPtkYm@lbHt971bxDLHQpV>JOwdmhNfPI|wPgW| zeCuD2f&USF!B%XP*=7-67Jz>%z@q;K{ylrz%WJO%5a;_tL$Gw~7Q|cu1|82shss2C zihs&k$Df-teDOsXvW(mH5#j!>95uj>(ajX;3*> zXiz_=awsV&K*y5taY}>wI5Q2m;;r%4O|ZUuw>&{ia4I+--o#v;GG(eSxNH8b0igPG zk~Dc~aBw;N4?>5?E%4ut`u2&I-U`srtCyLEUcJJkOXpM4rj4g;-FljR-bJadu9EWd za%4~_r%#{8x23ZePlcXD*7U8qq;e=NEnpodp-Z!G&|t>@Ce9kKSoRdwckhtrJMEIV z_#)FuN2iKUKb^cEv<=;_!+(XNqhoqO!A15Af%4&pu`-~41o@FTARbx7O5eWGTqDu_ zaN!8O?ATFC+(P6+{B`c!Ir2DFMl7Q=R8^HoN=l{J+GcW1CeNd5A{^TkWY{K^LuqLd zvPojEs5F>kzMFBb1$W|h@*0}sc>UGmQc_xJ+OlP9-lR#N&Ij)s@jv{3fBpI&iGOP4 zop(;LJ`&kmM9IK`ihlx-$eM`9F2xd$2g~;D?x>LvhXNf;EuU@@+{m7AgnKms}#*a@RpAjzu1|>sBl0k!wO$>am zxq-XojrtCyLF5WFT$O)KNRrmA-Hi3!uAMi1(hV9?QWA(=WASy7hK*ADR8d(Xkr8R| zWj=O!t+Z)JMX;vu;N|+#r-4vC$`+8 zqD!pdaB{5a$RJK$d@)&u4ow%Et_k?P5(~<|dWHS+;lxyM_hHUp)_MTz+!uZGku6&? zZqN`D6L$*@)zzi=IbGAX*n}g}?%BiAmLCUe)8-&CeVVUJN%nHv9ujNM4zU%bHo0b=XW%*@QPf`Uuzm7?UQpYr7Gx0B?hmr{{M z7I>w}zy4Ls+Pjqo#eL%VEN~2Coy15VwOxH9@PlE}t9OV&hx(3=&-t<+&wz$3Y*eDL zmnkaBfv#Nm?nr+}bj}GLI6%j70lm>B>>s_^zcl{^@^v?$;eEd85{)|7 z+SwJ!S6`)|N7>+>B*S0Ike7z%V1H5!8c6dSuVUmeZd@+0WF&i^1Y?~K#BTNLZ?;!T zgZh#_eemTc+SAGk3y$}A@$lyeHctloB%{BS@>r~{LO&ui@8dBtySF(UyaLJGf6H4Xa{!7@} zB6K8ChQ634Lx!Y4Lz0<}foiwnrC+}&>EAcXkVoIX;jD>M`0!x(k^y8wx34@;Ol3n% zqOrQt(5aIv^c3%s#8m(=EFksCPxem89XZ_z;;o3Fl_pHNm-R-K)FK|c8;0h#B? z)Tx=^o(AL)r{>DwL0RCP2Chn57HcF^UL2AkFAg=+F=R**b}PZK!D@$99{td(0Rtip zz3S8<*pNlfp1NKF#iqN)jNbT0PwCL{gp8ly#JV_xzb>hnJ9l0xcxevzwqCS-Z_S#u z5o%A<)6dJqiE*-V<7t^WGaKAfp&?sFjL4H$U&)sd$YVHq_43QvfYJdCFDl%mWANac zba3n)xkN!n1oVU>%MkDnh8O3x z75_-qL@4+Nu_io;ZS7^kL@#2dv!e6u+O0LwADF9bfqF z0`AB0(aFS7SMeid)vCMy4csl{FxD8>bYetAWVYJY!otg}>0E;j%8F2_bhY&x2}xY zO>L|C2Xbd+`03i>;>&XUcnS7D4xbQ5e32+~=cXDkb7l%QE0KI>9P1?#y$*q%0QANO z+4#x6ec8kl7qrfDo$*R_TpeHM`ETL;^Kls48hD?1B8W9&h?nwISFc{J#UEWF9zH`} zI-goxGJZP}UI(#8La|%%vTa*7d$DqS??voNtzlc(qvh#1I-ZWJ+Wy(w8UJ?Lh%B-av9c1Al~rH8UbeDoq1RkC$a?i-v!K^SjHXvE zRtv4HXif(!tLu7w+{%h>bi8>ztDniR=GI;P^vaIga$QvS*|@SBv0U}`jopc5m-64b z8asZ*|M?X>7wNo~D|8s2x%%mS=(AjN^)qxE^ewETSIm4+J}F-ezHx2DXXTs0Pd|py z&vaab~oMl?ID$4ZkXjk%RhooJ5TlP~9*lB;+vp0o2O$q+4+~niqdtLkL z7&_K%PHQxy{lIU&`6kuX)$M9UMU~0VFGuFi4w5II*iHRy8}%Ps@_(8O)Lf$z;7&fl zhdsFi`MU!$YLuHCx65QNP-W6FbSxe7c5tBGh~>*y@O_sAQ+RlZ3>tWX8vYi>)$@%wE;!LtCyQU`gX)RON_pP;>3#Iu#TfN#>p$>$!_Vf|GbNfgx72y`JcgbH&}(oV z4k^Z&m{zS0lItlar{I27=c+FUXz!=Gs`@f`umkl`tqof0;~Uw3?WJxIE8TnOJ;kAZ zJy~l779QvxEr9stG%>EPQ7_Z;6v~SS?vEr^aWHgJ=h8VXIOtmS_4TdYwk?Uenx0kC z9ILrD+@;Gwa{WHk*>YI(RqRVt4>!SQ<-g|3E%o>lm`kBX09uK4=-*6N%(KX|lOdy$`CXc{u)q&)C|t}CUV{OA*hIR_Okv9ad-eSUtP zfkU4@JHcUd-Td1AFu8#f*qbD`R&mdX8B7)}?CiZ{T zIyW$G$IcxWlT!+aJspvi)}+ih+<*TO^5Ze&=_1JQh8y|!f`VLVt74z98yvP6I6U*r zQEDN+)Jvjin@a4OD;Fp(&&|*&rAhhQvgI*q|uTFm19TU$ldx8>xCNm#Js#T2@TI9 zr>}l-x+qc)cmhwSyutg{A#lgXh zLu6!xk^j~+0u>c!D)kGd0DwEm>*)~8??UGrK^vTKe5!-R348$>Hv>p$#X@Lzg8SVp*awl1d6Y(KYHR# zjmL}i6-|!I8N4m$y>8acw0>r7eS$rQJ-Anj&JAd6NldS~0&{K2T$5qn-O&p>p!H(2 zPCWLQqZ~OBi#?4pa)qIxp+=oGAi$qIv@iHYpoi)YbZw{(nRV05M{_+)&(U@2bU^o$ zI=|t+)sMdWt`B==b3WfvsRKQu=#3PtGcdi$)6oC{C3^^dFsCxE+Y5P|7J}=>pRMiu3ZDz3!}GBxsvk> zfcM$xcP2P!4qj^_=GxTh(|Ob!YS;_yt6LX3ry1(kL7F$;WB4?kvyT6M8ar&?mSh?> zEK2(HjwL@Bjh!*`qG$II@_^p#AtTw(RFYG#Fht zwPltX#xCT!m%N9c5w9@6>fcWqw|INxnMS>(d6-1{#{<+@dPhq8X9GEBk$}y(h+VtN z_|=A8IeWGg`is!JWX4Ls&&C+_h{D3t1`a)XsC`g>t+lJ0wTDL^wWU^&p!u^}of{aZ zF;jY48FZaDyhUwTc#+JTtGSLG8jDzO5M~}|LABQ8K82D?>XZI!#+_7T-{w@p~m?afwvhi8D^46QG zyN=|*oRFo1y!nRfulirb!4iMO##V5qD1#g+dBhQ?$(v`8&n?BaXkM4IAU)%aobJGZ ziAEmOf`{gDUw9#iJ`u8W=V^IwOpLUB*2A#p-EG{c8#=IdOF28?_KWzVjt4j5FK6e| zj8PyTe{@<#yjH|~xvYhBBQN{%%j5txmuci=$t&08V-=771EcVvp`v+M&FyOrws&tI z>DSj8Kapv~p}!S>)!}d>{!|*N{x)M^;4o16WZ8cN1{8|j@jThNqlEK2 zx!A%yd2{4xdF^%b&97?iJVRc8EgAe`@By6b-;-bp3C%SX6cqpN{YO0AjlZxdzVf@oR2DxR1kP5gZF*rS!1bbV`|Kf3?2;GkFJ@&B^_ ztdBz-9)HUITl|c4fsk+MORnW{(g-bbNiq15Zctc6`ar?zcfKtB{OZQZWlSAg=g_${ zRiSfhp5h^(BVfr>jBCP&-|?C^Z6Y zif$@3=5lH`glktcSE+TJD|%0#X&Y^;eQswS+I>1}=B!xuW9bzYHCKazil}{svW^{y zANLwCVuT~LwrJLGrJhy2>hA8IrhT;Uzng>SbJwm}8CRj`3@A=-m3ey!`xmJty3<I;dSN4Q#DH^(h>Fm`XHFFif)?DXk@jIH?U zxSN12z&=37KMuG7{y+o}3uHq}K6wW(=19N~7gpBs>V`ZRf3u6TTZZoMALhFicipv@ zep}e{?PS0IHSbpeI{q=h8BiLuz8VAnl(uxvL}x>XGx2vBdt&!A9aH(l)kbxosHp1t zfc}oqdxZ9T<)Mf6BUdjY7U|e=3HR0jI==GA8Q&JdvkUBR3c!6E_mZI_h8mu;A@e%D zvSIu=s%P%*r^ydE!tbNB-A{ZLMD1JSjYQ)+Vx2lI<^B(V9km!Y&fa8EgQ$ zbN>{5*$cODL9Z&P8SGQNodX?9347*OFXsG zI2Wd8dd{CeBMFIB^5`R{=%X@WzuU-5R<1PmDdjpgkgDrt{5XI1A3^L>I1kKOPMxE9 zb0^NSCKJ~y9ZBF@!#*pO7(bra=QR5Zc>aI~ZJhvjzympW6Ms4xYf#4qF6f$k{WUNA zf4Dr?F$^5_tg$EU`K}f+b8yh}y&5m48)ta*{F(>v*;n(D4;iZbw)X zM>(HjTYr3mKhvg$8nJKJuF29_=jjxUZU)O|pQoxm0B6_>6cJBk5@#mBtMkNm-!i7o zp*nZKfQAi^z#r%O{4wPF{c5c@rn1+|CRR%29Bd4=r9x^(*Vz+ZL5He|&(BCuU^Z(g z6Mm%_y8FTlI>+~bEwB%M9+PjsjnsXpMZSi9dU+NSXL7!(Up_p_<{VxXG+x&82F9MV zgyS+DJBGuzU}Dq)bT`kSrKYADx>vJTIcVfy+P1Z4Z(UqpKaKTOP;jR9%Neo6H-*Td zkX#eHBJft=m==4+c;p@>|9B>x*fWg1Kq31j&P4z-XT@+H=p?q)2|aP=e$7?O`l?&Q zo9&Og<~lf>=6pD3Ooo+9pT1@6=>^>s;_Y&HgMUfHx6$lPBgDnE0A6H}fAVK< z%Q@FB&h*J+-MD9$v8{e>R@p0Mb*RDxn4n6;IhPbwp7*gjdq&`;2JbA>+8LZzl zWSb~GY?7Ean)jSt>B09Wmqdu#_Mh9gx;Z|j)*6(bUw!$9A5uAclrAGjRuHFF;akqg zuougbe+hAEz6=_W$DTV&dZGt<9&R9Y#3hR(;mZZ^Gkm};_F2c*7c?3EB|a|ayt7jQ zXQq>6;)E>rOC>V$wMydS3Tniq$S5D6hCDo+=RxctawG%W{_p&Yc?M$+!#}D#3Ja@h z{ryX1)5di9dO;lD(TR|cJ`CjyN`$QWK2dyq3t4wn*VVS)j(@B-$DiikEpzAmQC!Occj1TRl#Fs0FpJM%0b&q?XjcfckU&yZ4s%+E>TWv2;uwTjMY-548d;aag~* z`0yWIUrhgE2=F}+0-UV_eXsY1{8o3KwE|WzU$*SR{yn?J$K6$8!$J+v_j*sCX&Y@@ zf1J9$`?hV`Bu@5TvUFh(dKZX2^#cNUA1q53hw{u@v<>a|)gOcRtM&fgoqU&xb7^K@ zx&ymr518YMJMP#b?b;rsO_XJf)rtdshbUeyC%om|w@-5ZBbGC`CG?vM>;fE#EB4@D zD)@d#1ZNNT7c-eeUMG`#HGEIvj5KVxLY6HK zG5EpU2A`Eb|C$hjk2*?j!<#V@XqI{akk**!M`a}GL18WmoDTp-dXY(v5fzntX>gZ zpMQq@yj=X{t9eEE=}WW~Y-%wv&nfcsft-I)nG})RE8v`ElBldL@~hJULx1d##&Sl! zfViq!9(z0mUyy~*Ns+%j94XU2%aCzn)8xqh&|CDUuD|NOp}$@(0dnkMlB`&kDxZ9m zEE72QF=IOC9M^@5>q#F=-&^#z-WY#q{b+y73p{?;`aP?)YwFyK*byrHrEF~c#v6Pa6f+$Fb)KU^6jew*G(kY!wBPt+@ zG%VdL-LOBt|IhpU=bSn7dd{8KecacbIcM%`UIPFifC&Hqs+%JO_-hFO??3>6M*mOS z^8tXFH2_#y{ZFqk06=#n03eb7*+~JQGzS1gMgP-806YeO3X^X9aY6p$BLF_-8-ERu|M)ld+W_Ew4*8FNqi;9}1mS;t z1Q0<20R5tb|M3xkJ>;gp3?UGytD{aq%6yYefI?G4Rsa9!|6hbR@d9S9g)jb3x#_Db z1LcG8^&0`PQ+lKX09CPMm)19901!4B`i}tMEzeEvLIL3X<`jAj06cE;vS9@PGN}N- z=$z4{CkFtQ`kJarC~u2xf3k!rnW5JouZ6aEw%R{x>wb73squ@8_q%C}&!-=rHE7%-@UixxTVPWX& z!8zh0M57#J57#qxpc>c@od%ubTLWSa+Ru3>$rB!=Q<;`}&NO=I?$+z9H1D_P(U><(LG)PDUpU~>>nq{!$K2uN74tL!T~vzo z-Vd-tw?K7=f`)hpjBMxp$)3c@rIJ9&;($`+dyE@f`0i@=+Mh%bHW0+$F29|5tNjmX zx|LCe$YWaxYAHwY*zG3hHtGg~^JeVXpCRL&oK3e?@@MeCxu5c0Zy#W3xzIs7Tdgvy z-*S2fPkrcymr2E5_$P0^Z3n0D+noaRf>UGcSoyO5v7<0hq3L;3kgq1FYchlvQN0f za`nwoKucfPkF}7gHyGHnqv_)Q{*$eKE1TjhgDmRPCTc6PK=pNFE8RZRR@(l+tGDz& zu5r^lzLyH+ePerV7gtSrS&Fl=Q_S1FN8Sp@Djy;r${X3_=o9!oZcO8qKW#bRaUg%6Qu?i+y(!llF_3!DVwzL-Bi6mEj03XT+BpONJg>*~Fv{!6|B$TtVs+guYB#K8#! z0yD&quZYL(*yp91LI(Mzz^xC7wy3fWu|HI zx993WSVsep(Mi{_;9WpjMuYUCV`rXQ%$|295Z)}_rnR2@P7UNsR464l1Lbu$xyVm*cnv{XN zO?IeoiOkc%m?1eI##334F(5CnE&k@+Wk#7?mK&hTufT|tF~;Oo8E{7*YfVxO#5kdq zC|2ocSVEKFAS&ufUyJ9ui{)m>)t_vfr)lF(*-t=$UYY6UK$}7c9=L`&(_;ig)Q8=D zE=csN7Y5!A9VeBAGpiU2#%&0r1G2&eiAxOMDM1qtv6HcJpfTbkf@ZUEf_LnS;MejK zE6srGadyX#oW5twM!z%jg$eHul$Gg+3kU+i&+2PIs8{+gw`3FO{=q7@3yDi--2};m z)tt+%QlJ5HK)?o2h}OsA_Wk78lPd`2fk-k(y|penWV|XTS@mDmcH zVd8PJxJD`IB=~owQ94`pE_&#`YdMk{l=UMNqqAMGfK^vGiP`Y_#}-0C(6Dr+Qg+MC z-s^dQ2qqN$0iIRnukQw?Ong9x9S3Qvcl?t(w{-y4{NROTx2&|3Uxv7nnl(Ff4<7s( zh3$^VLb@KmUDE~K5w6;(K(qI;?j|qXMv68Viv2=MCfy>*FBC97{_cX%eOyTkegDut zB99Bs^O2Go5(i6Qi>>-(Y;?*bt40*datgXbh3w1Ehi&bQi|8JevehWCV?sF738Jfe zx5#A#f2~$e7A&G{r)D4gTnDHK6d4oxUt3aBG(;P!3HKp zVg)n;k9P*==_530DsK^Y@Q{!?0N+iiKn$H?4wm`^p3K@#GcXlI|F|NxDu$HZEfU*z z_Thk?=JetG&`0*Xjz*$Np=v9L}V5QRY4jceE3l zwPS!Jl;u(oxoaT%9g8zVb3zFHQVQw?$^|ZLgM7*?1=td!z^(oGE|3-bt=)2+->}{!#f}m1(+^U0%=Njh#X;Vl!p1zd2 zSj_Sw^cy@I2Zhqej@qS*I4aULP+<+Mt2)_o?g}dv-3u|14vHOjBs&D%E9J)ys=Yj# zZ{%JF(&*G)92wb$`-AtTGCH{}4eYy{9!welj-D@-x_eb1flQaubH-M&C*z=+V#VNO zp}T_LxCuUg632Qar5I*l(B)l|9y;P_%#OeUTc*O9r32+8bAo1z23-|O=YN&5TMBg!e@XT`C=T8Iw zN*3mQ6!MhST+-kSQ3{#Fz`deFzI)}zs@zA6kXkLun9WtGnD*u*q%@7@xgM>Y#@7jV(gjSVt}-or`BD@Q5JY=~Ug5d79@FQ!NY~KN_#zaW>a= z747cGlW$a;7V34v8U!*;f=5i>xRVzbdYPSY2178vIC+mF|J;I$pgc|ex-TO0J1ftb zj7yLEUZv1%sUNzn9N$zVidiLh+RZ{3&wSDE92;uK@bb~cOgF12ynm3^Ljm?X5aAqj{L1cMb%Mq<(I1X8Zp%1A9e{W#KOyWP^Q05BC= z{5<%hxd0wPN8f*&)meg!uan;@cU0s=j8Ke6{Ana3KWz33!NCL%BeC?=1{7q5{ON_B@@d_=FFlOy`iDC zKy_Jy_Jj5x%)VxVq+W$1J**NhV{eCo?kp?I(4_f4kkuIqEN<$bdD9FqJ$#LOJ=Z|_ z^GI)<{&exwmpm(b85)|er8%~sR>(CeMh+o#h0)#0D;3!NWB^{ir+b!mhjaY2?R6iS zX^_N+S9+tgw*X+~AWUn)!~3yE;6nioVG#+D5;#~l(S6P2Elj&sm4(;jk#OuF32TtA z(-eNwHpfq(b6$Bwm?%(!N7gEX-yGtk<`ZT;aA;nkIj^#SlF(1s!?IxmMVUXv?Rob>$qcyesOzR4J`-6AdSKFd*`PBQxNQOgQ+-^ zpm-qPAf7i^n{LXsNi;ZAX|?py=>zB@36-(sufMLuSKb*D1Em+3T}2qKngtcN<0}el zIZNr+Cf*&qnvddch(GM7$XJaH)IL36ims)lP-9pV=Je>PQYXgP;CFr;9FP$cnf@IG zXKbgaBDM-4x27Bc6HbD7Nk&0(q*b+*N331svowQpggEMDU5eK$UUq542+n>DhM#cz zH|VrJkU2PbP)15!F6Xf1SvHsRIIF~1X9_pe~7tPz*3;X-0t`X~`$#B_c$G%Ow} z$C!WPEK5~XCmQ_pv;?=+%Ewv9UF~4^=eATqmkl#F+7=Djv&jI6qAz5FA58?n@&H-z zqp~q#>%!@bQMuA9Ipcg{;M!<{g?Ko~-z!5QcVBSWvwNZ3y!N{)y3s97#K=X50usr# zZQ2ZT_;pfSL`th=AgFt?d`6Z_`T0Cv2W|NL=u_Dra=PkCYO{<)US1@_9|45|%3R$( zUxKesB#MY3l&%m6U7L@g$FAQtRwc`P>3PAav*T#JM=KVQj4l_l zJEF&?p*cOJh4j~vaUF`=;G|rS`{G20%o%&F-dx_wzv<)tFrSeoRy0^Al`T!q|pVtU~kaU7g@ujB)zJ{e;FiS;k@hM*Zz%0~6M{s;j|4ua^(( zE}D;J3K+YK^@G>JPD_`Od?tI6`ar?yCHwn~ir8b#y~i|6s?>RT8i;2sJ@c;3_&74% z;=e`Og?P|8kb!bZoi5q{mlip&?^tV7)eU`2uyl+6&9BH%vv3P;rC2gPb0nBB?n3XB zmGQn&d~CWGLR)kvxbSIWw(akr07*hA$U7rYMi&$#xPUqFe$6?!C>e8f(G<8u%pN@v zLmxJ(IH6LrQd|xDI49t55U)t4z|;PCAW$1tz_I&@{#TJpL5<*Uz|y2F+OiRyOzYfT z!%4>-1SwP_Wa}_3rwv65_-Bcf2Jrdm=-KCgu8~(rrK?5%_RPzNlLZm0fpMu9KLX*{ zMSmV*IJESVM}lX!N>)Sb(Z5+50_k9g_Y*?r@=$uj;O3p{0niqBU6`X3`qj;z^ir0; zkM#04QOIv~gYjiJd9(ph1P;3k^`n3H$cJr~9kDf*$5U2PGuW)s#!FWt7)| zc20tl>$nB_QKO#LomT6E#uw;{_p<1VzN&RP)wdmE#N%Q-F;!MH5n}$aU6$v6ilB)~ zqOV#iwi-$q4nn1rt=_}JI?6GHrEQzx+! zks9G&qC@-TKXYB3^(WE`$c)v9pN;6iV2Dv-j4k@OkA4BX<)qF;6JC2{wfMeTU01@W z-Oo`1Xy?jdB_0L^_6ap?vSK_zt%*+V2qRmsaQmb%r!u_OFXO(da}gtO)O+-_0*<*Q zD(DU8XXV9BiDrRh(#vFFfHzeL)(jL}w~XG8_}uc?!M9EwH!s1f2RJW!5Myn{`FrBJ zRbs622S}qWuPnyG=}iSM+Bdb5xUg-77d98f-nt*W%!9Zo<8^8-h|C^EY!VNg6Yu8R zoP`?%4HDgz)^>&s=Z+9d(e^)6jyd2E1)r*2N%o^PZ-cH=?ZN)(UJo2W0pcb`bzaGw ze6=`~$1-dukF`0f?JbeI%#O6q2v6-J=}XXkz0jvSY}5S{&-E(*64)Q19Uw&&&O=n) zsUd@eEsHyp`1#0fI1+tTEzLMCrEX06At!|!^i#HiF`8}6sh&8mb4*~=R2mH%&U~^{ zGi7>Op}R-lIOD=Nb0Er}lEJomPDEXp;h*MNnfs;0Qvza0$tYmWvjQ0g-9 zO8?l>RO8i^-h7Z6El2bT>)LHT)3kX7v(c27%4Uy!+FLvu-mQHj_|A%*1Gy46#qyn+ z=jtLo%k9Du&oaJtCN?pIF%<8N1pSaehvdj~u+)q(4(G5ajl~b9yL2|l{Ku?|S7C?Z72f7)Oa*7R0cD%GCSkQ6_w=Rh8u z{Cw5TE5f#bQg&%LUxam6apb<@s;_oWU&MzGI7}LuCuqlEvA~1!x%#GvS>F~{0g&28 z^%*j3$c)j!&RnyffBBm|C(Bk{sMx}YCJW{xl&iCR-S=AwS&5bBbuJQuY)?>DJA{Su zypJ8a(_$fbcY-8NW2D3!xGOmkH0t2aJ(CX#H^(m`-1Oif}xZ@juC-;y2d$QU*sdjM!%{T}I_vrnhhHFl6CN*9uEe<7QtPYU=R zs?@E*HMON`-5_D+4)FNqFPO|^%c3jN@sdSZ0e|(Y(Qk#m(>@}DLa#P}fuaE$9jeO0 z@gB{}Z*=!rE7DZ&nPFvP{;>L4_THR+NSHGsJb8x3sCITto6IJdfl1h}33FUkPW zD@_zuF=7RL%#l7iJI;;cdSTv4AE z{eZUBvrih~xU!MRk@l~`E*Z`G#>9R{*XpkiU}B^0+9d%F6<1sRN+P zjT%Gr6BMcy#ltJViY5hG6x<2?qo`&yNQn5lfWuD{N*%@KJp6c@&aKcB5Cv%!$`zM_ z#p?fnY5-=q%GUjw6RZrulRyNmCod@^bKheS$?tYz5v@4b$6DF!#(Hb32~AJpZsQzX zF-6Dy3K$%u%zvO?NNTCbmVtblVLe+bHML^~%A@Ra<5!Z;_Q9^kx`Mp^DuN8?w&|$( zFvZDWqRi59GS|qUMypk&poF<>{$wG4fPB|W_CGeF81+mjo;sh%fuNHC1gma)UeO20;JAkLI)_wW?_aN#V$X#o;tS)hQBT2x4?rW{S2oVAGRDE@e^+{xjerHga{(iOx z86B%QKv=pJ=&nHYs#t7dDfg#da`@cq`sYC+gMk!<+zi&6UuGtdc4i=<|%}purLmZQoX!G1rB(QJa;NY49Mb2Xkb4?{2fZ z=qAldb1@&>joFYfR7~B*6oVTgzO_GtncA|FTpC^3y@(n+mE{rQ$(0IXqJpqaI2uNZ zI4JU<>7TZ}^W_wi&bLxC9zy%e;d!1Gl-7J}DLvKpJAEsV<1D>zLV9^Jdz?Tkt_d6V zBRow`IPjHq0)zGfh^~a%ps4y_aZOI(J-}_1;uddD%o_)d1FH{QC|N7 z)VG`6^htNYx}3!TmlTge7Am{!43QvRF8AQsPyJ|qb;1+Am@n`j>s=Rqt>U8a`_FLo z4d~?aFV(km!1hVO#MI*w=P6#1%`EjIxNICv+GUQ7ENTB90F zj$FLymx0}KI&0)Pe;*pii;?BdM)7xC90(?*bUy+-V z|4nLGXAy())uY{o@t&(#Y}&vGT5|Q%Vp?jdS>TrnE-JlwS@q$3B04X_4y86yd3kd!9V>2WO>_Nap`7mXKxG8A)SefQhWJM^&3S1}R6hZV@S>V4V1QR$blp$3jBH8U-ym0bPd zTvpX7hW?s5CS4tr5|NLzY__B+bX9lDAn3$)eLPbt_!?;FFPli{BalIIIzJ_3?}(>k z(kH8(Lyta@r<`;yHyqb1AV3a< zd9ENW4%3;5CYz~!Tv)ISP>!-}gs98RzZluOb!WGBSVJ4@SC>JM5lB?5*F@s19TZB- z@Bdtl^$O3|Z#-yKKcfo#i6LlMy|la#E#GULCBujfPZ%P6TJXnn2)LtI5msXQfkUe(!9H$a|KHQ#{x}t9tE)$l8YlEGI#hxMF#e| z{s5Vez~tSkmS6Oa)A&tT9W@8SXSx~sW6Q4FwVVR^JE6q!yKC-rp1@k|=-AMSLVdLds| zcO)!VHFA9w!P$nX2d`?a?Xqa|kWo)x5sdNjRP2==1(S?u4ocT&hjpl8Jk&TN$doKe zcFuFDQZ5!REFpMC^;VhoPp6CC`cj}5L?&9dhS}0zmATR=nSm1UEY+Tx6b2u42VpIw zh34ky?3ah8%R9vZR!TzW97^qrY&k+%C5zYWpi9!VJHk^CQH=(G@vp}^)jM(BsEdH> zmL@912ODkG>dcX$w$m|TJ6JsihGpvdA|j=TQwaDyR8D|I6E-9_J>9&PY5alnnR&WA z6UoiDnng-t3sFJtz!R=7QuvvCQ*K`O;n%~X)0-sI7l)+qeCiuuOCaPe9C#sK7V+<&Vyg; zzLmtH7Ku=LoCcTYDny{ zOZ!>+`{1;QiDfCJYX(N=dre?`kCbgAwOJp6b;()o9yLhd;I1U)KS*4aj9Zm1f1oQV zEN@`MD-_u`lJ`Df@vhxlBD)@rU(Y(bHuu_!kM$x|aUtqd{*X&AI7UZ6^v_QsWY{H< zR6G>Tp^V>;~{o960RGCQ5AG)im%(qgTyKB&DLJL`!BWAZ z6Ejc*cZGh#K-7sTdhy6yK8Gs=dMxRjBcnL|_;z`dJY%G2QN<@pqn-Uv?d&-d>_|d+ z_3F*HN^Pre1R*Ut;G|}V(39F0{^iV#oa%;lMJ+m3e(f~htG%q%lO08(UG8`Hj7wUN z1AYiGTqitX315Qt2c5eL?<7WeWFvn*mfO_f5M9|YV6$4jSvYp4>EydC6F4+i`mwxl zJKPxgA(tzk+^-DvbY6MH=Yx%g(lK35GBM>k|HR&Fq&G)@fg8KWht?C`Kyr%|V(5#+24GzUdYbf{!m*&NueoY7%Xkyn17kXBjim=nIy71SrM4Xlk<@X0Qk^WIR7{sEO^iY*Bhw(`>*boPq-L4Goe#H|M zD-&wY7&nSHyy8V7DrXma{xt@q%)wP6Or=+y&1l~tpc5+s^q*_UGL&h6-=5Kw1urdE z08c2uiXrVE7$nwMu8q48?1_0LN|7dPYiK9h9hA7OpGYH``4-3LOBKq=292O?(cRPO z?&y&t&6ASEmkWHiq8#Qr^}23*2#cayXhofhBic6@52f)+Z4jN90o!xp7zfCOM@D4Z3ebDbUKOdVR@K-iZoFf?su>On-ajCEKa5)iO> zbsh66B!}vCDRlh^aEVjpyuWHhXL_@6Fq&SBfCJQO-xW3WI`ge}`KT&la6r2oKC9|P%H$z zCy3gZ;ddA~BNWr#b&S*bH2hofXm%de)cG8qzJ!?6(o(VM2wH}62gz@>1Hy`3w-9S^ zBHiHbUCFPIn{T4nTc@X!SFI{UF0ce;P#}j4{sYn>jUuS4v61I*lSDn&tbO2Y`1JT7 zjU`yJF^v4u%*`MSnH5Xfi60X&w#7zfN?(Hy`Eib@EYL_(7_9%%-cCz+^|Xp~y;3o0 z@Zdm+Z}7;E$Sf_3ZAIb_KZ1T+^ty3TF`dG;EJ5xqjItmU-t;u&xgwzxWW`Sh9%%iY z%&Mow?4ie`rtL^s)xFhV_{~$U{5NenK?*_Lc5OlZ`sY|UiB$;z9SHO^;&Tx=Ze08w zQShbMbKkkeyb1l4#s1pR z-qRw5F_7n=OI{VJK2NAFUa(+jodWk9iN;DWcDzCTV@c3B5YI^Baj;u_Wj%64p;?fj zlE+Zh;0oxmoKlf&M=aU{>cHsEwY zKCmdAl)*3bNXYwNeY~`^{k@@Ze;FRkj3qT~BOy-&M2D!(8RFsZy_a^Jr|r?2ZCFb1 zjT21l?!>z=&()2l-#$6D{1E_^;{J}J(_XYkF_L~sTq68k%n1)R*(Strx|_x$o{4P7 zo*8ft{^)VLLsTUSYLISx1gNVBdXm&-g)|oKKSY{~n~e3Vo67lt)(-7y_m7 zrL{(Ub|3nfYy;ebYeLi^qLp}A#D+dAk(Q|f=iLS{PoS0NgdbsmI)nF)IuHvE!M4Ay zoa#^Pqx}APFj?f?$4+>>_pOs9sH%WHisic;^@Nn-k@T#Aa41}}`-JohyACLcKsRx) zCl5N9bmA5O<41xjH7IEsVuJV*J+@8jM}1u$ag_5&==qx*lOYEi1qFMho$?;k1|GRx z{M!*U^l4q)_aO`*s>{It=ArE=XMygrx6chd_Ptv5^J=UqpA_UxR)S_@PyoTc$C4|x zsL%y9_1Ib29J$}GlYmLIAdl3FT=v`w5JN2M^bvz4bqya-I%UAlm*|N4%K3fgmg}B4u z8MA6HJ{j0LH*rNzU6~*|Ja?M_bxnfFZODS&wO+%4BC59b-BMy#Q^P2s9MsUxNN)o% zlhu#LpD&}rxY)bxe}aa3QmE0Nmc031o~3inL84`N#jFW+KEVx>Sd`xIg8GR~8KyFA zIY&}lf31mtYwj4wS1$oi3l#w_TJ0;nHRQQK}4baJJ~`RG%p1EnZF;4j>Vxru#$xGgC*OwN<6*C zLttI~h}RtkiXDVYCz%8d7?-2pbYwP>WWCv|KR`yU?6}4`*&bCjFjFPYkS=RgaeTH z49x=MzoohoK>><)#aq*`goj#67(#cfr)s4y#R*F`OURbKG+2gTnRH+Ov^1>se?a_ zsga=h;_}t6Q}7o9Fhr=>@FiEgiqKYm6{p>A)3X@(0u#P1ow>9luv@$C`VR=}Mk#tQ zzT~!P;cqCqIPPFT;K~jfN3alGNf$)9_lj#Jbk@-JKAR2cElB82UTJkX)j6Z%XkXk~ z8TvguC;&{}C1M1BaNCFc`+ar*H;_ugew{W4n+RZnwLRh8l~&K?Etghr11q%xI8?Hg z-YPJx4zRh+qpZT|=%lx#i0IvaQyOkp2r}*dlq-LE?LeyAAEc=QPHd<7^;(9;vGvc# z*$;dd!p5AaIgP(G91&HgjxgjSSJB6XPk_qm9QA-6j{gbtJ}z$Nwa2gX62aL;=(1hgC`8TYKt zC@Tzr%mZQ4$h!)M@4k^}xRX#B$YnF08HcA0jUHu1eekpRyYPhA`S@sMXaE!{8$r?u z&*(7D08x0Oe+BO!QQJCDY{4cBp1P0n;n1F3(Zqow4VL7i!~%looZ1$e$IN zv^mJsrFp^by`QJPEA?dHd3vakCDD=&>99033m-!VKJCLLZKhbUjRtC^o5^EHyGv#? ztGNMj1*QB~vZ+tvN^~K#CtQqJjrZU44{K|_{K0UOexX#Vb1e3h>zc{_l4wGp3-b61 zh!yo)_01JdB4OkvgJ-PNX3-`GA`p9U$+r_Yxu(S5^1Ic0U7y5FT%IjTC%NY3xNlf) zwO{zP&#tcm%_;Q z0qP6`IQSCRp1tV~%DPtE4m;drBfNQGMhat=G&gxXU9=s$HM^Bn|1<_|*WyW9p73dr z%b7eak^;*`J-{6}RPkF{j)fcSM*6Y^ZTz*2KNfB<&hZKs-Bj-TrgIc(_jnP*;^?hO z`#$eWOlYtQV34z8Zk0vpbJd`pWe`t8%9*`1bVc4FT}~qQ`DDM=%)3ROLkIM?rPXF_ zC6*J&I$Qw8|GlrlEYCnKUhEuuJl)-EhCEDXGI6>)VL|#&eHoc|=zI^x*Tn|y*> zDH-zXvE81kEve$-@?#SQ3w*x5d-K;{fPDAt$LVk40`j^@w$<(Ft~%M&+6EG5cJc-q zgw}TKCda8hi*xi)1|2*H95=TM8=lxpF40{39xZ zwypYdANj+N)Wl7U34zRQo@K_O^Q;Nw(bY}sf_fVL#z<3@H=eG$TQ`>;fI z06tYQI|q`@>hd6X-OktUU3XWpu)1)NkjZEL&S?6sj4;eiR*B~Hf?J^SAOHOvt;b^v z0~q>(w~-aSp9@V>>42#R`%sW{0Q+JPKQLs8>x{Sj{hf7<3nE@)@C(PCv>h>p5%K55oP-+Yl%X`R9Io?|g8;00KIk=`2HMq2rjOAyF8$uq zv3zEe5OZDVCL~Qqj2s{*{n^pW-|>8?q)Ap^?&1kDH?uf*VRFS}&YR6>Dd+(7hDMtaJfhyt8PrTWQN zfKC6yhC{dmB~*uoY901ddXQp*j%!D-_x^d)B=N5GF8e#{K2V0wGe`&de$z?&({M_9 z#lepD*ues%n5uqShL>B~_9wN-gFdx1M5>h3I2E=BMibfHxPIoHOKivX>#c+(iOPlPa4YLZ%Y^asIDvc17`A` zl3*mPBwV0LBtYTDBEXGK4Vtz#Xh0fd8AjRKf+yndk9eIS}Yz3Ift zVkTVjO-NpIDumE2oYYeR#7P2>tVGP23}uVnQ7Xoq5y1;*a%bQoOEt|GS+=`doYRT} zR=Ni}v(6MiDi9NTynyc9OWs6&KFPzBj@0kTy(ue-LpBBkR7j5;yAF-3Daa=G&X;zQ zP~BCUm@lNivt)I8+`4}e3>J){YY0>q!ctsY7Fh{IBGDZ2F2zwQ)_3^LDD&!e zxB$7))afqn3iDwRvk*79d7x~ypc)P_LCrhYM2snes9JP{@sW%(iS}P4OLUSrOi?pL z&ji(EVu4_)IK;4#b=HvM@>mx9(C5g{os=4y2KC0FEzi#cMvZL~`gjv(Ksz+unYXhL zboT@QeEgQ~3|KM%j5^9uzs#!<;Xk;4_xQ#{-jSKJ08lXOT3j(mwQZ2V2qV1pb5J6x z$Z$$6KFX1|=QG-7cOG&|>QD62_`5pBtwV2OQ`O04tBrI`b{ldlDM~RWy}B^{qX~b8 z`G(<==xid=ko!=Nh0?M1L|-S-EPSRNQzRO_>GGH%;*BMk94zIuh2k(-({<|Y`Iai^mH`M(%f>QQMRI^K(2;jBy2RTx9T6r7E( z`ym(wr&EGrR)S8ZoJ8&xJq&~II;_V;a#>^#K?fJ#t~A-EY8FmjxyBlc`Z4_UZY^PT zo=+jmkKF3}HXz3y`~B=kx(%H@>AI}i41y(@rUt1NUezE%t5yH9%nc;?EXw=b5r%Pu zDsx6C=VT&Z*jC5+nZx|P#oI#Yz)p^T+{8pzE!*P4v31G2G+ThTmCMXr6Xc97vFZDY zAc>WoiryjD(Z$-+0?dv{G_^$_FHUk`w(QSCq{qp$w&fkH@y-i9FDaWcj&v>_&wc!3 z90<9HmQ=;2C?l#by{URaX9zx$bmfTA8XvrDPZvQk5;X5Dl^9+_`ipi;{ywW$z?6V% zXLLJp2(;7l&kdiIwAn$KTpwh80;5B~$1$JO*^Rofg?2CJMNnVDBZcKpxsOB>(v9WAztL z6VKd!6B|U~xB(rKn6cOR#1HSTzwX^9H9|iBs|ymI{dSzztqv~Y=iYZKGx`Fjb~Fui z)|eh*;O(NWzA_fu%ZE7Mt22bs(GCR#(Mr(=3FbtZC({DAKjvX#RL2jq_&moB%&&Lg z$Zr$&U&-tVD?Hm00o2q8h)RszMiJx^Ee2{v8=JL*GhY4S_j!_*n*@oqo=Y<$wU+pI z$iF8C12G-ve!JFoKBfNFt!5tV`w*%^_K8&co!WzAGzI zYL6ry`#v$BXVV8^P#$^sVLV)uh@}K@a8giV_Edwc9D4H*IYMq$eF)}-rQVQ50%q&P zjlt#FvJz2iT(YrAPq4+x#;>`tmIv+G`1Z(EvOuHF7)`OLqpy@Y8nPAjfe#Rmma{{? z5#^(J>&5{M)LOEeZl7N54}EN9uV1XT+!piNEz6-cvXvp4j%i3}UXK+6VgYT(vDTks zuz+A9EWE`v%-$ADm)$G@O`d#R&dkS%$t&t5vN=7yP}IYRs4uKAp_yz?J3>pGQSFWO z0(pQ!F&Up+xuP*yo5?{ovZA>doWzXr@fm&^kg04^LU|R5MM1j#CvO9ikG(4TuH8hR zJS7JsLi~VakVwa);-Wj!ZQ&nTaGB>~_scaq8>{}VWq=gjTnWuN^r`O1D%E@aKla`Q zF2?lzAD>Pdu`1+PO3v&$?K*~HGZS)7IfPJ6YX@P>3`R30%`BtAvg``kbqwXOj!}cm zGfuG%TZnR;FjPXL(){1oGo>8%^WD$y^?UtZ|NsB>doqXTdG7nZj`ww6_jO&*usL9g zN}gl7|COh!f1f#*^1A%&HqhhiZjK%{wgczhv<)04Kg`Pu@Z4k9@Rh!Q;;E5&PRY}6 z3eHs+4lO$sH|XhPC;4mHU{%q*&QgaVIkt*6c)Iv)aQ5!sN>^?f-R+07eeCDHFWPwi zg-tz=+p99Je!W0hXX^dJJKT_7Uu{^}YNxfQyMM^H%yAzbCoHnV{sV0cISKP8uebK& z_zoSb_fK8k%ijA~M*S z`^RL%r~q@{QS-c4)M?p$jP@7XF1q+Fb9ApdwH3cGuQ!-q&bQ(lq-}g&I%L={JHK2x ztKHsRKcx38m|rsNydjjU?S4GtdF@LNtaF}4-@5c|!LPl{T|2A|nBjD`N8qvRPLqdL zEUw?^?$L>5b>CiJ=$fULcMG>uthBz6*lVHWhh8^+;pDE-JqWJ#a=D-JkVE5D4|L7} zuSW*wI{UspTf6Jd#knCBxx@SRsO_m=z}aM-VB>P3d#&H=w&>`|nSHROW7nj$oNU{H zCvtB(rd0Gb2jvanw7j;)Zs08xJS;!%vUJmlK`lD9^|lf>DXuN!W@|Vj_dV;HKXFZD zXv?IhsV_te;%ZAh*L>{|bb0ynud?mmNLn_0%n4mC8fWfyxn93o74caGWl;|u4?5*G z(cC|KJNjJh&NGE+zyH{=o^4U<+Qm~Bt;kto9eexdi*uIu{%w)gE5vlxyY7i+uH8pB zy*g;>2CnqowbbRt77Z8LEqGcDcG@nXYKB`OU|u7{&HeV{kxu%Dz>fNm2=L`$7`8W!tYt;4!xZnRx)-D z{-a+RTw8Coi(GeN`{M6%GahnAdhC5P|3z_R$YW6=$Lr;31(P<`Wq@kp;RQKezAkkg zn>OY4tn5PvBWLIi&HF6&WKM){kf+OPbk7 zX|?C*yLq!`bt>7ae(mM#JHB-5?Si}$rK@XymGpZ1<;xemvwFsNi+I^^>?a7^6HnynUEysb;XCB&?)azFJ z+L|k|7vp_|vf1hx>ihAf=0NM-efRckZR=dPBk{x!OhM@|NB6w$A!`jIoPM~uCDDCW zt^HR{4@h>?`oHVJ`L@B?1!=?D1Z*BqFgTGZxmZ!ly1ha5v`^u!{NoK(PY$oN$^IsP zdq|we$VWa458oMeHp_JuzbwL>T71m=X%Eh|)vG*D4ysq!Z_l3{d|v2{s`V>&oqF%M zcUsHBJ1^upif?L5crG?6O3$(u(Zh%SW~HyED1P~@iRZ53jHEML+bz%GrTwBgp4ETI z<3G3FXsYfMd3aq|WYKs{mP5`(pGNCUE+GQ*swS>YBa=G^G#Y1iHIFzwe92aI)Bfv| z+W8$!tT%9xClU~^$ zALulpY($<{!R6?VNl%*W-ScDi5LZL1Uyl!(m~iOOpS{ZZZQi-J-nKKh2Xl`!%G=yj zw`a-h_C61alYVUN>^9$2+PKN2n>qJpl|R`M;&E?-lW^_w=q77d&zMnY6_TRZZFj70 zBX0Thg2+wHh2qgqg=RPH$mttAroJe@{&c9l(SOh%@8|pHZ;aM0{w2F%;>Mx9I(6IQ zWdF7GH}T($T^6(@yQyvd*fO8Gce`({Rri}ex{bOu#qsxzOAHfzuCJf9Ow&`nF@j04 zN*`)f(ZD)iT+6dh#@~6pqz6ofw6{ZdwHw)_{p?kPD)!C)aa`EQkovZ(Pfzep-e@yV zUaYb1|8s^*>u~ugYl&@(-Yai(P9M3g+rZiL!fX3HZ00(CR^dj&>ED~DHl1Ck;CN~3 zq~uN+yd}>A+lzI6t7n~TJb(Y#_vS0w^s)9njk^}VY#6y!yXa}hagXZcFWebYYs*wm z-ySLB%KvP~N%*Pb&TyN5ZvRTCEt_~C9h_c;TmDKog* zxi_c3sc7wTFmrOD*yH6dZxTAXF9{huV)vk**QcflZ#p(9Z@zJvxM5mv?l@(L;kzmB zFA5r(lP5BBGR;NeoLdhUh}0A67DuFvU)1Wdm*Z4pQuB~e&$iU&Ju3RvsdLbpn@xYL zce77Gue_4dVe{&EG=6@sv9--f2`6_`^V6IBPTMA3G`sj*Tio1Z?66IL@q${7%383% zK{(91d1+E`+bL3Y#ysHk-FPXKGxYqnX~pvb zf^KdWjbHTb#Il^pUK@YNc>Y~>zRlF%7dhlqq?x@3y}w&xn`onr$-DEQNa>Y*;gI#A zH772Ad&Vte`S%Z7j5@xvbXwF`jlA}>TD5fY7IFtEpLAtGIe{yxg%_hw&S-R3;sTG zX4LL>v+9r8s~0I=w;Vd z^XF#GvwCvD)fFpyJ_x?MKI&rktd8PeI{YehlLpoEIsRwn@jj^goK=)E%qq68SDvmc zSu1vae7K9x8tWTtIyyaFI4KlG?YiZWw)q$yw-?Iq-6; zzE*9mbNtWN^I5~|xAVfXg%hq!c-gHHSGsV{sA(@Rw(cA-Gblk+P>}4g>Tb#m)A}bB z9bL5Lqj!((ZDs4(X||YK`iC~^tF%2=dv!kjsOaGS#)g>pB_sZ*KXF`lPv_NfqM7?2 zI`p+3Jv;iYwsrKb(ck6ueYtF43wgU9jY8I6@P7F)d3Z?uB%#Z_4rLc!9ePk_UgV?S zU9Sz9-evUdapscVRFT;B8=UpjBx^V+{}+L4eW^&LZW+a~|8 zVy;yyso`DXt3zEn1O-fz=Zb%^I{#=>jEZh1vbDwZ5qNX#3!C$jdw9Mk5O zOGbbFjy((B+g^yYw!QGk)08moo0y5oSwZOS2XfiQ(>L4j+@fz4qSM*Y|Ci* zQP0Gf&fnCjb#+vacD-L;n=r}7V+?oIvd2kT58Bl_y}HR5?is(lW%F0-9fpMDT0bh^ z+qK1>oZRCa`)8B)dnxzNvua}88?~WPMmM{LV*4Mv*0y`;^TMz8y{UcHwwe1~Mgwb+ z`gCWLIX_2k_}1EW)cCLK`iL)1Z*a0skKu|2BYdLA?rRa+>x`H6-B+8F?QSI0|9U{G z;`+*9tINmJ7u`K>)h{=C(O?JZejNc#aXQ<9sly^&|eqK-V~ao=7Fo6{GP_AX3$mKl?tHSyMH|DLns*A4jU zYNP4a%Otz~+tl%}o%=rCW>ljsE}KuUOmQg;3U!(v*Qs&07Q<5gd-hrSy=-#h)mBHg za8Av0$*(0Ic+s#g*{k%z9=lQg>hXOyPg~Eam{^z+%&C<;!Y*USChLGVheJ4`1B;yM z4SLzD$qU1{=!&y`>mOci{>zgk0S=?CZ7yFqWW>!NPDTELPI)t)^^ESlWm-z3RX4_U z=OX&qEqZ&h ztX>x!W9zfpb?L+>^Djo8oH9q7EbM2qWQXgh)V$#X`n8*rVNvta8ps}TV&-fga!o_X`yw8<+AcYiBV`NP`Ktyjz_qm0`;<>j5e%0I3=DvVnD zX6g&4fapDb9x2BSFVeHN1rI)Pvaaf>&%JwI>&9mn4(S-@n}Tbkp>Q*+tE*9(F3*zixxjJfz<6-$wa#4rW^a)YfIxwpC@Dix<^; zcT004>v_3XV)=AMUUII(s13vuI=NvjK`+ zyH_`%3j1fQ?&FqyTvvb4*sTSw89k5ZwEk_;l@m7`pS!ZM$a`n`mJxOn+caJ$8EiZD z?hk*gn#Vmhuj`#xQ%8)^d+xpem-ygM`_J3|eYwG0MX6ifc&noH-kFcooG_nu`)h}d z?D$-mu4g7Wt!Snlao z-!tdko11dmeI3&l)Jxpq;#<#e{Ds@Cnx21{)p?-ndb71rHuBE{9ljYmuH4OTf!O_Y z?H(~N$11#1U&U~bT-h$jzxGRTFDcXF$@>xS`?RTezW%+q1!w;6OCD7B&8_14EWEt#`X9-V(L zx2f^ZE%H@MJ9S>vD|%|hZgb|gRo(go#VN=lN;`RzIVYU`J2b?m*0kT&R)HMzveVY z=lSSenyCHDrQe_IVS2yFJ|lNYy*0iIIz4!JOxbtdy;GduJ(u}*ez|B}_x7W@T&tfv z#J_v~?JY}AOntp^_A_IaWBF;?3ImoY(G$S*y_)xgAUI)xMot~1@95Na+fB0x0Try z4<0k*T&?_|fm=46Et}#MINA9eKjr6odsj_f@Xf&AuD^6IRy2>A9v?iSpyNB{-Jaj9 ztrjk+Se%(57Id?`i_Q}$ie-Sh*l4RI*GAGS0R%}ttSywNwi2L{6HD}J)3`_`l z={m4))(hXgd+g62nbCZ3hY5o-(m2y53$Ctwo85Hx+&e9o-R$Fcq;6E8Y2C(OM`+tu zd^6o|ai?90C&o$==U+SI@zdS}-Cr8#ksW(3l%afw6CS3udy?FMn`qy4&rGY)u`X_p z6j_h7T~jOCZry*kWUB20V`%T_*$cnnYMANUdoFLCv-m>o*1g8LItUkp_wqS1!FrS5 zG-cgDLt$I^sgn<@ONl$#tB^BSc!+Mnt8 z-Q%6@f8_!AW+tz#e;`+zl z>00QEetw)gxmm-k^mF%Hn2I+HSeWh>J*rpOuL0YeU5D3MH`w1QI5Q>Cse986H#z$& zI<)Dn`hip8FmuGXL>13>RSw7g>)oq7t?iz@Jh}h9k@u+G`;cGv*&VaqccJ)Jf9{^# z7}u{;=S}GCn0j&X_DvfE)^h%t-u9YTbLvku*j}yZ*v`q=Pkz1rlw`Y*$v)ZAc`kmg z1#j;j%#Ntz)3NwbtNdl9_MD;?4b~cMn|Y3kJwIcT&5dn-uhOP0Fnr4y?K>B5{wA$$|Bk(PFP!*bhD(c-ksg;^yWV-Xuz!bE zX(_5{wVn@pzx}=As-ih#ZVg-V`~tVd!?l9Jp@VM@obdC(Ll5fjx-!4$)UsFIM{o1Y zT^XGA=b>jo0i{#tYA@uDd*^<~JS6Yole&Ox1|5Fy!O6bMM>?My!jykjr!@<0Op-cx&8C-1M{nRAyjGVsD&=fa3LLk_QdBN()6;IQ0*U9Fqm z%<8bPwy{>CEcfAIp`>I?jG|wq&aN;gWj-y{YpJ_k& zbU1YW{jYTgZJo0^HnQQlYpLan|44c9^7O6?KQ~bQrgrPZuj|X}SMUDNd+GBJ%-QL* z^1xe#d85|-^6zcNY6Xkq8Z`0Qt7!DR%*SDC`MaZKu^vWs^N#b5|8#P}n`fGLYRyx#0)qgx&n>S!$_uT7loJqyZD6Y8~x3 z=wTm6le~fHuiAOG$7&Bc=+i4vxWxARRT*{b{rN1Q7k6I!nf=@{JY4LS2S~c2EMxK5 z$3wbp>NLt_;e-g+7jwOK<#$r9y5YX*^q}oaTi@BFJk#=|;e4l)t+)vV5ASu(l?+ag zv;}}~O$EJSD$eB_YXvNux_V%(B^4JAxT+s!b4u$*j`o=EWxe=u%$x@Uom6j|23(8V zGt=8q7=2Xo3zGzL4U7b`*)*z%{)h!760tz)75Hp@5qZK>rQk@ zuzg~>@L=TCg5GN$+0NVQcr$&^H$^kGHWl97@;xrr{x+-XW`C7;nSpM)cS=ztO=)U5!!w zCJlKzbxvgepE^}+DDciR+ng?VW_>}|vSnmNV|Oy?B^bxAVA8Au*%uc!NEKH%Fg)(am$62k)`Nvs%9kOC~25yjm=_bu2W8 ze#T)MxM-k2B+~r3nQI>zdiL&D?diYoYU_y3)4G zm{;ayilE87=FBozv6ZRWmHri(ft%ABhwRE+IO0+MK-=qSc(hknbc|;`^N)IpZS`jv zv)|sz+VwZzyJ&Oq@swtRt-HFXkM-hCZy#HG*hc=#6bIF-0qbA6U)eDxHPf#BAeFen zxqW#KqgCWhcZ?a3Id)t0!s(@v&b#029_6{K!6@hQ)JF39=U2|T|I?9y%i7#Gj+Y*4 zxqE(_!RK5e#|`baJSzC=j5Pt`EpA)piITM?<16F|t=4wz-B=N-ogLE1L9n^=0J|oP zZKQJ(L+)}X*F2`Ic3n}j&GC6nb29HvmKxp|ZDZ$0jI9;aYkxtI{SF7&%zMGj3Negp z`OJr_hSkoly}y-DTPQ(-;jFPYH+O!fg^&PW@i4t+4X0erCB{T9Za`c zH9vH4-K1KItb;uyv;Iu_Dt6S~v{#K@R6h z>A?D#&h6jy$y{RJ_tuSvJ!VIYKD_kdsiKs_PmGN&{kZeh?peu>KBHIN%(faI_;&bg zd7rkYoIAeUdZVKEky70RD7MH=ReQa0kY1;m9hft@y7NJhQ&WZUA z$5`<F*+MFXqUPZTC{#!?SOTn{uwyzQT2FRXEP~>bTv9JpXDG80o;x|NZru9&3l582iI$ zWyCjWdnSFixM}@tyS&L$%q~f0j`{SfoqVlx^n9B=-<{swXw7L6H=)7&j#slwY@`=| ziW~gUH=TWXT%Y%MXI2b-=bk6;Yur*xY8#w4eY3pX;QTRmQ#KFnV6(=$ zL()Xg1Up^U@uckWId(C!Roo-a=d`~Y*Ira^pXySSHt6X>Z)R-H;=;07t(>ebN2kuS z^zqyVXADoXDSP&7;LNo7<)h2z)G66Ht(SE? zcl=7Rq9F5@ouf79w92+9eSQC9Ys<6B;`mJ@o!`g#Ol;38zsdMzAbBe^!TU)TLYi6nB zf+kV!uvk9ah%KtyW^XSe6N3NZN9|aHS=9T zlAFwfj^<1c%Ed;iMPeyy&q)bevqJBYk|%+KZr%*@kjN}_zsc@LXL zce6ezQy%$s#eA>i`+HO|cSdUiJ2?g$@(hdHRy2(k*fwf)b@iE~UE+3K437t79r2oD z_jaeEB)0Th>#5&ahy8Ko$L}433WF{#-1JA}kHs?|4|?->MT_Deo>149@e1oll9Q67 zQ?IScquqqtrpGA>_3hf3eKM4lP=NQ|2_VH$^nT)Dp5)$ z5=rF$0)h4tl?LiThe;)o{FfuxOI2o*No6@`2<3l;gG6Q4P+yaV4i#Zy`Y%wBY6vvj zlLjFQFv7n^K}whdtVALZ%kUU`mY8c%CjMtdu!peFoyQ0SLUfWa21XWjj>Y7XkR9MZiV@wV=*|xl5b8v~OcsF= zWKoO|Y@h*5|A~jd-i+=%h6yFyX$T3J#~wO}LJBFA{4)hyjZ&lJ@d6n^D1?STCBq1q z2$q3SG>Cu(_-7WVRPvJ0F#MsnI2Z#kg2#GrKMwe_$0btif22SP-ibt^vhYA1UnnC6 zLWZE*fW8>Tpp%Jpdd)u~0Oo1pfIXkDTM!<|(l3(;;|Ku)|CrQ>5ktMqUuL0PB`paH z3)S&-fnWj4Jb_Te>Hs5?sf9A3S|(!{jY;!G7TQB?MWH-Cj!>B(ES!3(R7#NmECgVo zENTivq(o@Gi~!dpC-9-6LUdL@VL!UdV^9}rL}O$0teMgkBA28snV zk5n2HpP+s?j1qxa^#u`dRjLvmpO+CDDhd;ddB9hWNsJLRv7`$!%NT@~Om5PAt^+Ei zSp@9qB@^(1gknCd0DF`OFc@ZG9Ag9-0)~-52R>CoaIb{N^9T9tAVP5Uh;LB9xpVv*oOe^o5>pM}nT02wh5P<+Gzpf94X zfjSghY<_b~xnl}ZHBg@)xhS8m<1wOKp>Ca_{UOh0NDnj z9u#0YLpf_O5Htqzc!P!L3lelt0WrfP=79i}8YIUNY@lIagi#ttXod*0*8*Mu{K*z!Ex|hi;qir`tP%rzf<`^qHzCX*Xdy<(KQK_GdJC-zXH}069`FGgi@-UdI1JcZ zptC3teE1W30g0rVfnXma2Ie{)l$RzTO+lSV%p1%jod$3~mx<$K>{`MC2MQ4;l|_S~ zJz^Q?1!Q#OGYoLxGteP;o;XBceiafjiGW2x40|A{VxT<<8LP8MC={_O5GsTaLc<~; zeXu5$ki{SUBh?YJ8YGtRRh2e`t1_X5Pz>w=pOhCm0R0)y_Q%X%y9+Re1rG=jS5SMd zvRHAhsze9>2<`!9E#AUHfxM0!wCJ?~t(@G3cQcwH|=%h-3a+MM|K~KX-1VDm; z8i5jv0o26tv2K$PBo+c#kqRY(FlnU#Nqo2nZ3zQ((g6!6{VL(p8ccdb*waWvEa~8! zN)tfhBYYUldlEmS&-lZTS>UTm_$*uuz+#W4L<>&AA69^{ee6x5iVzS%`eEQgCH*R1 zU|6`N7e)}Em4K8Pj!C5eAwCOxWY7ZWoes7H%D^xd{8d=ML4g>;BP5A~gsl+kGi!pN zJ~SHPFNO+Y;tECKAc0p&zbaNF7BIX8LEj_}iN_0vKl+A4lS2g{#6t-<07VM3;LrVlKa@hJW5S?_qEHe=Wq%bg5(kn)M|KeS>u3Zq zKU}4vMGWdEU>+N3Vgd(Dc?=K=fdvLu^)G>1U=9evbmBmgf&eWs+eI3=rN4^U0=D80 z7z7H#p?y$g9t1>d2-X(d2ong!;G}@hgu%HD#u>&Z1t$16yo zmVgr9a8WqJ_XqGmbS7NTT?DgB{Y@&!QZI}m*Lc)A>cg-1<-?F;4Z}~ghe1!B-RCn>15&96ycu^ScHXE!dI2( z!!5X5WDDN$`B)7^;ePD;i&5Z}gDiM8VL}0q2@72SEM($J_$HNrR(CAV26nRqWzp#b zI-O7!Mg&M{5i)@qSX3PhG-jt*2R`!PVO8QUi!;#tC(UC2VFlLl@sFoRXY`h;G|M1E zARq`8V_66k33xK`;41!=L@<{mI#vO|Mlcg<1Y-^q1SCGG9wIb_hB4t}nHh#=DB}

    YbW0YHCP{WY1eG=O@8P94EoN+LoW4gxR>GpckLb`U;AXecor<~1-( zfcaUe|DfGK>nrAFl$e--5nzij2cauK9*4qJiy5Ub z1XvE^PHQ}Q3h?nOy>N|27LT4r=zgUk1S0H=1}<<32|B@#g@Z$mACfR{cIky`bsWfspJt@34mKPXho6{< z{^)Enn|M6h++Y$~T#fOS{ehWO9mRGvva1vMYYa321dy@2qS2UesLZ@ztZ-sb0oCA% zL{;mbqpBoRO;Gg$^6|0Dj6*N_19SlsE=6avMq}29!g)MQ0Q@5xOB)Opf3C?Si6{MI zNQCSc+O9x%!9_+#@L3GZBAGZCeFZQ+G=nSI4+Ch*RI|=~CTqor1G+G1B5hY-^XCw3 z`iEsmKm=lYkD;r?hyEI+3dRR+H5hL&lDnb`MGICHWipC{(Lb{YI6?EUKNRr7!Yh|A zkf711RWddHV87JphL8jH1E3+0CPFx{uY}LqZ_*3A0>>-a>BII{>f;3lFaQY1Bu2GC zZ-&JrHHJlzvcL&G*bkVSxDN?kZ>j}ft`gbxn~ zS_$Hz#o{ojvdV!c0jL-lAXpz@0UM~NXqSrISZp*Z;hW5$92CHx)L|vztE386d{}|Z z8i~qaltt;G#+ZOn2=oxqW)+N|nT?zQAF~NiX&tvLFkoL*e}u8sDm8RRCL`K)j7*O> z5mAf-szU_eqa+a1io98@AYo##@52TN8l0~LaJ>Q2HRxrMe6}+oK@le!3}d{7WXK}Y zBoo4WvuGdD;Al3XzW!op{nM<{5N5T*_*FeWf9-qI@e5d#qOqy1qN zaL`9EMq(OKzaKz{1#2x91^(5i=(7YU^W$YuUT7aIDTGO# z(HC!oJiDYry~!d<5M`|f&3?li1PAq4e4#>^ixlspWdn9wNu1ZCqkzFTNKdR%)(9R{ z4g_dQ{5QjDqdJZhFd|c8fHRFlhb4tJjxg~g0)qcJc-9D*;#F!Trmwubr0O#njE8X`H<(jEk0a(6exW}HfmMtQD;g&@U>bmhWRc_4;0A@T z1qLDcHVkC{CG;Uelg0#R%K#;Y4o4yC&RS%K$rK|9PSG#IpN-0V2|Q-8Nu!FFDvi)X zwl(Mwz?^|^q&ZldjPO#)8T@j0a6n~-yQj>QDWmiTy#R};krrdX22n6i5}o=Vv8OSC z0MrGR$ViKc8X^SgPzbe{c|xACP8NaN{{)_N0G>v?QWb}J0G)vdjd2D>%-R+3Uk2#t zuJ{M^aTyYT66C8SBssAx&OlNykS~LOMlpOz;Q!Cvi2@7&hg}N#aWKRNFdkxrBI(JO z{dD4dJQ|lBAYQG4H8jQ3~;|Y58 zn)fl>>NDW4f)L`fWbrhOuqZ%v^+pK@2k-tP@s>eo0Ia;~cxe>$0Ah@n!l0w;zw1sy zK)MZfLoK1Xj7h}Aqcabu$n7IHNju_Mp7W-1&DOe3BD@6 z(DENHafybS2gdp@x?@xt;lmIb@be!a{qtom#9%oz|2lK|$!J_Q0H^rm>L;g_K>iPZ z6mqO;LaYE%jx{di;k;%87H97d4a(Vb`w!<9dtBW?%iib6s~T8NIqsF`mhK!*)c{rI z+@|t=US)f#kDxghPa#%>H8omlZ)$kmS1wdX^^GXu6AI>cR71ie~ zz#8W)!0Ov9Mb+RfJgf$9Ij?E4h~jE=EC|&+Cl=<_7@y9yHO>jakIv;axI^teJ@@{k z!sOF)cXLhj3E@xAYm!6vKR&lN*CdZP{_(lZN8}R0HOc+_-0CCpNeT0atPjVh=bTUO zb3SGd+!F1FzU-Gz&*h)o|Lk1xasQ9~UNHQ>yzl)<`~SC{|F`sf)?WJwzy62wPv!C1 zdEUq4eIoBq_2KjLkM+&!GyOAtG``Iz`unLq+kdA2AJ2!+=g-IU$^Dc0_~|+3r=li8 zpPtJ#sU|^WP-_z4j`M2s%i(y_c@2c+bgr#N zfIZKvKBwC?5VF|gYJ@BcLNx*wdtQxzJKMh+0dLFs2Y{B-4;-jkkg5P!hOegZ!-`jl zVC8ThD5xB+3S$elbkTy5`-l4$7Ram531W3~TvxEBxw=6G$G!5TJ(`B#rN!$*ond{P zeDP4As1P?$SIBN68;o~WG*2hgT3x0st8g2gPTkn4<(W=l=&0TPF#j40wW*@iZ5^p z$eYj{X*R@cux&oaJjN~(n<$FWeW5+u907S`G_hAikO*zrD5@SbM}F49US&d!7*ZL8 zk4*NMqQ03R0F??-6k2}P9-Kf;7$pu6!vS{?0-!()8xH^ppEA`Roa9l4C6IccA^sUD z0Dw#aiZ(tY8N>5Yjux~MQJT!5Vz1@b5q0Gx72sqmV4^`eL!|gy4v~LR3lA6tdKeWU$T`=%CI6@h$d1VU-v` zQ^H4IUDZHja8)KTRfGkeqqIR~A_oNEKsbU5>QIeVgJOGg335A7H6&Gm|3ld>SpwOW~m@5$R z7Q|@;Kn!|aB?5a*3DWqe1Q79XP(GO5!(&V;hJvE9fuRUfReMB#keLI)$b0Dmb%-(3 zmLIW4q_!=^Pe2K2|0;x}W^e~-(hM}Gl(A4?X^x>0E};k*4mIi|ECc|387hNtfLdhI zFbO15iYv0|KA;Yzpa>yE#_ABzr!2gT7tHpc@&-hHG3zN56lY*Vaz+GJz(uw_*IXj3 zsy{+o9x}bqfU3MMNB~zMII+ZJk$}`3O9cm1uLXgDKa`ju0x>#;5E;h6@<>)mu*!^V z8k7wjC4JKk26KH;YRFCns2dT?MmQ@8mYbou82p?N=`P+m6j89|laGl;Bp596f?lBT zl9Wwj3It6M7yY4}>s%;lGpf%BZO98C#0G>fk&vSHV2=P1WfV#vpA0aS3a3G1Bo8TG zC16>Eq92w)P)^)IbCAs9uY8Mfn2IjIi4_2}lb}Kb z_=l1pu*foDVu>o;!ezWurdmoGDm9V15&#)HXOLoyV8=K4BK6G&`Y@1;Fq~mR<uz&}{%8oBL!D0|dno`2h z@IX`=FbJDr4kL34h|nJZf-r(D_?RPLUy$zs|3MgNz?`9EIXaa1VkU)!^GO}U1H)N- zfPYjlrW?Z2vq@@fxl#mGSYWY7X#y3#&}`uAf-U?3{sE3;&?hF zVIdVTg0HLOPn7Hltv+P*Fj)a35W2xuFCZPtmZrh#@d2e0e_32G!mB`t!s-Aa(jlqO z0x*%G6d}nT&WE;(SbU@=2_nh{%QVH>PO5_W59K0H=rx}dgvVeS>3D2$D9VzMxFFmO zvsu$b&4C2~z+*zeBA?;Yq!5WjDyqx3H>s5%7#8W0Wy%s6Sk@!h@lk*R27pD-U6^QU zZ&o7TW`vNj?&yFPqy~M3%v6*yLyj9|0(gTY*vO~72GLkCn_#527Cw<*0vmxW6C{A) zsbnHlVxrU{)<#6IGr=P090=Euazl%Clu<%80&9cu24}%Ce^n(?tW(IoT80KX2E1ef zwmFrtp{|iFv&1Tj@u8r444sKo2ZRL|05T&B&d}&c24Qjqf+9Fla!a-d|Er%Gl^V!! zXF};zsMx}7nLtm?O)wsyiJA+=a!YwORyGr^ArFBpwt9{kv_c#@DF#Om)VYwcL34g( zMLig*$^-xey^YAyAng^7f+JbwHYX0wC{zl`SEjOp9|km^ctcqd#wZ8cN(hck6$3yl zlB`U)ESvyV#;xTly;=qU@biqw>eHdIj1GLna1h9D@kDZSrBenz#p@$3MUg8dE3mYz zd^ef>k&6+-cB7QHsu~>;Zqxx7DAS;4Yf}|l7m`$*rbl7W5R}kMvwg-At ziHW5b^cl?wfG)67T4)bbA3W`uW0&bFWS`Ic&kJT1g23b@!J`e$+PJ`=Y zHP9i1;#J0Y5?Q8%#}( zvKVpYCZd?KR#AF9u!5;h)qxUBY8{zQcvn@zwNRj>lwT$Qz-cf<=`I;D;RQw(9c0U7 z;d)b*a4qd2GRlw14B!xqBa*F{5E2vyv&=N;HJ?6R0{jdrWOH#KlV)V+GPr_IBMSDU zp9~M3fR8Oj)(It@Mi@Ix7`P>BWRNiZf&J$>6sZ|$*LdiVUIKfa37bcq1Z3x_as`I! z$rvdt-`UQVuWYcaDhx;iRfPx%vSmn1zREJB<$GRb-;Z)8@*3ev08mu5 zajy~9teF$38PBa5`>h!lt{F3~nct`xYyK!MZT^57*j3|u&D_I3efR!=GT8fHes||o zAOD~EUV}#W8sGmF?b>R3|B0XSyy`YJWlHuqsgwAwt-3C+5!W|Y1*9!{UWEkBg(|=l>8=9IPQ1!-+;P1Mm^XdTv)rJs zl~h{hqh%mVz`W-CwRHAo+p`_2V(iqx(j4~`RZ}0|%PTKaoZAO4+^ddrb8+&;Lt$x% z;5NSDg+IE4xBrvR(_0Lx6c~KzfJtZhp!%|XrYC->ZV<(XlLL)VhVCI-V1W(!S*jmcMv4T-C zo!W?IW{NtnhrQ~pFTzmRF44k_;n`#42Mh>0-xr0BQmlRmsK6J2yCbgh&A8YfV>25X z8h!-}B;s$_lo>EYl_Rf2_b{HXEDV7K9H{3e_Y^zrO5ahc!BbwoGyr=ap*uLDI6^G| zFg$i;y1>CgluKcJ>^Ep%i6JZi>{YQsJf;cs!`aO%ymR4drve?Z43jj}JFgkxkHL;mSFbG}Qts%DdV%9yBmf#Ty#Pfh4Z8?A%d8gzN0s#ef z5wFGAB?tP4@`A%NP{|G%qdrcJwt|t^2y-a{m4T2E_KJ8!LPcJ77&hn_3Ndu{KAu$r zY#nbf0w8$2Rv-ZJ;1R+p*eTM}Ue`p;$hEQx!V`f{Sw+*gyTs7P)PShbdDEdK>`%zs!DJQ zSQM{d1psMavxD8NOpqa`{s@M$+|&hIo{@@0SM2_Pw3zKrJ1+xDghRu1=Lmp`jS>hD zfbnPh)Ak6oA?|{QtPnrZECVVy2@4lbRdO^X;iN7^QYa4`z=6v9KzgP~$g_+OPKCpd zh7TQxCq%$QbVpzkkqEkP!hRD2AT)?Qc{s}4!6SsD*&rdoHwgqNMr1enAUi`(?j``C z0mDP+Rb|F=2$wA3Td+YOK#))aeL~ocjYO!-V!aOg4~iWT8yL1W8KA(gP((7hW`q$a z%mt=kVv2RNy@W<0kbzhQV&U+xLrcT z!dzH(5E?VKEP8!7;9Gj5_8IJe5wvVbuwRiv2h^aj9e83fqE zp)e3zV*#RJ*vM(BEi`RkXtPFfsX*FD>Ir&f7z99&r$Mzegg|>P`~f<4%9Yp=611H` z5h=`8JnA3~Yysg%OAJAfiYa;rWkA6@R+~!XEgyh@Y?uLcn3)o>n(U4;64%i2u371VYjJ(n%aW2?iiqQ z3*ue%naB3yxL18@E$5D(eA+84*FXETT;|yPpZfeKJhT=BKE>NH&vN|(eN}W&8TAK8(c0FL~gxaY;BOavAA|U%f#P z8g4@nh2*esFjXDw@zWJN9;~m5mJ$56L8YT7M|KrX2xc*!aK&;Xu^2!u>z?t+H&Nj- zMv}9T?Mv|M5m?1AjuH+8Rwk^bIOK1UjPsR=Bj~pb@GB;8I@y6R46S*>Kq^|Gs5u4# z`?z@ES;U8jB&0B75G*?|f^oCQZzKreR-(OtHP>jb$8|1J3A8pd7+)Zub-*By0I*6a zU^5cF5h_zKJRB_P3dgKiNdR3IKssnoOT0iA%s%I=#N{xgfItA+leZYI3-nU~0ty?jN1*Fs*<)Joc{*}y zUkd|uSbQtnlf%UD{6T?7$@N@|h4ujUS7VqpBXyRls+kU+_?{jp+?>ZWSC7 zBCB6U$-YV^zGZ=BI*P ztY~2(TS<1*n?AK1jyruSfG>Sw7#qCNdS-=Bi+Sa6SbHt!aL^4b<#6)o)4TdpOXu#E zdNuk~(7EI1pLCgH&%Xcf`}_hN1%beIEq&I&E04}=;9W%zOP|?7FVRi(6Cd!;!WRXt zJ~jA-j&eFLr*d(8niW`_IPC8OdZ3RFURCQ1#~LSJJQNlNVR6AXyzobt@b>TG84!LA z*|Py|(}zGWcKZk4WCNyy39N{)A4knTe!xc`SAkQe4sLX(rg4LU}yB ziqh|5^72ru#V2D(miY>1mRy927d?z4yn1m7>?_Y7KT1Mo5Is~1dnG;6?T@UwTEGbA zL~@mkFY;>0X27qMNh4t-!+AR3!fqmw5m$#ZIx5bg44GI~BFDZDX;b=@1?(gRC33Qg zlnGZ-#w`^0ftO5(4#?|=%1WfP_dv@CRS66lqm;u60WsuBRk)8wjFi~V)0W?C=Ia9a zDti^ue|k0Yob(8!RDnFP+K_KT62c@D3+0hqRa{gs>*-^c5lDtp$>0H6#BL}<3I-`n z>c?VAy3vXRe%Rv|f%G~hY_w3!S{RiIPBvg<()N>Os7ft0!ndy6kD&BGWt2q)P+fW{pn_E|&i`;! zwWCjMW&b>kMPt&~1OszIPA~~}dk%-w1h1}mRq440eiQS{hk}%w6x;HFcYOWVdJZ3` ziU;@=y{deZJ&F_YdqM0Sm68uVW-YjVNoY7yZ8CZ$OO9w30t2){a8+TUd^QLH-NZBd zIw>k9#E^5GZ>R_&#NJmS#hT2+f{nF6DaRH$L#ha= zaR_hd^d{f1a6D^|B}yhmI$WaUVuey7@+B6JgkA}Za;OcKXXuog64a=lq6HTTO8SWy znrvL;xP{PGR&SJa-to#Dc1!0K(Go@oD2XII4&bF>*Y+8g%S9k$t#lLzCf#kN2J zsZ_nd`7a(-_vw@RP+uB@#-cH4Y?8ARULJT=$ytH#Up^END(*nI><8ZQ^tq6jskRM^M)OG|{RNM$TN!>^Z0WkSC=u~;d^uYM_Yj8Y1JMk5nK z4tOl{Z4jPT)H9mb5mL-^xC7w56pYlv6rvgd)&_9kE>!}Q0$q}Q(NjoeSaD?g8!96GY9nfYKWij7~&SaxV7*RJa1Pxoy{M^AH+${bbX2wTfxBL z138=nnmXmv>~QWe!*9%R4rftYz>ei`N^wb%&*3cS%Hcc<;c)tH;BXp8CY%`E52m>O z5Z{3T(kU-ay+5>I;e>m?ny0n>b;wsEzP@;%`&v`8rnW8zMxEZe-RedCQFDbZF+697 z&})Iiy52nE7pwBzG5TtwLc66WRf&UsI-?}Oude;)m??38W(JWqGTGaelQCf6rLE2*LXO87s$Ata${BkSaN)k>!pIqXf zQgYI;q+LP9QL}jBtI|!9biwWLcN^2+y?lCZQCc?Br$uqUUkb|K8^es~gvCHQzb^8~(4|H&f-Z6Pa5oZcQDL_2yfXe{J5Gyn+}H4^J0+d0CG_ zmloz&ko{g}qfn}5e%JU>%p`@pJf))aQTlti+{>z&_TX3J`*a@PvX%?}ca2r`&o6v` zJLS~#N9%Ln#-D0awz4!$bH#ATyY#-sxVp}k^9F-q-sVSn3rq>EmpwPE?_IGSyzMBn z;cWK%A+&L%b^lhqL&|>kes`$0TK-z;zCpY1k$uET+oN}m`)dykSaj;~H|gEoF1C68 zZcSo=DFNUx;d zly&B{>2Ou0&$Ui#Hry** zk^bHGKFr$tw~vq1$j`TlvdPKTFVZ^XuY1~K;=x?~h}J;|n?Ihvd+o>}-i_Z|xh6K2 z4x5?Cle?=A73j zj~&09d%S3Di&nq(iEH2}?RJB6TrsMr;AL8)!j3l4xzXO5-SwVzcd^b(*1E6e;CH({ ztbWoi_$9dUpgePzmOcvO&w78C_zQW@?xiv#Q?oN6%o*XzSry-nrG7saKmWRRykBBW!mKIfrzY@1Q`25|@}G9FH01Ht`b%eej61EWJIa2?P?=_x zRqncVb;c%jD*mxW%A)dGfl)S3-dNZF`Qq(`F#}r3dOi}Zp1OZhZdQB$vt9q__MEdc zeVH!d&g|4#i_s^b15foX88TA#;QZJvuhu?o z_FeN^D>xCkrEhb8TU*PVWo%k#-ct7UkXI$c9FnZZomFvrXD&84j#~O*gGw z55V5CU{JTF!o|<#~;nM3Xp3Bd^ zNKbFofE&F&)?;DoZnAT|PQ8phV7JEFeAFn=FG%z5=v>C9vg|^kJXbX-cOCF>&*rk!>z#(QtbKpQoF&Y6 zg(|cAv!Bdfqg_1{e_kCwXv&%nH=WLhWcGgK^)Ptj4u8kiF%La<3{#%5c^;GF<6^oX zv(G-}YBlw$;Lmm!4h=t5wlVF+vazv^xA{(;q9|WCr?mL)#rE~Cwpq6J{Q|eHCq^bp z5)0mr^U$cQuMX?}bxVgS#-KK#&+-`_%4Jymr0e<-^4 zc&7LN|JlcesoWh=Y`G*V4L43j!-B{Zo8LFB;SA+NLbd&_k0U@vV+E{~dRy#4A5 zj#Rd2!!}?*ng=Ge<3o-#2D_Os@LZ;7W5zOy|8V|)HU#F6cv?w_sSGaTr$+7-P}TYKpOq19$N*qx?m_-?rH2O@p7g&!C>I^VGTu3=5zks z)6=MS>wnkvlZe4wDSBu>B zvDf01PN&?bY}v>_K?xuKL@N_Y3Xi;O>#;t(NhI+c@X;G0=l=B3tvz~A?KnL`*m0N8`L6RC#~ zzIS8(`~5jV*Xo|`$ODU~iBH|Yk#YM9`)rIGE8d3dI$|)zo3QOunSdobZ?A)tM2z}& zKA|m_xnm)H$SDcUYCNb=s8giQEr+(|SD4hw?S4=$YYiQ3)S(h-y=#|hp+;s$QLlQp zJN}s7v*U}5Fe{SIc9X46Q6IjA22uQY zrq2?%G7~CnJ&n_Oa#+KUVZd1D5vDGa#BZY;?=t&* zjxgT09$8tL7XQiJrMP+H!6G-7H|M)WS0ZY~AKL~=R~6X%fMPyWc=D#8a4ok!qYIz>-v7ex<%kk%;f!tr3UZJT-2KZ5Vu z`OutW%Ix^SC}ifMl46%|dHHC_ID~UjKZPV5!ME+{`DFiG^VpLeWM3VI%$tx;o=EQE zF|N&%Xf`3;;f#=Dy+ydo8C&epwt~1Veb0Tb_OXjF&2X@>B zJnKxyT8-EfTgN;mebWGC8Uo#Pdd;IOD-rO|uL14>@CLo0nZ00pKeDw~7P#%wo%~CM z^y5~}Z>V|(^2_||K?R140o|qd@%DHmhutFMwc%!*GVyfF;?S2-oHlEL6LC{` z0w5`geIC=-*EQW_wKUMmgvrY}=pc9Kh7vHhmjK;9AzurD6RsbG6-k|MNcNK&KBfWS z%C(gcpwHGVXx}!F{+3y3Frcz}gL4|lzrOIONLWuHp>cv1`F8=l&6Zc&|0On;@6x zCLI$`?MR<-#y>GivD?peq0xm|wA??E)*n_@XR3d)|JCzlY!&_GFt&u!b->+{^2G9uz%hGN73Cql!F^AX3KgldaUpJh;G!qfo;)Ik~Ml z!F-- z^pd#zU8vsgOyw|_dU97lndpoz{YnbOD8-m=^*lh?RA+c-;sSU|F?5|S%T4S?UbqAK zRer$T05jY=sB~OL6wZ*$B#CyRhq<<}EGOD(D(CauGhwz-=X>4>D5yONin}$-_pE&Lg(whi0uOyaoG+RW9m$@I>L95 zvEIk$I+24r+)id0FkJqcDx5=scp0u7@2#F`j)(^+KVa5KXNj$Cm1YsAQF(-lGD`|Lx#HHi37~hFuxe>NXdNfm)axqlbjhM%{5*I0&u)?Y(LGkKk=h$JxMkTcg#A z)c{Wi2=(lOiRI?*P5rw{To-iy&c-rt(><#ZGxVIv!Uw2-w)__)oyyu3sDwgg4UW7` z$fXdVG-XCiMvRiS8$<3fU@hLq$lsk6mzz`cck1uzhfz+_9s~H9rMQZ=-nl(Qe9hl+ zx%A;2Qon<5N;cT3icBkY<{I(!?_Oi{|EMdCYjNgYTbkEQntd*Ih3P>)cs=$>nc7Ts z*jBH)xi1?PYOhdGhxbm=s`mV0xqFe$m1Xy#`n-zwuR7#IG8D zjwvPNa<3cczm^%2EF&=Pj&sL)L$1+KhQzOHue_TsgRkXs5_eo7%;y^sZgr-_60<8^ zls|yb=wS9>heE>*u2yXebbNg;eGc=eHJo=oKObpF{lba}#e7|DNuoM)Ex+11Z#VBH z+U223rW5q<>D@oH{QYx@aWh7bMKTvP&zW$8e(mVnyC2^0X>V-pO+9J|;nEyd$LLf? zEFkhjI266EJgYxYXI@8i z6$8fkjnRu7Cd9SCK<5|D>G7K7bC>*(_x;)|G7OPD!cUGVm2fV{murGeLyT#YDG?u_f9R6L;iQOWaY82{gX z632iYMAz3tD**0?R3^htqY-e zkW&9z`1`$Juxt7Kt*2(#N~xo}96>L0`nHSmIY%(5AeA5||j}mX_+!q=U=; zjN!eg_ps1_k9AGBJb|w1aAWW-f$xAx7vCM6U7MW`qL7SAbM7*$46mohyrnpwtLS`Q%B~Q;MkDvw?{=KyOp5j?FgP16H!b|~zI`bk$ z+{Y6Z+M#sukG2Z_tCNGq*WSA@P)9(V6few~SuW$y)8g*$wiZR53Dm#(Mk^M zD5i%^`4^KbRNZZ}Umnm@<>LYGSzEX6lbYTdmClMSJILi(SbKVGpc;4N{>Ap=vByYm?dRUsLTN&qBX z8`4SOt0`mS_d1??!0_onRFsY>a4iMKAg_0VY)vJ+9Kg7htWj%$-uVTd#&*jj;e{|j zmkdr)|Et<5omoJfp+GE_t#C8H~ykfr(yNE*(nbVlsgQ{ zDYS9G%aqIbK-Tw#4W8`1Vxdoxu}+eJT~vi;Gmlxb_)N2>OSAzQ>J%hoR8VThLr0=s ztG4DrmFJ2`{kS(G4J+}6pUx*4_P)y8a(xJG#pllzOt6dc4`m>|({sK^IFdLq@q$2l zMw)}d4_PkVX_dmQ)Lm&cT4lbg`;Rn0rI2-{+NTN#`nev$c%ctwin;ARxAUvtPXNqEW z4L!NE=Wp%4JV?l6%-M`q&587P91!QS@p2!*vZ5__v$zGN13+w=evQ527UH`_(Bv&h zNH3DO4q=EEAb8vEo#P z@wX^(ROp_(9%-QE5=S-p$&1=2JWz8#KIZ#PnnB$qn!%@+{Q!L|1{gLI;6HUqWz|+VqEY**?Dwf)D75Sf~KB z{@Q@sPudxxE;*mu`)!L zYRy#$dFe#Zyu&?=x^-W6;e()XG1OoxWaGNQ>fCdD%28cWb?=m$IDIM5`%E-mTU}7Z zVUW4mU8)vpz}zu$4d@C>a($_Axb0^yaQF5Dfy3j>$QnJ+AF%r4kn5xZJ6lwUbDnv- zf_u51*;)FKYxvWp6tgC!2i3t3H@yDiQ)-F9hZZArm8^3fk%!H*fce7wU`U9b5|`ij z=B#nkCBnjw9kFe|y9f%)8YB2Nyt2uBuh&pKQdO9s`#36>V=(u6BcC53$2fAzaV^n} zw*TKlyJlyeTLl`in}qqAyzZb@A+B4f}Sqlk`kO*E5jc z*8+!|0{hKW}OP@(?|CwoT+SIWAki90ko%Nz`LYhzHl}czO2hdI5`mYwZ>qvAp;^ z7PfQ%gE_M^2AcDEs@kBm5(tAfQ*z~E+aP7y5Pu2si@Yt_j#PA%BwdX%|3)6uvZ1`> ze0?iy|AK)ZENiSa^LhpKOZGIzo^YabADrk%IE!t;S_+HKsm7SP> z*tJFghLD3Ol@Y|;O$vYG;5~^_pQ!tpAJ+arvAGo`={tYsIp#R7)cqCgzGaQT8h0Qd z4x9jAQ(Gw)BW$kRRmJ+#pc}aRE@?9l^-jvtnu4`j@Q_b5!d?`4D7)sIdnOOC_5QxV zBFmNfLJh?+#RH{NH8tp?@a=R+3iFojS>z)WV8WIlW!^MT!Y9p7J^GIFTNw6gt1mDh z+6AoC*^4D|&QW$OvUQYilXGlP>%-~Dw-z5Pf=hK%Mi1l)AqC2%(8lBJ70$SAHrgLF zO3_OR(rnmA(3~Hf+jCMfV6wi^9_%*y;R0=sFOXx4VF)jyLIs3nba1{AdOCA1L)nxU z0AkHf-p{^0K+Wj$&^hKkL!OBDP_kd-22J4M+`UZkleI)c5TV&-;=VWN4S7E!*vQoU z+|}zwr2^IfB$BtJEfD34*POtejWyPI=dD228gHaid@o?-t>A3dj#+o@AWc&<;Gkoc z+_5y-;#V1(A*TpZsdwh86*QXac_7vt=cI8h1IRkDbHkB$0(AOW-%EEu+}*YNJjQH$ zc0uH?l)hJ}N3ws-AN!XqY=l2U1_la&?4ZrHMIe}+CaZz5kE8x&jSQiz)_kDkBKIQ3$8SIbL`X5H?t0yje7hs@@{M!NNJ1V zyFg#vS9LypA+^nXa_>${aQ>t&{_FPox}fFuO)7}{U&GHO)fe5!4!IEhQe|SzAObf> z_i|W1f@;-;pyj#w?g?*eLch(t)+PFYskuU%VZ0yQwGjon)K|l~Ud85Oa$M1}6FKMFCUS!+rQi2lUYk}nX8Itwvd6k9fFD66HE=MP z;E5va9nz_C<4oP^QD_!C5d6PZRx-rg*(T3WPU&w2OBQRug~2<`b2#mM6mvA+E>~P2 zea!K5ph1uebmT5IHt7c$1+ET=tl1bvZjffFF!fZP)GGegrSA1uooueaO|H;CNzK51!Sc=#L~8a?II| z?EfMOcdNbsQ!tXq%k9tjk3?!caDh8m7QY2sj7QTG*ZClKrv$|zbGh7oQMH@eNxuk_Na|vObL)UPEDf*G!KvRy)91y&X@u#hmIIVE@Q=BDd zxKD+9o>zy?*K3aFn)AE~6Hj)ka3gLCtfLK-(g{%r0O~`;MbhLK*f9%#uDchoOv!)vgl=b{UwvmLe%4_>7;F+D7p=azE8s_@#%VPskMp zPF;_@>Wb}EZCSbu@3nc%QjX4V7G7Xo@;DV!O423Tkg?a52Mn35;@_uDii|)tfyURW z$oA{!$wLAdMF|DLw3Ap`O3q9XSs#kZ6nj^J;SWt`Z9e?z({DMrH)NP(MnWmVvY-T$ ztbV*Phn!7Sc6_q51e-Gg!bDe|u|^AV`O|T=ST9JlXteRi1?9QF7}l{QEVM`EYQVQG z+h49tm`tWP(Maz|vuG zggO5+Nbbs9_5;M6dL3ltDW#P-h6lu}(~6B_3JJ$?t##iIU6aCLzhWiv~5W z#t{@LvGE}B6wGW_sr_!{=!UF%hx-UL*_i5H`glvX36(FMZX^}-%^TxLMIHq5ptW)| z*;8r+LBJL2jJ`>m*dM^}TsvAUwh;QkPTdEP*+NBH=Qh14XxgNOS9>EL(AHXffHj8A zl{B{as=TK}kh?nUP~@r&k}kmpT`3h^?04Boj!-zh8*9hhYN>1-FtA^0@p4!{J@xKA z)Piy>H6|W0d!`azoX&dAFLL}5eEDB1B;4=|vDY}nk{~t-BP2tH#1NhZed;VPvpYG) z$wwbA6J9LN?!in8GCOJi0EP-Ug1L-!C=i0pYMWy2Kyt+Eo)b9;*R#Je*Y%ZrI5MgP z?P033xSoviq(X1INHgPeZ{J?fe;|SUA&etWJo-sh>H**!y5zqQ`;x)1@0?>*Iy4v! z)I!Tfx?j2Wx<}ngeazVYGe45|IpEZz{fXh&i&XE@;c5R-)|rQ&RnC=x1FEM^(wZFr z(oeC1T9#xJX~PDqY;&IT&aTB}mqZxx=?BFsf;`y`5P3xwu=FDt-IJs3DAnT*!jj~ zQRFe_UMXIO!|x3EoKu{mLe_}Eho-a-r_U#>@5yVH?eILHfrfGfy@+BS=m=Pn@>P4e zGCvJtCsXI!FPO1go?f^+Z8$*Mg3*gbe~E4zfxas&ABGR)Jee-$Uu`poM3j@K=5sb! zlc+O5(HGWd#dwm%(gwB?Jf-iI;7Mr1c%&Q^#rC7%j2iFwZZDBJqhp-fyd9ZYE;zvP z1`s)encYb#fy$i^FvEk(h-@@7nha^{u6?)xo^1$ybJ-q|SiD%mwBB}zbnha>K2M2# zlpQx~zmKmXcrpA&cdAYyOD=7?5@HLEpK9546^ef%SQEcvZn)e+mL<7!jHX}ztV+p` zc#$o%2=D3VSCer#DOGjINu2GX13~)?#x-u+4syqo&|F|-^jWg7 za>sQTmM=0|rw^`Nd_;*H>twwWZ$A|O&u=jm>N8@|_Z{wZ8d5%7{db)gP>65vofW>_ z5_`U%v^kligU{zbTckJfBGRcR79@I>F^RmLY`NL995mEv!u6N29Nn=|q|uR_MD9%5 zWmjRZM0I{6cZWD>ALL?oF5yR|!q8KP2&oiu;?|;pKK9KYPXpw*Zt_73xlpvG#07YU zcv$1xKj`9~vJ{kW`RNsm?(N$$B^`%O>CCkP&T{U+)1}Rk6aqpStr6%CGNhKjoe`~f z_^m5^9uP7+N{?{J0&jK|So&6ppeQsHUztF)Q*zhi%rGe0<;OWc2w#5}y|R)p14VHy zix4cP_Wvbh(yje(=0YejH1QG@*P*%^4;RS^lK%8^zJvOb9HA>*Nw`SGCbXW7zxGbT zLIKYac}BikMe0jsoZoNvK@UQ5L0?F^Yv~hM%pt-jtX%H>pOJ0K?YBQ8+Dp`kr_U>z z6+GNhCV0^3aUu?t@xQ^#|3lj60>?ZMgj-Tk&d+eU|}oWw-d0lrq;@q({uBZpGTg? zOZRMvH72Z@n`@Q6D9C7?4fL0iNUSnz73;#ic@oL&-oGl4Yl7?x@M7 zkjHz>S-2UCtWVpJz1{t1qJ4c0>DT6Cy*nmYM7C6iX`enJTSHblYH(q>{M#IvTD9}c@aZkxKYG$p7oy>k;G5U$?EOk!Yx)H2=(unAdo8frRBIE$G z7v|Fa%GWg619klxPuDQ&W@-c|ftU>i;OPrO@co{Wmi-)hYnv25@QqbYs5SinYk*_G zwcW;4P{+Vbgw3<4Co_~riZlPj72IL?P!Vcfv@+lP^KYF@}!R^|F_m5MS42jQo+w?Ih3;Sf(58+?fHLaA>v(W z-K~|YjmvT`T_hCg0*+ULNg<^=KWYds%@kj_$(L>FHzc;MLvF`NUsF4-zHE!2l>nb* z*b|Nt10xS8BnAj-J|>}?#c+Xz_=V5|IKPg$$$cz4l=ZRtR$LgvOMPM_e}Cy%caq0_ zW0y*di*#6Xn2r8!+b)!u=t;TAN%_*sTmQSutEWG)wxr~1)h1rp7f9WoN{z1}t~=jbjzwWE1_>aRm-P=B;0 z)|+-<7a9_{8je0HMvAx5>zR6lT=9%3<~QZxj8MXXK_y-H_1k^NYG2z zW4)FCYAUz@p0JiWKO zemA6CfFNQxq|V3{fNk)(oCk zR7J9zQ!=sBC+_-j8<@p z7vi~BOd`5Ye#F+u&~i$EGtr?Fe@R{mX`RpaO8)S^Z8Lz}^8+Aw@|iBEwf>-GlpC5u zI**6$pT%_Jw+wzT_li!(1;0o65-m&6hgpxFZ_9Gsc1Flz>9XUw%7dMYYXXT{`dP|n zr6o`*DduVre)8f}2Wy;2N+#fEl=P11F-E9P+F1lvK5#YvJ|JpIojgMPgB@VHzYo$n z_TSv$G*wvEO!fj+R`e2NAH(L$ZcXa`^!qh(jhT3kDR#R&Vc@WumIgf_Ualc{nirIe ztGP+7926HH6(6vU6-!Ls;>bePd!Jzhc?sdyqKbXFK@Li+f!g?IF|;+3D`i1*-v<(N ziEi|+9}t7#i#dEZFcqXcT#5-pr+kpQ1)`qe7jQQNRDrgg4j;~#WdYFe2``X+&P9`u zyfJwSB1%n7n)ZTZ>3V>+`VDy#HQQv1}qi9qq*41P$EvUvF zttSTn7un;$&UatJfneY}VbB_^r=4=lMLZSUm8GS+0*AD=IiIaW16|DI<@t1LXYm&R z4<>s-{2Dvol)4L=gWB7m0;9z`Kl-A-*)gXfa@tntz+IbhXhIM}^Jz;usqeRFnGV~QtHKvqWlE1iJ;$@vaATtQhx7I(W zjCLN^1J^gwXW$p;FFPV|^ev;z(gQ>bna8fDWHunmGjQC4uh)kpJd&7ZF((5ecL%`G z?gY6Hu?U)AN=8MG`&z(BkBa9N2=Fhzv3eKLL2zBVMxNM+Q8z6Sz6{smDuZC_b4B$v zRYT(8jm0=-tTjF*h<33z#t`yjx1ROPC(U4Hya^>#21gPe*pAC2dYHK?yILaC%JHV| z5Iw+15}AoVA_ruZ-z6cvqhoq|KScy4#R&iXg1O1>S$(PP_rJbE!q{GvzoU#`yh?$g zc&RXj4atEb0ab~Kz|kqc5{%xHrv=A(q9Z}QuE!r;l$ zA47lwueE?HeZMz@tTWfc-7?pQ2q<`2io+DCBUcDE8SAGuBb2%6&+rKe$qScR4wq!> zPf)__y5f;~gcY|w#r7h(IalOYr=c3CpA_4X#92xME>z(z!hiTePK!KB_q#3aq-OC# zpL51v9oRF=ANV#MwGiUKPfA|Mr(AQt{^NG>eWYonlB-Rr(p3~72Pl8|)&#y3zYdXm zUMq==?f>~-$=0H+R5YCHdlLEAkC(H-AZn2pw)Fc!YpXVP&0d!=ER48A0FTSclHck#F$w z!#Ob(ZN{);-czCjOtKjza@dY4)iOZ3oTAm&U_1wLFxf(}dfylA!#^m^X?KOcSe1e% zGT|XIrQ71Eny+0&Cf}C0!lE8#GAv%2x|j^ilBQ%JK*WE0F3>D#mxv3Npcm;2c^!urseE! z-a5boH)-vQdzNht@Lsc-GomXWM7r^kh{P^R_L6tsj@Wj3PI6>SjIOxp)tw5^NzD~J zETT0Qr7_@)xO5yMeDflecqiFPsp(=giG+qP5*_5a5cu^3TYBy9J$Tc!;7b zE-|kNF)-8G;VM6?6f&flaujN-MZN`vCw74MTYI1_F1S8?9aT40Y+IFMJ@aga4aDx6k`k>fq8{aKH zTc6r*725m#-PCDLaPwx4qjOBX?;ug{pIknC$sHPr;(iH!qboZIQAPLePM;c%v%xGNSNx_$QDeYCYm;6W&4U7moKHOQy$NWlPdVA&lBc7*M zB%F0hEZQ2^{LUo2%w_4|-NlhX3RoxQN}1inq^j?-p1(a7x-`XexaQ)kdX9#nEeG)?L<{bL{y|F|Z48bYbPGr8RJ;e6@yxj{Aa(<>DK@th zRj-HYm+JmwhpS9~zbWsG?Ug-z=}_@vysmO}IW4{t8D`vw0PnOfzxNIU7Lr1tki#wRUGLF=y$j!jYqR|cck2K&i+*-k(C2j?d0 znP=Asz+Cg@zx(_lu0R&8IBxs~4wj`xNEdYOcy}r4Adu3swHRt_LUWNO@u?w$hF0N> z`30dCdyyhPS3HKgxk=w4Xu3-E8=d}8ia41Fv_X048)2f~A`782gY^K-4gecGzTN*f zTh3I?6ox!p-9+st%@4*e6Y+g{R<@U12DyVx9JM}Ql9S;Cd^FWA()Z+u^Rm}2z4+Mv zIlXNyook0qW4&qmm@J|Oj64R^S{(Y?Mb~j5d z_#G@s{bk;^he*<|a9g2M8@i7-;<`Q|MTb|WZGo6ul~}wL&K6FvhW0K)j>!OrdKC_F zPXkqIghYcUmt>=zH;v;Yn1DG+cjKQ3!O4hDRN(x<)Y)yd@v?f#!dz%1`IQXqJXsm9 zx*bu1DNaUXB81m=;G*=}qta?}ByWw!|2Wt<0|V|D?7kGFMtgi$0)d0>+)iNxh*(XV zo_D=nz^16K|EYg_vLgc8dleJIQ<{sXcN(1IB`)6BlOjubtNK(9Cq$d4m(5WnGNN+X!zAxJ{5Fl4#8N3Yk-r9WGwP*{UYKwaLEnqg(pae;h!lyK) zv_+2n4E>b9(`+qKW!u!9NH%iS>C`6Hf*LWCsOF+xSMl!G zn01c1F+S^4ug}3YNqoYVVIXUpKe?#)0ur?fcH*mlJ$Nx3Me`b zs2jo7{yQd(9GMizOQ&2y5>B7+4rpNksGRMTXY^y`JsqKda~f7+EXojTg1d>y77wc2 zlglJ7;9O2bJI0p)r4r&uv<`OSSCgV{QM$klRCZkPPzJb?<8QDoz*~!}4^0QA!l?Ve zM^r-&o*PF>;$2?Zvu%Jis~t+f*>`wJEYK=%zz?(Y&b(ZK^DQ+;PD#>KU^${*&UvjM-q=|GRj3a-vvP{*bSRt2{{3$Gd3aP}`&LSL{;?mlsSu zz_Qph9#?u(<5KRCkda&XaOFS*)nz12O%KYR9DJ zH5Z4W{b2>l)rtop-(G=b;S$j~zIQop`6PZpwDl2@V-jcm9(~rmPOkP7Jty$26!bX@ zaq`aB7Qvp{W*^5HQMhr!3*&u2gNq!k8Z9i;yDG~Ve=W7GihM-506Vq}`M|lS4Zx8G zi%-qB8(%9hu23lNo}g}Sx6Bsn>zp&=Hm|g1U#LFZO0g;vRv&&Zg_{W2lbAmD_C0ll z-WipOaTh5;z6r}L0J9oBh5#}#4w;9Q0zG_IJcoagZ30r?aBJlnXGx5&qY2KVJ>nMG zz+!&F*HcPs=CeAj%ty4z<@f50DA8btfm-RAFLD{s==#&d5ooR)4WYqa|1)Hu^C$i0 zq-N^>Co~qnqV$GQdJEpe6Aoih^-1|P==|wn2VpEHUl!{}CpY0`aP;j3R?=ATUHU#6 z-Jn0Vh9F5Cd@hCJ-SHQCIcuT|TYGk~w06#pm@i)Lg(vnZT$RgmVmu|p?2@}V0NHup9k^BpTy-^N(buLrM_4_S z6EmU##@^rJ>aI}F64u~Nmu!63ccyvs&B?3Ly~^y@5+7x7A`t!vHG$i|={iFBLtv@3 zyM_?18ftC2=dRf<$&+#r@#2C)JS_g(W}Nrb$kLbQrrJw}jeiAAadt4|W@7m*Ygicm ziTH^qqiH%Ye>zwJY|waMQR)Ff0ycN(mMBIt9b#83gOnjOcx`m(Vlx^SAm2JkX4EH~ z+2^7&_ITB0lP~>N3!#1(5D&v$|K+w#mFC8HIyfbekEm~2Z~aG3S~p$`kQmH$OuN4| zGCE~C-A*)`_a&g##80Ad{atq*7Q+Su#e}I=yn*n&GN!>`jx%t#Jw8vb)=nMkywO8n zeAUB>v2PDP2+i|JB9%%aLhDJG5;6!RzSTNbXYFu!E^va-DSb}kUA=JX+GRU5=my;8 zK6*~&M@&-BLeifnxNlcHnP^H9_XScb!60iBNu=toB}1K2{D~~&zkO*HBf7@6R$VHV zY52DLn+EZ_3~ggt^h=)`H-W=!v|Vp8(f{HuJIm9eN%-%fcuW=21{?EeC8m1O;7ARq z+^NRaSZ-N=OgP7^K(*UwOBh%Mw46_il|S(GZ<%~>AMh9AE%cll8Wue`tvzf+c$m`m zg|$ejFN!OfBhQe3w@AFQUJG&4t1ZoDe&k<{NU#o7x9F2V%f?vy`|wt zTRh3Oc2o5~Ideo7IYu<+#09~kjX|tx_B8N9$W%xNkuX=VdhqtG0ZBf}_aVmorgzrx zsPNxP?co{*rklUcl@(YHV^o%1DyaR8Vn5(*9r-pV=#M!|NX*ElR8Ik6+}s&AkOLJv z0ojW?cxkfl27(!^&P%WHAnD74ffX|0maXH(;e)058T>e@ByyC^r4{3Uza=?vm{U)f z`WiKWGqlttW*-dw*ijx@tB1{`xk6$YWJYCnD3ojIY4=?*@G|>WDQnWIdo#cA&TL`) zkRmZ#aufn=>%gdi(gA)1N_?^tTcaBt0*>xr2ylu3gH*}+r<48_ql>Qv9OoQlk01X* zY*i#8*V^oyTXhL~X-Y@#cnygjb)WsCaZmQ;?ya89N8CVfY>Nq*%Z$Fnp$S1=rBlE} zMSPO`%(%e;^C|lDge10d7ILktl7cauI;`@EFu^(7zdcYKf&A|7HHE(u+J#yIHtHVj*Q6rNwF|7^0}JnI5v&@mpM#;SQ^ z=;BI-;!&$plH+#-J;bL-^2=7h{$f(z!;N&4Z1io|?f>q%$PtQ21r}K6{c|fDSG$QB`79b5T!DH$W9~((6sboFm=?1_`<<6Y| zVt%)23M0OGGYqVIy2QOR>q!J-c&zzWY!0e8c~AThNG(hpnH@VRGUC7z^EpzAW$3Si zF)d)*mcT@*ePA5W*j5pwuhdzKPiV(<7_*oxt2KHJLFu zr{o9)AEWIF3YCz6PhKgK$ucBRht<{rt|=`_4c%A2k5K;vH9Rmzl-NLfntaGbUrhHghQcLHx~pdK~nK4Q0cjev|QR#bH{l5B|fDaILp- z=bd`h(sjU0!d@IW`C=cTcWyC!Dfqy6`&?fNZ6#1ARd)A~$2S>4>(gF$c0id) z8AYB-d*5UA59I^jqhrCk$v!T9(d?TQUFpMSvRYpRkvf~K3~?`22B>*Pw5cwc4@Gry zXx+X}DaL;`u&gx-=+Lne*C-C$W%rCiH0FhVLww)%U0_bXe*H`VnNc|r>>=??+4}pG zB^U_P?r+*{U8$OS0My#_3BJ5Ra`eMuX)GP;U;;$+UeL{2SxeSMok)OD2ZF5-r7hk% zot-EdHdHjaKGe;X-=M^;>}IB;?PazyOq-L7!RkE1j!nohUDHEe3TR>bK0rcF+b7*EWVogj>{&+BM zonvdeq^VrZlwBM3vS~j1NN`Gl2{n6~ytTPQB!gObSM!-%PL^0f=|y2485w{r|_XhOa~>JN=6sZILIs1)^X!UKWYhORPU=PYgfB*P1qj&^Y4xoS8w;cNY?&_w%= z%M;cfXiVAO9ANI{91eAcFu(6#=03nh%4WB0>Urg8Q$;z#zO>AQZgNpU;X%hheY~Xq zbYd5NjJ=a){oWd@Y1u+kJz&{&$6GE$aNPiJ%4SR4M6wf(hS8Vg&n!nDvohA!0>XZxC}h3q7pFbJ4<~ErjmIP0g;uV!AIn!ftuv z!!!B)8Fx`zP2YKc5pn9<`df?ysdU;H znr@&>i7FPG&i3U{yn4i!%hSPA^h?LSrs1jrF`k!BKP)zv;Xf>{U*`&}I2m6EKFeCm zrcJbN&WSQiFd5k4tLUn&7NQE*f(IEe2Ot(VZ9qlc*YY z3TQ`c9Y2)Lm~!p*-7HRNA*u8Q&D@PQg|#=fH|4lQFXeME#)qDIZ>|PTQ*WuEh@A<> zntNC;HA4UGyqCo=)l$*M;=%SsCA*z+k)?Z;EzJFYpf-9|T_wwmE0bxi;KDqvAl76# z?ZHCL6Rr$PhLbqGT)d-l+YdAcGB`1;E0YzE(LUC zL=g)MROCg^`PX1mFYe+&rrIII+AWS0$AoP^)AkGIcaMZ5&*Gqy_u@h!Z@(ft*N;4a z(IjZ`4H2qB{u8e>(#O@W9B#x#q>Cr4Kg1CEkyG5_7aa@~E_&Q&y0HiPIP@q(S5;cj zN9FEqdx2Z3!lhA%q`GR-D46dgX7tBTF~tIR3(z}<1rS6y{RO51u^gxG4rVYuQyrRE z8bv&{hjI0A=V4JIFi^f$Ja58E9=6)(p;dpuiMI94V5Ha|gu1$Lan!%BGupZqkB5hm zA9G5Nw+C^$g=vPIy0q}(o8tw0;mb33wvF}9l?v-b4a>$R^K!OAw;poh$pWpuM}K@p zdo^=CMChdpB6rfXe95dAwUduG6jghE+n!Szs@+_ zCO1G;XYZ$sNc?kBqJYEyr?%Dq?yOHH)*YdMQ@i)3GqzqlgY<7Jz|D)Z9&Q17xUX$7 zE_|Z;;Jg+HQR9lmj8~FM94<*LAK2_0JNa)jQ?IL}T*{pnNios{oYreCSIq%qu}hl5 z;d{Bpf7xRoFd%kX`>%ZBVgh(N_QV23+@*}|_ZM*5%|`MIt4ZeA3W?@QToIm_bK??=NA1;x=xvQ2#>n_S8lyZQShEkZh!;KpYNr(cyFYJvy6xPWM|wt@1J> z*)+(T`z4d*jo7{B|7`0&YxK!$ac1y4#Y1tt){m432b4(!G16Ja^6c(k*Rj4wzBJA9 zImL`XxE(z7D*d|<_<#jA68Uk2-Z7)dph+8(geD5rJ$Gh|QtsmYD7)o1PUV zKlj4F+79Wf{kP(^QRi+}X*NanHj*4j+ps?WdV`oq7Eg z+^&A=$zPwQt0hTf_00%hk~$)lT}9tKZ;$xfO8b^yi3$DBjd{g7F-a^imjcN2KC%um zcK2T5eF#@;A3+r!Q)%tnMs`TSQiVnzTW_j^Mod%R{|= z#7mF;679B3747sM>dn2tx_rB(()ay} zf^WOvwpXKz){#?)&-rQ?puK*zbGOuh5Q)a{%tvE&FLY@H3r5xBx)m2 z7fs*0Z8eWY$7Rq~-6batGk7daz?L@GTGTXXf+IEuM!0b9PF7=6H2ly^b6NT}dZIKO zwx@Qhed6d3hJVFL2CHz9DGhlyz7p4%dIwq4)>DR(;OU82!rBMrF?I0eU6#(B5Au%7 ze-4#_ciMYs-Y8<2%8ZaO@$y+Xl#qQx!3o?&y-&pGow=QvdRs!#by|Mc3Cg2^Y!V34S4eBKYlaqPPT*i~l)>?sR!=+3OP{h2M zM{%TA+@gjf!>w*?#P@nvNYgDfv7Q3EE*>5EWw3H_;uc5puw+Aaa&oJ&5aFa?kR~B@R=^9o{6H>zt7+y6 zWRcfqH=vzuFO7iLe*m7BLLNgC>4y0u$IVM)%>1Pxvs5aImuNoQ;Uqc9YsO%HLL?1=7Lx$tc$;@;Rlg5?r_7;9^JTAekuqY zW)^Z>%*dJV&&bxQ$Ggb+O8dVU%bj*k^Kh*bz-*iJ-}bE)q5Ou*d+$>7FVRz6URDUV z#^baIfU9g;^J#$s)H(hUai`Hp&T;z{Jksg$Kb-MJ@7gc$urI@Rv0g6{WLvh%Rwu;4Omsgk|Dd3pZ=D*1&oX zyTpbElQjSl@-#Hf(Y~%*544s8!!7wSGu<@*VVXTMURZBr_w@Yi2%dOdw#Gc}BqbzQ zgfd5EI!@`rV)`z(GwE}r74x`S^wTVsp+{{-3}Q=UQRMDhsY=CTt9Ptcyr|(`o9Atn zmVOpakW@TuH6-1x`0hAN&K2}6`qHsNyDtcHhxZFl?}c%UamNYC4?g~92KAAm{>8>4 zk3auM2XaT3R$@G846~qTvGMpQm_}|6-9+nbz(nl0Bx(se<=oZ zr0Mq0ti+q8MH=Imq&W6r81;5P=Z-u{!b#yEsI=ZF^|X2s;!U6ePJHjqrVDlBXs;Ra zcsenyt*R90zaQsbDZ=$PkjsUNa!b&4>$@Qf3cSmllhKna{H=>UU_9SC0=0qezD@a_ zN3|Es6rik5EX7z9F>c-alT?cz%HC|~`MKoOgu6np7Rw~cfWv!X=kltX`1damO_4+) z;zXme@7>qKw{uidE#PiDlfI9&X%VI76z9em(WYv9x_K@&q)dW?NPnDnCWMv}Tl>1> zaP!D{LXL2x6w#oMfF>@C)sKq`D5Z$>C=pPqkPN9DMnpKn(3CknhXJSKxH4$Ges~$*pRd5T)E@QY-4D7x% zNdC9!Vms9V5&f?i#SU)%M-xT41uoU?&8v@f$j0eys|Zl2)pB^qn9$LFyZO)+Ue{M# z!K%jy`7V^U)?aC%O^_;?4L`DktrDWFPDC?^Bt-fntT+~4BKmZT&%pfKE#p>?zICl%#u;x3f4^Go4x1y3YMckcdWw~Z%yAufoc9b=U}>NV zd-+U7IpQ>b_Y!!Cz@{B}nXp(HfZYPAI~V=P8PMKDLv+M@FUypo{0z(vg0{H8AF^K= z8zX|Gn#EifQbgZa7B5ApPCeljN?02U`uZDgA16cd=J4MzPuauBet~q*yh3s$W$U0^i17@5LH;*KT=K3sf2zX}LX_f32`&(EAD3A9}?$O)Lvs~tJt22P_ZtNwyRf#2h2Q$B9B z+lkrA>D=o(*K|?@v&Ep}6kw+8>tMn@Jqe_?lrc+q|&c!nRNnv?nA! zR3@V#f%^$K!(-f{QJc6m4}mlIDln(Ui`v=#t3+!K83y6Z#;GtL-$*QeP~U0%o~xpt zT{^u6>!emGV!58){-IcMkIX%>xv$a&$WW2Pbu+>gF;3sFm{Zc=WdFLrIW&~D`3ZmL z!cgGWwB~Ln@vg7t7vz7bBuQdAd^VvKV=e4mL(9AKb$KC-s{ywlyTWA_8MxOO&g$@K13LijWt!P)IPBeSg{#=36oVG3ZGBB4(d;jh;|u=%%rWVB z0?y_$>g`tKe#6?%a8Dch2Ccm~dS=igzEY?3EXeFaH2qR(gYk-sEJte^9M&qNq*iqo z_;7O>dNpqSS3nv4z7EbcpB4av>MfPM^#1|JNt_}*6j8#15 zpg4$#C+zswXA!@mt%3=595ZoW*Z1Kq0{C2!GLt>|1Pgen8$ds`xfp(8(Q57nWA1WS zjjnRv{9&J5cJcEFHL^b67hDafP3^^eoblKg7f7cM>N;;QPt6}ZBE0B01&OX6Q{(Yw z9nnKZ?U%yVT9Po@DYNHv9;f<(*YrMV3fWz+PBx(CK$o#2fR`WO$6-3T0{Bp2-ZJCR zD{iAYY~r7x#QQP6Mnax%k(bdc)_PgayJz(IPG@ZTPayU|4H1oaW9Ya-uIn09js{0N zZbg1fKj}Q;4wqp?M-XH>j*dWD!-y*Evn5eVjUK0fy1Fs*IsB6;b(AiB|MJ*|nNl?Y=cDg#!F{R! zoN`e0j!*8UJbN8>2DOjhAw3$F6I^P3GF^oJ2u+l_cUZFP0*!Z}rKu}Oj-vd~?Um%@ z4Kt$7wpkyZlri!g6lHrXja+^r5x7QO!D+4UAFWup53dxYD@eMjJNq(i`LgiPzSyZw z6J5c%Te`|U#wJTYTfnh}0}DIoTC7O#yW?ZGsY4CA5_dvU@THmOwH8ud8~*T65twr^ zfNB=Qtu!od)1!$rZpC#IRNCaXtH=GGvz#G!JfWN3t@%K0U5d!X@fPyq)3;oW>&jp@ zQdd5Q7jp~GB2^TjifXxFTY%TJ#jUKRrM72Sc&u(Tn`LvxRokKH=-;_ahX&n|?uCQ= z8AJ&hMsV8w8`)lhYgn5LpA$qU}R+CQ838(S~uN5bI1{>P(7DK3~& z%$=Bdd!Mi?VSEi(3@C?J*xrL^3dnxheXgFOU12n@HcSc`%HYSfhqHnlabGR0B_NxS zUtKh=6jY&oTe5hbTLq6f=D3jDRqJ6V%Vp2#L#wFPLPo+dPqs#ahvGxJYr( z9-iu~50pGuju1TGnWeUNER_1bE1vL~Zs3WS!!Zeaq`Y zNjwR?0a6Es#QLapdx>wuOX#p?^5iotQ^gjmV4r1_6atNF<%qzi-(G}$Yr^ngtGYAv zQ~;EMElnc7Cd1py;W0kre;Rw&kE~ifz}dyF;<1GblRw{~=ir#mS*pX_k-#6G`bSCf z#^ZN}*1oKG%=UVY)Ee@PiP0}J?UtB>aVIp}7|dp|#+i;oRUWmMtgXg9lk|T1FJWMW zY6QS^ny=eCk@!LnOxUCh(t5QTKRiceugDv@^e5n3-XR4Na3U5Mx`TU^UO$uclc94@ zxjKB)5mIc>3>Q7R@F$-?GC}ji>wOPT$zP4s=$~Q7y{0h; zR^BSal73b(_GH0(y4Hu1eds#T^4@J@JD46i8lSRanD0N0TR6C^B-)*!mA)M*MmFTX zx-=TJ=ewI2;3p{kdH>>s6dZ)u@qcknfdA6$PpEuX$z#X5Os0or-YKfuoOtN4<2Xgd z9ea=+b)e#(y@7{P#;9|oSz6{WMtXXP?apgy^A=go-}R1WVHU4UslCbDj{?i5VS!UP zn2#;Cgpu58Ur%`PWTcX`g6Z%ITAzR9Aw1xG9(G1xEmuC%(zC|cb5d@*cI z$l+9`jU9KAabvoj!jOAuxF_0vm|oXxe;0f6y$KD-hnZ|r**@PPEY{tGvPn}q=H z#_jOkDh`<5c1K?107htSdeO`tI(@{t11tXZZ{6z(f92Z!74K*~)xF|47&(h`*sT#~ zCzyA}?M&BiO_@5YA~(I!b<6AW50*a^vOQMQw8B#g3Fj%y-EblTm{WIlB|exF>fcuu z)j>zNVc|IC5<7nKmU~}h1jOZUW%HU!`GP&BYNKMShMN#e7vHz`MUVu=b$D=S-*||x z{Dj*q8x`d0gtpXLZM)gfN9`>VH6Q9#8VZF}tGKCC16rJ{#@D}_y)}vjVv$hux7pkF zAF?{8(S+~)Ieno0G3R6~W+6+N&6R?Iz(1>y4~BUXc*5O~UVpdq4X;?37dB(q4+F3{ z2t$DY8_PQ!!=Qk4{Le*x-)i<{2!#`?|aM1Mm?+pZp4~|cGhVMsy8|&*{;h~?7DD9?1 z;VTY7=ikdNDJ+QhcvALH{c76S+aXSMJx-Ti^_6FRufJDX19i+rSO)f4_NhE%pQl4Q zP3blAuDPJWI7Qh5(|lLxYsf>iLmv9$$Fn;V{~%PY`I5$k z=8KJlg-FLcZ41Sir{9}!yziSu$A7*ZdQo{N0!prGvGheHh9?p7E!id6)J$P3$>L3j zvSBr;sWz9&Xdl?F#zFd?HM-Qz&m^*dxk{)-P_}PF@wX6K%1ejUv`5e$fAcYWBrmQE z*5^DJA$aN1>4q=Yu~{0vWbzq;TWPH^-)jx0CIBmT;rF!5v3Dn9qi4gUMEpV{va?@$rUbiJdGxn$bS0$xI)ZAMJL`)@J)c$40qpV?VCRtc^>vx zWTs`VhnEylWMgCuGfx0mx557|= zb&mXYiByD_iwl4Pwgc1YM+4Y4k)*kgr~7&~KJ+4Fv7l$6Ysc!Y2p|dVky8l~>%Cl4 zA&fe=vadb+OYMy2*Q`f$i{Nt6%K4(NtlyDZw1Z*vyXw|b! ztY*9ctl?9wTHW!ZxeFti-i-1{`p;N#!eGl@Ks~kIbUAAB`5XpHz8!g5uUr>dPvTcM zVFqZ4`2J1mU8H#ize<$jSq%=LE^S2U5QVdJh;zSN+1}kXk2!C~{I#2P6>A3wx+_9- z>us(2(f0a@kvzhiS(2TK(Dvw9t|C4FSPDM9JH5%qb|E0$-@Sv1eT5)cBfNx85k-iA zWyWL|Ve-%Hj4K|%v~a&m`xzspFn_vO8*t@W)doSR}cywz5(_qLc_J`x{dEE=Y zs8PVw8FB!sAbK&pZ|8Xna)je#s0(w1i^6Zp|1sPGn5bqVlc-zQGRJI}WVyh-vYro- zE#S&qb2ta1!^J18fj0)KZ-ZDb2J})I4yo0`cxX!Pr$22X@#@=0%d$&qPx`L;^B(kY zgVqwkX`w^E^9Vueocz_Lf`fBY`p{dKAW~xX)D5gca=gjCM)ic}l|E^@c0AFf3j)yM zPTG)V-+-Sl1%X3UgHkG%SFz{;1NfBofUz|lT8Gp z!P>_wU&ok*8>{=`M3x_0tvyCRm@TF=?v}%%lAAG`B?=Z7GAe5hm4q z<);5-C2hdCb}!Vd0*>ka%SWq&ur)f5D_U{LR@5DY*_O<1qc*<(#Hht5bH@C_U6yCI zYxhc40>qY2A1)g(zOQ#0T>r-H<%YvO)G_3LxZha~Wr$ffq6|z3b>y~Ze?_*r#%F31 zt5ktp1xNjRx(4%TYl(Jr2P#yERVGwdK1+MT3tPm{JE3xtmk)RA_kie|5la+iyTPs( zrYGi3!v#>S^nXGM&%mPLCUgPH^;Fr2{;&B>FDxQfs$KbCY3#QvWeKSVG0@10B|(~k9lSxa_24m6 z^tmd2g~_P9pq$=l5aN**SE4(-OquZ~>;dUCQis*>h1$%|-VAy6N5Qw6Q|mI7k&lK_ zbdIP(D=u!T`oL&HYM?9XaHQ`InB(EdpUc&2PKd1%H#XhlQdcH!V+YH~V;%=7f5c+XJ1udTS-$ZP>UqAGNZm;h(@Uc#dB=Az+k>j) zY-oZv+fNm5WCOxT#nP{3UF!;%=GX#+vtmrDXRgz7?W?Z>Z~q(BaTW4LUlkfeEZ3Nm zx!d6_nJ0pyy>n{(*PMoQ&0yaSZr@}I#N55ca$J4UYZbfct?z)bHz#(w!y+mV`(cMr z8TWR7h3)J(p+@ju(M0(TL-aAF@$hwVH<%T#i9?h2)!>Fd4RL_AbMKRfk8Zh9c1*Q( zkz;RdD;R6QZV9Tm3!#93$of@G=RqghaqT;$@UW?t^QgJ7yB0Wga)}pwGfJ&p<&|&l z>5bDZD)ES$_@yK_o&J^^N|Bv@q~nh}>XkJp%`3R&@wE@k=zo+p-|Xs#GKT6%ws>fG z6{5>?-emRapoBsOHkYYuwXtUi;*HAAXCbWq)7@Uok{xh?vJ!RSFXfpK{63-;qeI8F z&942yz4_WGVAw~dg{Q1cZloH#)hP+m+Ql(02D$mP-!&txmn-1qQ^ZRgcLqUYo1upB ztJC<>wB(iTbjh=Hr^zW5$!Y)R@TZSAAoScYZp>l*A2Vix`3nGUcLvr;b0nA%Lild@ z=2JHcqxZRLmqYgvTlxhOyXTZlKfGyprTU?fn}90UL131`k5s?EJlF?6lD7}9IIX5Q@iSIidZ|dg@I-?5*i76tZ z4&h&WlJs+#%IMw^i4GeGBm{%EREbY{T;Z4U|Aa6l9SymG!=$V1F+k#OZ0mpZkRzBE zHAVZGTC6r_@zE4W3#$5E`f;hiP#9h3{lr4c@h+wJl+m!4ep+X`vmHvJ`jb_R!!YWr{ zpKQIEB?z;S*R1@n#P0suayfjU#dOwRlfM6*$0?pDiyfWLOI?qAMm6B+{a7{IZVpZ+ zyF5z2Vi9uO2GV+KDPkQjMS6_46(y5_59$(CYM(Lrr0?ro#ON;0?O^TgA)(3vj0K6} zB;%a8J$sT=YD_mptNbt(Q?C}3S@eEI{>B|*T~@UHB^qF@RW3snKdtVZ9{Gv(7leV6 zDhkqw#971FIXeG!qO5%2-ZK3&tM;AcKjq>5>(qSA3%49@GB1W2L#v!!c(&L$En1j^ z#2nU++d6i{29$PBfjvjK#BXmx0y#wkiFRGwh?X2!H76H=Afw4a+r3vy7Pr*%{lzJj zi@5`kW>pY9B6-p9pzpY}3XEzVv>mV#;X;P~1jiPLDL$yfto_Z8S@A3oJBq@-z^U_9 zm+(mLU-jfISa^xDc6^|4D%M;GueDiN#-Baqv7gRBk?jb=AU(2Px#0=zXLA~ltq`~6 z_V1cNy%9Kt^?UJxSWn`5i>P>p_WW$}QX?jBK>PQwi<${8BI#V-n>GJwr`5FBp<4m+ zKYTsMEvz3AxqULabZZsnu)s|F0k$T~HPzB4`}PgSr|!23qqe*rzPM_(85X>omVCk+5m&_{ZU}!YRBPjN$X9Gv=Tz>x+rw zMTczg-Rq+{XOleR8(Nh)^g{wFW&LPMEEy0rg6SRq&DF5mAZL$2Ou<}hHI($06wxPWpOu00+d2ChNihiYg)e=NVK&F z89eVql|^f40Srn^KWIFWuG=%{yZg8Gc5^H3bx96FzqzGPT(C=uQ&SDB1|YrC5czZ! zoI%-0WW%x$dYYl_WKFbeYC?Dfr4u;th) zgvNb&$1P|QgiP1bekq3Qy4J@9dOC_NH?4Pry3$5A0t@fE7V~^`0 z-|fuBXqt`Kr`LA>+aj$BGs_hzg#9^db}NJYncEhAv}~EKOPJK)22D{9VBq9dn`v+?} zeyF+yq%$v)%`fCcR)r|fp9;D$wJ+0Rb`~A~W$}CUql>|&wcU(c1Im^;Ac+ULzRf8L zP~YUZzu0v6O50<|z!=-xhch^(tMA5YV!v<93L8J3hSvpl!sPHkROdpU{J>k!D;t8;KaFz1A&h|CdbanYiX zMvYwg-&`wCpWGm#xrz0%e{qQ1a#LE1zn#$FTImDk@Kg?Gj+NEV^+CnQG#a(8)%t-- zi2p~@CK^N>y{N3$j95FgQjO4|PxiSHH%IoWD0s;bGjMPf!#Kp^cBHY~Z-^Fa#W4Vy zuvwTdcb-b4umhsY zvNPN~W~3qKgdblnG?KlQzZvBiiy6o;3X<7B8h#7)An1rA_88j3INoJGXL8A+z>t=Ay zT`5gjw}^BE{YX&H0oWag?`=g0aaJ?;+sV4gujWL;`^Dx;^LcWiX=)tRk|NVcjhPW2 zj0`bu)|iU#s~Hn||1yf8qf;?Jpq%1gmv}GUHFmE-hp5&i^mzHc`G$4{J9bk}o9G5B zLepbiX&rCZw3a7x1LCwP7*2hzLk6u6^DSrz0?l6M-RvP75{SjygA%Rt^0*^$5VFDZ z305;P|7cy2%zZm}eDQONe-yQahIxLONTSWp*3x>eNQh#CX2?Y57F%jAad{Zs6Xzyy zT`G=qrb$*a&Lzqz%*OI?mDG$YYBBHeeNd&GF6cYLYcZImNvmjaZ0MyTR!(cDZVOn2 ze?kOQh|LPeF&oVHzO;(1>5k$Ywc;z|X9}n%`AuQC6driAx8T>tj_E@`NZoDnkx=>? zwW#wmOJVj*LhFMjbNg;s=Extd?-!O<@k?c7?GAyXD`{H-@5Z_u4nl_Ic$5B^jy1`C zqUEpy`tU)zknJ+$t^UR_WXBw6=lx;yazCVE-$D9w)f+iBJ2sdVM*FK6v@LAGY}BU-MHtFw zFk{hvQlnABd4^n%yG-pO(V4CB!3t0V_UQoGd^;q2+e6^6@~ZoDavE=AU}|1m17#zq zlaPEAjNed(n;7?BuyjV&xj~lo%{=8U5@A^$PWF7AC?(kCI zQdkZOOdkomj(LMm+{}FTecr=ecKjqB-yn3djqePna}1D*y6H0(Is%?b)1Mwdmx|MB z67R+){a?{qmC??~TYF1HvG!bk;xMm8iOUsap@{t?J=C5SXsGvMzEyvuUK6J<)bO9TL}I2!;xIEUBg#d&+pBl^^nu!` zQ}`uY{|(ztXpPVlf%6;dd5o{n(*f%<7sV{$(P{FuO8C~OCTvfxe8DZC;&0+B*MBf; z&!BGQ-jY(@F*2ICmp-9Rwt7YW3Jf+o#ck#xt{eRHKQ~OUi5f;ywA_p4;7)-x>UnUr>QJ44rk#2Fp@WYeu{$yOr#0qWcY^H3zK-6p7d_8Og z_A$5x@|&bd!sO+4*t;M5!kOq#3MVI()cJPk zk|S_TN%Ux?HcW$J{C4L83S7^Ic0yY)6vqvY;z8&8EdD;?0az8nDveX4QBo*GALDA# z_4&Iw2ULj~f)v}WjstC75n(YMsh*#k)3`PE5KN-O;=iVMTN25IHby}5y11k){^aP^ z^D{nX=5Rc+7Ljg0Rlv|xbqgESN{@6@ca7NYWuvfN_~Afgdp(KC5#~LiP=~JVev3f9 zDHk>O+EQ-t*ndc7i8w#(C!!ez=(vT|)CZL9ay;6o>VV5~niR6%ClrKdt@xPsJwD zRdM)yW||MYJ=5~-=HT?@B3f5kYon(f5_{?a_G6RvG7dm-WTJ`u{T0th^QdFh0(JT~ zKD?3ax(1Ex6(L3udih1bjSWqS=tmMXVfMsKqB{}lOYilyBET@`xA5J-GF=)Gb;!*8 zV58Gk-U=sa%U+#R)vYBv&3m%~g{-{AFuQ*RyBYG@;;N^wU7dqCzNy15n)THe-lqaP>Wz?{Lcmw~#5 zZm=AfD}*k=F5iuz>W_k$m0g$e>@H=pFVK~@D2^3_cKt!ip1&^Wahk1)4c4nVJS$UcCKcL&0aS@%HG4)1dWCqX8^qgXjV14D+<|QayX--+%o;f2afNe^=zQnSzTaQ zR}kuFItu}2@4{rcH{hQ|hy$385D|JkG?1=nJ7l_1LHMcie2HbpK2hxY&QP*eG(&NkfMLnVxONB%zFzn^vEeb~ck z1`<_buFKxQ_&92o9C;cGw?!Pk_0jWwAufI6(rG;{HdeIE_?+#DyJv`C@#PBrQ_rtTtmF(B@pG<~M5drm9ny7Bu*k^Zw8jjy`Vw zzCPo`X&)I(Ob6k-i?J1Nf1jI}()*;F!4^W|GsBnOy@8@kuPsBF zYe|~w_;Q2}@jCnWG<4~Zp`4LPKM5$tXFEug$kC7#9%NLR;5+g>WPGP{5x){l8A|_( zvQ|;;_5%29zHw#61_U`KZ)|9FS*P;OLm-@|E8DNM=kCsK_e?TRm^O9Z8Boz2b>;16 zr#+y_ByxE|eh(#lBO7*}5Omaeh7P?XDY%vVIYCi&xB|#>Jz;W}Q{rI22YUT_b$}v$~c4bNgMe#gtid^o#jUA6}~Pw{PqxJntfN(PmA^9cP+H z+CDZi5Hle)y>0&P!&prA`q-Bcf91}X&Who@>eFz89mdH|pPzVGt&7d8%TIVMRe&B< zJr~D3$2SoOwIYNQHf#kYh}uL1^fr_*p0yKezZk50IbljxVS#HN$XkIb7Uos#wBz6c zA!uH=15*KVAPjB^?bM&7MVaX*(xW__GIyhBn&0ElSh~8wSet}j45CH`vX%a zp&dV=jVd(1eHvX7@lM`xQ6Dn;7K#V?+ok&*HiApgp?v73y8tP6D1b|z-98J`Af^gm z=lnfmR0=KGbzs6K@Bb;|LDq-nJZWu@bn#sT(!*CGbW|*uNv+AeyzMk$-$UQ`Z$p^) zr$V{P-Bh#bWBAqBP7fP+Y7^b7gW!#6-o}4gdLDaRgTBvlW{x1-BCbG0;l zDnXgs=Gy4t4*SMkm{zumd8pzFBZ|X7a86AFZ4UF9AF?)De%NTTyLG2DR zhe6AJ$8a_@xH5u*O(|43X<2e$*g*hFT+(w9^*fxGN9HhgLbE+&<9S>x(Rfw&Io=RC z0-YkZc#IXk8_46Y7C%2uHZ4vi>|R&=$A6fLI*!0(77OdbrUzq`f6A(F9jjxYvC(6> z^u(JIE@B!h8Kd*!p#sUn#191TU%V3t($@2e1fmJtdCPyAYDbY{kiT%B@HSw>KEx&t zc|TWk)H;}-KS(Mk>2Fse#PUXT$MFs@D8c&et9UNoRf%2Rw&Ihr<@h5bf`c$`Pz`r7 z_7r7eO2Lngjz&(2$Y>)VlP1t+=VegKTOg zP6lhmdkGFi@Z8aWVg)h z(}lUMIw1kkRTPr){eTEw2$mAa4?uiNB?q!z!Fc;*_BildY)j+_&3w-w6R3ynQzz)a7r19(-)@1cG(rX9v_P{6rKTwI0&I?mdk&Gx zUpc^Xbif-tkdBE%;F@hL!<)Lp_HpgS>EU9nW^_K^o49%cF3_C{n5OdlCGP^Tk24Nk{pUtUs z^2(mJA0%J9^fV=*X-5la#>#m9J!lWU3R8jG5Iw|@Il@(Jk7)2qiWsJs{vA0ABfEk; zc$v^)xn-zvx9%d)uc}0pB-H%zH$XAuqz-?@!b!*ZZ^wg8vlt@~M;KH;b#7>7~iV-v*>=^lEqR?C{Ai%zC?UmNCS3-97R}%&z2FC zs(#17r4Zu_)M{;w0Ozhc!Wnn*A_rSbAIVlR|=Y2V|Tp7v=YHeKKsT#XVsxVvkY zFYy%zLMfOy+x}Gze|ZEfEYr+F#akgq{O*4lsWbPK!+(>t*U59=hB|{&%D?+O;*qv0 zN0=+oItCCM{~dQjUs4&JF067VMj;38UB@_D&)>6Nt0Y+a&?zi4L+6kFK^rty)mb+5 zSXlo3E~}bO(SWZiU$L2>3fn(ofL$I*qP+o;Hz?)6SYl3sK|rm^EWY7EUKDkFEX!&V zvTCwf*T>(KZ4Or)zf#o~^IuW}=H1_bSZ*I(vcaCA>{j~~-gdc$;6PdV#gpXB0rRiK zfR15P2^~r{F%Z^yTGU{-DmwVUg_A|m#5HVx+6tsW<_ZeTjPg?vV$jZv+gPn~{Q)BK zGttJ}AHakAWP4{Xbl`e1duO_?F<<|tvT`a&vUTdqQfm?3&`U*Nv?>3Y+B&`Xzbu!& za}1J*Ht8;kXG%`(p?GN0lRuUTnwzwk^cfVTD;?)U)po7H8$}g^6?pO*+o0r)ps&#` zl_8=VTn_(Lf%D@6?MNKHTZjnus@?fjdm5W7owIjaA&&o-5ji|RLAN4Ah=mLPa!~8o z*4SIqM;qZ9lp{3%=EUyEV%%I?Px45GI>NYGC>Z zE~~->OUYVP2Be@^tsTi0(xCMfm#98%AHAf?h2ljnv>s? zM<_K0;q}x)^z|BXiVf5FB)3W0HvpkBy&Q#$&R0@d_z(W~v8OaxeC!+3-vP=Uu#Ibs zqhHSB^y`{=ymU{s(L0EzNw$c*U1d5dX^I&zqvI>t!Zw<)5BpItir?qD;T_KYT<;4g z2~N?PvUb9MLrR_Q#4gP?#gVo~TQ-Y7XS?uhonn4y{AQc$S2!`J>xpTD&ve2Oy!FJ! zpbgy|VQ|xge^zu+ow)OkyCLz?;Zx~5-?=p9jM&pCjIMAg!h$}jiJ`1fXQO=Gs4w6{ z%RpSv_jv0-i*yXDyd~0QvbE^SlePa1S0VZb-YB@ms;T!(+;?MrT8~0VW{n((2`_!K~pDwR5YMteILd2 z7#}_(K<2!SJna+zSq0UBa_UW6-9o1k|1QdthUXR-z+F?^;PId=dllwMeA~<#xMc@5#L{j>S3$mW#p5-?r2s&&1z$ zd|;Yt9=@?PW=z?eIBK$(lXJlb4Ptj2ik{nQQG6-Ttr$o6`QukJhx9@u>GVXU`MLMc zhwLV;1uK4)=)j;>ck`hmDsS?pU-!9?KAdl$wONfL@}rIsD#EqudfM4y6UKz%hS{x6 zEI3`0@!`fomuXE%;#47rdX13H9?>*VI!Ab2MU0t@vo@2RFjY*H0Iem|^(w(kpaOgA zxpjA>Wht+w^XTR83+O>#4CC+V39s8utr6y&7!xu5nfimvMaCnV;q%5VVj3kPp*^wj zBFlGa$i}sNSA@i_R5W+D*+>#B^5}P@Rq!wU?*RgM)aerXqXBXwKzWs zRaTuawT-d308Ltn(|}K1e$5=lqC2A8hyytI^1LycSd5e;-`#~))}d%m99d1x;3Z`V z4I5$asSo}owkRikpf7Nz_B%&uv)IG`2;F{>5T=~YX!ZjT+VFTWG$J$p`J6aZJB6z` zID9U=c9}4k5?w*|f3za6&OEk{0gL#e%x@?S!O|cTed+ikcJbE+ z{>(D2FpE90ZLr7nv%gYEly2@z)6zpDrPq&TOiC_W0|j#2I*ll}hjOt>$1X(&DVMmS zx=+zo!{SbBU(!%-j`~ymurwQ+l5Gz1)2P7hEy3)y&Wnu;gw>yUoguy(^58Vs8S1%1 z>pu2~#Ek}zl7-#psv4pv1|H|(LD+@jb$wtG(Btx1Ib`CeQ7DEW(05VXqW{nVTdXuN z#3k$cwj44`+}sC&OFLgQEHRW>tUsM0be1Uew4ldx1XF30Kk~=$0{`Fde99H%5nAd# zzoHAxKw(h;Y)?6!tg-Zs-v=EN|GNYB-?#98M*v{|cl&=g(Eb1Y?!PZDjhz6eBMq)< ziGs`fr9t>XNf4kX4VTLHYc z3y8Vw31R~MKx`}?JT~0}vdm;bf|(jf!770~3q??JN(nqZp$VQ?Yk~Xr2H>gVVerVs z1Qebz0MBgHLAmomQ0`<5-Z>ou6&^<5?FAFia?uQYbT9xNuEyZw<>MgfoE6ABcM9D1 zae)|iE}-gyCG_zMmV&@jnj={LX8bsap2 ziUirwVW2Q36qMb#1j=q+0WWS}0wvJnE5ojVzoKt|S22O$P4rdpBKjui3OES{f^ET< zPzUfe)DFB4aR#4mdw_3u+`;>3Uob%M1%(NB!MphD;Kltr;N8PWFdl~ky$M&rSfW4Z zPQDF>Q*MIqS$DvX$3cLe77BjmL;(Vx2#5qCNJvNkkD;H$q$Ke8@nevek_?KnQbB5J zI><_cezLMaes&hf&3y`TpFRco`30ct5fN0UB!Jhc@t`_03A}mo5R@0>f!BrEps64W z)EDQ0s**y`RPqG8DJ=pmWd(plDgh0~f4}ctGjqz!+3Q(t*V$(uI(le79oc`7LJl3GuzkDe!v0-!^2mNV ze|R6AJbIKOjvc1+VMi$>a}*!2k#6l+OYy&M zqq{qQpxixMNVa!7WgYUT;=P;c-eDiQdm@M~9o_xhkc#+a&7wBd}6jekYr}Ee^l3$IW zixD!CMMhIpbTnO#iJ>c(F447wOLQeJ0cjE`JuaHkk}gqhVhp7wU8CE{SLjCSWxA1; zNZIL0l$3m(((p;Xo=O>MX_R&22Hm`MlX9{$DC_1e%Di=pa&OobS$-_4;1rFo>dbDQ$>3#bsEdqqW5 zcJCgQl-{HA`$be-TuP-SrBqT@j`RCeRa{8&2Y0FRVFf8Fi>X>sPIc7}slM(ZRXnUD zIX)F~1-@5MT}?Hq>T9T4Sx5EwDC-*N_uqf#?Ek;?zZUpk3;ch`0$+dav1rla#Y>nL zEn4L9^?P6cpOXG-50A}J$+`6^eX7k!_Fd%hp2z>N5FQ>&B2wiI^`*IK@v^9>h=_=& zD48tzT1JUn4RMson?2t99}~gD!#7^pP?{?X3`)WemrAwENU%Hf#aI3JgvQl1>dMzbG2@z_2 zzy5DW!=j)Pc}9evci`2M%EDWhHmq4bdf>nhKJ4E8!|oq`Fnr{gm1_9gsI7bffMwZ~g z#{ZTL7Ri*k5uV<%N7c6uEbDLE(!|crQiJW}VDBK2g@b(udppNbD-P#0Fg&OPZO8wd z7Dbh21a9?Dt+{(>S=W~BP3%nVEH!#-pt0+OcPG3p>^nFPUvZp`z;tiXe=5Nu-`w0F zPye*4TYLJqY~S9_*wm6qsPABJ@8sYl2_eusfh;UK*gK9na90vQCHv0=ScJPqJpEE@ zZmsP4M*H^0#>S?0rj~Y=PLct7F*a{>=$$%t>eLY;IF8y=sFC152!lobCGmcqvWA?M z@4wOB5a`CHrmVl6J$t|!A4z%Mvh|rdGIfFk!}mOb1PH~Xf7b+yk`Z?PrIiQzw`gH# zXbb^Np+D5Ov~&_7&`WE7n@$eyS{rnfM6j^18*{u~)mRG|7X4dMxH%)$Z*6?TtO+&wV98@&t4ONy`(I_4$w)^$-;5?fqK=0l17#6pVkUXg3=<^2B~sJw|KR6t2Tyh zj39uKENH(q_Y)yu6~ zwQ0lp3;P>e+93-d2b!9;H-4l28!cKJnz972zc2yvU#E`lO*ViJK044)9-peJ{rdte ziAmk+nIT{PMr(kBfR6w)g8G~T*!Y%~Cf$~=4-5%8@V!fm79H654h|h1I!ZQZg2z!O zJI6ip`uJ3J{ofWqhFo7PAJalYZ-oG02WSHTC4i}EH=o4R)Re@OjC;khfv>h_6KEX( z88ki+rBSC&_Ks^R>*KGflz%e@f>QiEOYe?;jkOmdK!0rjnwX*lv@@NWh!#govJ9{I z-15~BK+1v>LhGCbIpj4&o|ZHY5E&3fAmEc? zVq~%q8B^@F+BL7j1r82C*OdYs2CP5!9btjxkL0pcRnp&R8EsD8wl+gPx&`206mJNj z$pJ>~+5e`dePUyy(fW%Di3$-iT(2G28t{zn&`DS8e$t4@5+Hrc`%r z0qnMITNxN&FG+zd1TYenAZj5~@9jRm0-f<$fQ(dAdk0621)wzEEQuxZwwWfukfq{fB;DrR(XaWGWfT6Kln1J{8^Og({Q9reV)DG^=xWWLE078x? zFW7bdUKJmq{(}&d1$veiyk*!1n(Ne;j9?((5rCQqT)EwcvGHaD1U@+2L9~O|0=)$! zTcDE&Ms|WE5dYx#L0WZ0>az_1^&?bMTeN8d=6l`}xaC z4s%Ob+ZE8dfeoM`NhCh8v-`B+T0}$8v#MfQpkLwTmWF@_33$YSR{vIQr3mC!05^lC z`Uh?I_xA}1ib}bk6^GDeea$tp%radYQAY1@65eOOwFuIoPZ9lDvk7#&C1Vlx6mtKC~ zRA{f!pN+saK=`o$25m(%NNNZh8=(teY42ojDfa9EsV)2wpai-W@`=4Y4A2me_H=7- zExcc|+{Dye2w(s(1{TCdfB?b)ZAB5t9x#O!&=xd>0HQMj319(DcMzU{B^*0pGodLz zKoWZxpaBMWsvh){dFN(#wKF$wr?Eg2J`2Gffd|@(cA&N;W+^&j+#clq2op!4fYvDu z89MdW7zEN-*xPlzrSvaNZ5Dy3cmk@|w6rwW7(lXuq`wq{FaQf6B7hr0+z>%y49#)C z>r4O}aF0X^1Ku`~K)1JdwEey&Le|i%7TA*L7q9FOdzzb@wUta@pce%~e*?g`5dsJU zNCI$k5EhUOAo|6+I0STWO_q=(;TW-SwCh)y7Es?T0)u3Jg(0?+)mLAA`PCNOB-eCF*#`(pCrtnd?WI_N>k*;&-Oe^d9*~jygacsy zi0b7g_U4wBkf5zb0Cs}L1)@ww(Ik1Gt?3YFkSo)tt}R~`CeRu|3IlinN;5R;&cNc` z0mC%Ng0hGw9pD@9msr{#t^}Ezo40MJi9!R|LXrUbBLdsP0VoHIH-v{rM#hFmM#sh` zruw{MVrl9G3z%B#hGt*`1f$THbr$IM4tC<$u4`$wf4!f6E$DyQzfflD#LBY(fQJCQ zVGpnbI6w|)!y$l|aVVZ*6d4v785I^CEsK7`7(EhuymTWY0+MCWkR*e>g}r?Tj8eT7 zQt6+YqVE7%L{Q~ATYGaWyjX~KARz#@8UaMDfYK2LXv6pdp7E2SUNf=-xD#x^LTK}% z7W;`k>~Cpjvalvdre6dtxfPIHI@-?O$_fHlLIz0yc0xN=za5(ak{IC&L%fVnLj6ee z0Pq)HbW+G0+$u(1wB$H|BbvN`GD!>H0poLcTjFioukvz0gWjl!@3nx`?EdzaR;Da~ zcp(H}f1nF5uoUcnltFFb0AsYk(FG9jF|jdkwFbJqDJ+0o0R5305l5OLiSdCf$dU(+ zp#S?AxvAAUS`K6YFozBCs4d&{}{C0g)9Y86ZNd&tka`7J)w? z0`ZAi|I(|P(pb2FH;_UY0y#sV+W{R1ra(70wtXipCZJvyfJ<@%Qi=yUL4QjtOKTAX zaDylZwEBzO2z(9$Y@JZ{M56bn=>sNy`g{wW0PukTcj6s`N+Tu^$DC!dL}6j_es-c? zy{-=SOWBc~*v+Yzl{LVb%&lPrjs&g!S$`eD0LDJ(f<>Sg7KBC+j*^_8Z(*dK#B%E0f4Nvf`JqIK&H>kD`m0qDXK2mu_i z7xcqW%8Muyr*8N2+XD10-dk7*|A43mr(S!>(9GCOQnG2w0yLfRkx`3P1%C0m8W8$d zu66>xKo>T!WNb|&ASdebfs_x8c(>Zu*W1r?tM3*+Pwof$1VojkwR~O-)3ONMOAutF z1;@AIZ3g^>`F`=K+R?D6)R4+mP7@hlQr{8>k^ojP0K!4f1TX-5p

    3AKxuoynVOg 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≪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%0DuY{{@ZC<^Em0XQIc;-LW%iuS7pU* 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 TJNIIy9ffcD_@2`{diQ?-P*fjj literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_Warning.ico b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_Warning.ico new file mode 100644 index 0000000000000000000000000000000000000000..ccac6a8c7ab6010b0a11a69316cbacdacd1b7fde GIT binary patch literal 68655 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ⅅ^d@V!tz@VNRMt1Q_jFU_@2#cbro=PVwsRk9)BbUdnr(lLMSL6J+Wi7UZLY1AU%)xM)IJbJ>+ zdb=GaD(=&;CNVixww=WASUZ2Z6*YToXGL@Tg;Xno=Iyo=Of5@q8(C5fE8SIL_NhFo z9~=tim+SldehddxM>A4i+Llbkhl^!Y&mK8y$kFXY zrfj|n(q+2hDtD_!M@KDluZ-MXIuWyi4uFj_*)<-}oD@_ovy!RRUMqa&KweS>B-E`# zKBf>BK*yxHkheC`yHa9O)irp~onhKuT3|Dkc<`1kk^2NuwUHs((XgBBkMD~nG^$>` zdKFV~?I_pUo6T2c6va9Gss_-Ni7cZ}MN6`7kxUl4RQjkuFU`5bC7X)4%mE~m-IUxC zeK|?-HTG-jrC%iII>rtn;{f%mPRf=_j$UL%nCDYe_jT72GC8|%p|dorqP`kfH&>}q zyS2MDWBwY{c*<#e+J`i1N{S?M!k7l_cery6WH)Ip=qyptmR)?F9S~1lTWeB>4l%ca z4U*{hgr4|iY1PWj_Xv?u_nP2%S68JrKlqCLx}i&J4b093I`qh+K);s{O1s^hrtFh& z786(zDxQDJW3Qdmon6hgSMRCV#WSaN&lR3w{o0NrxO##wR!~rir8!AC;6j-#ohLyAQ4N`st_DXNT#nY?T&m zvul)IRI;F$KS58f7{firTAD39ALZ`!>26tsk#E)NxpSm<3YmQEV@j26F}~k_ylC4( zv1g4jY4?@mGU0AXHF3wHc9EgGE(7%UyWab(&5%@nSz|chFgH$vEy>2Xkj%>vojhIT zrq8K16I}bBDa9mzzVP_c_v2U>!V&NJZPC7a?mG0fg+uRTnpQ6VUO14~nQfnZ&*CYX52DCin_EK0F(Meedfnd8}MW0 z#3f~=ogHIzh(+1`j&M8A^F%)4~WcQ1v3X;5@q3*Vwu~UpvM~rHi zi&NXd85|lK`bm6@u1qxR%bna$Stgy=0{80DReCz|V7C-sc7HP$j;?;s z*g@Fa@ptVZ0m z>`n)?a4*7wgT2Q(GWSov+x8lryzJpu12Zl=s8S7+GU~`uFo>TJ6|H= zn@QY;`hqE4T(b~*G7_s%eKD%x>$Vk&J#27nxtVZaw0-5g`!*iefqU{QUFT^mKpr>f zExVfhZYk7Xsd>}g;XtOvk`>>xB&$m=i=GS$x%=KSew8wDO7y)QrZR~AxYkRWlEV2S zbU8&eVyR`P6g3ZJq5)@K>!Z`gx2=TG)ZMpM1_u>yPjovrG`&`(G%Cr)A?bTybh|sJ zW3LO-f@VB zDE}&3%x;eWkya5uIbm$KDgd zBH*q!Q0X^vQ~aP|XWdGlc{DO#w^bXYe3-v{6p0#v@_>5Xj`SP#9M286&e$tZb-u|6 z&rZ2Psw(xJ{N|#m#4L|OJZ2PkcACAnOE$jgjcEqw01 z1>40pDflvMzvdbstjVjx$k4;CcSj4yrcx(iBvG)hlBtwh{w0{51Q*BaIs^&~|2-(4A+ z^|%^wMP%Cx(fL%GzU_c*I`&faC~pDVNFrOe#?XflGl|RtzNU8>FVx9W)})~mBaH7X zy6JQ?yz~Wqxk2M`^}~zU+)T9{(b;A_jJuvGVOS@H75#oG|mbcxGkQdz5|ewo1%8&r)Ru#l3!sUBFvO%iz3r7WiU%D`S)V(d$P4Eo+S7 z%<`riD^z?DPpMmrTs7nU9435mdG&62$upN^Cv1%6o-L8UzJ-J5zL2UE=It#WFq+!x zx1`FfrN5}% z@gjxG@j=_Y??ap-FduqdRZC90ulRV)7jP86ropz1c}LC`gjb;>?`i{iuBsh3gFP

    ;|36A6n1+Siua&hzgcZCf}Vwe$ErKcQ95 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 literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_info.ico b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Annotate_info.ico new file mode 100644 index 0000000000000000000000000000000000000000..91eea761285c5cf9626f2883e863d0c9c402657f GIT binary patch literal 25214 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 Eg24EzP5=M^ literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Gear.ico b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Gear.ico new file mode 100644 index 0000000000000000000000000000000000000000..e8c7615cf93d912e05f498c79f70df437f0dccf7 GIT binary patch literal 98182 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 MWk$*mD^n={2eb0k&Hw-a literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Images_32bit.bmp b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/Images_32bit.bmp new file mode 100644 index 0000000000000000000000000000000000000000..522e8f93b3b198d2e503acf7653ee078f5da2331 GIT binary patch literal 6534 zcmeH}&ubG=5Xa*`;KhrgH$8avAbL@V;7LIbJ^2Gs(1HgAFBL>V(1=Jy@FM;qhvHAF zRj@4@NsUDDM>N)2n`jeT6GNNYrZL&gW|R7DzIA-;CTSw-X&=dS-n`kF`OLg->)w2F ziL0_!L$1Vk3%*P7UEo>_i9OB(3;C@WAZDE9binC=(*dUgP6wP0I2~|0;B?^sb|4ao zxZUp7)>bHx(4nA&Y&IK<#h_zB!IpKU(`g!`(P*hul47g+|N1|-(Vr6SA1SDuj6{Z{ z0(&?dR*$d+5deYN($WGquh$E97KWp${@^ScMkB==g@XP6e>PT?jf9%>X!fVy`q{t_hej0D(y(sAa@BlIHLfTNqV@V>Ol_h%*5#0VOO><&imx z&%rDAAz$`?id;VNVB4DO-A}fkyz=nbTY92kVGIU?q9Z2b!-z#4Mh+LGq~?e*bPTtu zzaStTaG6wB(VjG?I@GTpdg||j) zp?`~OU!$i&BTM}m*M0rgt=qd!dmlXy)0sn&(WqN#CXLwQeo6|t*c@?#_Zg3`ST?~R zRBG|6fOZ`vsk}$K0%b$brc)n+kNr0;;gkRJaby3~qV7a28bvoY>^;t;cnTm`h(L*v zLCIt?7#S@*!d70YJhT5>o) zGL(zG&whNl=WK`X#XIss;z2A1XEbavKF~p77APt#pM?+XT($fyyy#Mcyei$VB)|WZ zRN<}ER5s0$p_|$dV`{9BPUxw4{>$LL^Edsk-U}~4a2pX5L7=EyG+Kg-KThZMxA2;# zxqC;9srT%RL-{NB`PjXu2vyK>uljm@cRE6SJ+YyIw@)9wd+yf~pE3PSht4o5im!8T z?YzzUTX>mNm4AhI_CC+d1n+j>GaI~I0=1c&?!I=hFgCjXLTBIW4@_G1Jp)WxyjR%% znZL^0-rf#6%Yu=SA?b`FiQ? zoApwqTSxRbG1y7K@aG$3X;S$XTT;K&9=*BPs_j-wV7M{Qtbn=<#?sVkkmN z<&SwSaq4X6z0YVP7lSnGug+J>xLR4V6-At@-eh&YaFC~(QtH2d?4g?V2ZEvN_BeKn pmd^<E9`>r8TWxYKvCWs@77JQiD=TZT&y<_nH6yzvsE%J?GqW&w20rJm=i|i!;eiR$4_G z003EnJ^mCpJA>meAbPGVuF?5u&?!XvYwBH?dEv;u%?p3D|m64a&G_MTw? zAlJG(#1wRXhy^z!Gh98wJ&2B2KUN5WOl47Mh{zB&=nVj77LjbSUl1)^jY9KhFwNnM zjZJVh2GtyX#)xP@WS^u3Fzlm3X{Vz|u6|KLex_8o1x{AlED{Sw2%&|O)gnWJnPJ#S zbM?OiV?lY>j8w;&g;MF*Q+V629-wBf9uOYR#v+kiE*HT?BUqvSNR+9mDbm0YX=tbq zdgzCpV}_F>^_gKBUjyK2VSb?ub~uB@RNDOhu#gsc1CS*a&4}NJmlBzorjo(EppC8TOS1kPzhV3KE4d*oC|+W1T`7G!VsZ zN*v1U@Adz)nIU(9{0}hPe=OixLFpf6c4_*DT^bXllnZjFclEjq06@eEcq`X{lk?Xv zIv$)=7FeK15p0A`>&*a>IM>*VSV}y7IHg+a-ssWxz@UNel{#LagH-&=Q>*MttAD?7 zUu(5^q~JM(7!ulL^u8l-0vWtS>M{x{eS=Ct6eyX}PFiB;wbrmj*p?b_hy z?w(jg_y4)LS-2K6`tB$J0*jP|z#tNP>@yQPD6r$lW%B!M$z)g#@+Zt#Q7kmRt`6hs zCfQ7>PA@D>?W3c|@<5|V;<1;WT z5tH!d9yYcx@}bX*Tb@}uH~1YhJMSG{ur?GFg~b(fF2~00p? zE{tyMh3`aXYuKd$?5S=Axg#c)G@2HmprFuy)**gyu49}He0b9$jtO}s@u7PMSG>P* zL|9-NHZwD0kT3RoWhKSe7l;M~ ztxtW|D_C4h(9F2z2Zut`$_O46y`>Ky7PiFU5EoqA#@mv05r}Vmr@F5#@y_WkIT)&> zYQOBXuIZRu+hha;s99JPx3*eK%gA)~_g9pZkR!c+b}TYewxx?M#zW(cCy)TC@bi_t z{Z1N*mhvAec*p~@XFktlIefoUl^RytG@d+nLAJTvAqTjkcFZCyQ@@4E8VamcabW1} z)ac!fT755Z!ZIet9Q>vO0ls5y>p;0f>Re}Mr$l4_yYuBrN@M#^Hv2x4Tt3v)^NRb3 zcycmiCv^Hd&u5074+3zh^?B^KLT$dZ`>j#Z{9c-#$AkExyZ+)&1_yJXPAfz;I9%|O zVE1~crly8{-+Mj!k>ZxWuz;~%UstESPAtY1qWy)MBC(Z~l{>64T$oX_%p|(tyMF z@&w|R9F7t1n7KL>0+mj>j90fsV>9gAp&j(QDAuUiUlAvAb937%sJ5o6suX+8cs@gF z=TM5)IQAGJ^KrulcM`kZT`O_kFcI3|jqpa~pwc4Ej`7Gm0rXDQN4aX471t@TpH<7= zXypih+_>6u-Pg8X#jxpmkBIQ&){H-s^kqp6;Hg?*j@|PU$Q`snWiNxJ{2|iJL+{YS zSX1#6U7p~ifl}EYf9!`z)aV`7IwT7>0bFtaOcNs8XQg_!%29AR&eJsImzyf?LEp&~L`=WygJU%9&u#538`Z86 zL5oK=3Ld>Ny|9%s0(5qjl$9k4g(LtI{L<3KMzX~Dva?S6tJ)y>360p_bin$ISQsWS znFw87UEA)ZmD$tQCD8Knaw?rZ@cMN=RJCuXk-Iqkq~zqK5Is%#C_R*OX4yOR2bZ%N z36*a=gB$i$woRqpQ^psUA7~I~@tr0gu1-a7jW3d^XHL6a12Y$pDl!Ca?(Ql#t%$@_ z)OvUK50l4iT%6q$Y+M>*HZk1A(em2bYx-yFz%JOgJk`_n__6Q8@cq&a0R>fAS!r(@ zym6NBMNpb7x&65-`?m5&^GmVl>6nzWiWdZBahTu<2QS0|{XuO4j)M}M5PsY#Y$D4$ zt-pPH;llC``vJMui@{`ef^Aesn#17$qUX<*Pvi9U=g$QZ(lvisUJm`VFw(O+H#obn zz;9@{-rMV_cSyz|TMsp$TuV#K7Cv#Yr@K3I+MQG(U;nxfY_O*1 zKk3!h)*58KIARu=K0NGA_2fT%7$YhzdOZ)~gr;;{i3+QvXpi3JC7_CuI7_$OgC<-M zN93|HGFrgiG*lOIn89G^c{il<`P%je(Dc5%j<)3eE^gP{s@&sdqi-53rP|tUd!!c? zr5R@8ldWMG=CHks%eT+?#Dt8IjX4}f&*M&PT3VWm|3tt(xlVgRwR)lfUQ~?o5?0E< zZH22KJ~f{>kQEtAuomuucNw0`t=G}ffg*AobbeI_t7BLB^*0Fd8Q$c`p%!0f(0b73 zTToc}^huidERoNc=*og$(uYDIZf;3@hBXBCJyAZx9xst#^>koB-OJ0XeS34w2Hc&; zm-5U`8e3FszTWe;D=SIKy?-Xv literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/MenuItemsImages.png b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/MenuItemsImages.png new file mode 100644 index 0000000000000000000000000000000000000000..cb3ed148102bd2b94c3122e4d5e22ace540aa702 GIT binary patch literal 1999 zcmZ8i3pms3AOA_@-f~O1ZHrv8%`9SuthseE%l%fzW*ZAL+hR%Nl8i{@5~4Uyj=PXc ze`TFq|LK0_L>h&WO8Ot>AnE*e{ypb^d7tn5elPF$_I{r4^Spc#(M?rpw-NvVsvhnH zZ;*$9TUS9IJk!r)V?idv@pi)lO;7aZL1k-%v!^ovv|Lo)Aj^TeBFjC90|45_(kw}6DLPiB^(b6W{9D2$xvQQG?RnnIl%u)j0I(> z83lL5v8i;dH^KG02dFu~Be`4_7KKVkNI)iFkg@Ct6xzcPnV~+o}fNuq*zmbu`^f$URCJ1Q)h@C~jRb>E>d+tGS_KiHWa5W{`$4_%mu&DY6 z7E*$gmF3S@zt-Bnc`&G&dx8o#A0nxT-``VsjF%D=X^(EU0#lNQ(Az8Hwc_r=7hmfrPZw{?H{WOr}w^_M4h zi)>SwWPzY$Zp{FgT_%x=#P_swXzm!lVz{^@{>DMu1>mM{fC-HHqaHm{#D z(bMBdI-DxRlRL*@3J+#Oi5C6_K#uFQWywS3R$AiT2ilLC&rZqq&sUk&eRzgfNbP+~ zT9^BJ+$P%}Z&t49^1R^~ca|a{shIjZewBas>iOj4Qy^?GPyZiJF|-&P-Cvtvx*3oz z(WhvvGTx6Z4tTg_I=$v}4b3)l4_pGKuuk5ir zz`7F(obBkaacM*{JMB5L*_WSo$cRKDi`}_ffFpY~f)9v!7(Ugo1ptvAAXH#Kw& zGbDG2O^If2>x$Kz;(Y3Uyt9gIU?gv=ei(d931g7F?w2It+lCCMWbyfmvrB7NM^3o- z_-K@tmWH(lzg=1z?d!{6Mhh-I^1;?#ndJXciBSPMY@8l=ScMy&NmkN*>5zF*V4Et5 zx_*DG_a2WuY;a?|K1*H^Mn62?aHW1HzV%uwMI3>~;V!Uj8}#J?i{RVt_WPAP$IAoM zh9dOWs+b4Ek|4md4Pp8!^P`DMqF1X%52q`IhDf$e*fAVc1gpq@-W7L1UM-Y!!D9II zLVPz;<&pX8b^ZJ6#m9ZL0xgPQ&JY`Wy}TRa3-aEsTbCNbW{0{(pVDR| z?t8C9|1K`CYfDEo&u}+#@ge}oHyW5yEb$zqhUN~fM!61*>@pjH*A}@O!G^u7b$Atj zY_ZItm>3R({ZhWprh?b>pt9znLBZhj=BLn#ut0U@ zK;x!8DQLz1w|lGD%!%=4^BVucVvEl=qFkc##H9WCk7v(&)lUa=)qEVYBu1 z^*1crM4*Pe*WlvfE?wPvm2>#fo-_8mibb()(;ke|yP@I&-6C0JZX(3Xs!zRE+pGH3 z-E8Bmz9Xw^aLbgpF+BQs+3NC}@wzQy0t7F_PKep5kS)Nw`T3*ebL=}pyLmL`W`SAm zbXVRUx4av5bxIP6#HZE5Fq;5>?^arYYt0V~Z5$UEBv!ip;K)&O7M<GYc2QlVb{u5XxcSUok-E9_T`Ast;Eef{uw%wge?C9*QZxK{hR<<=YF%5t3Zde+aRxBu<^vy@K1YT3b+bt*MFO>aMkQZRe z$BU6Jr>6?PTn>Ht7#vl@!8m>Q^G4$3ee0Z|57>I(@RaQTt@Lj)DY9qCCx3KLQ3{d% Nsva&xLK8kL?N4Z3Xv6>j literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/ToolWindow1Command.png b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/ToolWindow1Command.png new file mode 100644 index 0000000000000000000000000000000000000000..b22d975cbf00eda60e37587614e0677d0bfb525d GIT binary patch literal 1172 zcmV;F1Z(?=P)AHIP00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGqB>(^xB>_oNB=7(L1Sv^GK~z{r&6rO} zR8bVhMO+m@n`n^>S1nuxLD3=*TeOfsmlen?+6F={#2~abZOoueAZTJ(h!8>v{t3;> za?E)|5DA$%%#4KTQ&4A9oX&T-XSj3Ub>17D7(e)!JLjHr)!%vdzW1y+tlHh(J<9H6 zC)uRE&VI~3rPB^9A}Xs7r5JEE`&%NBp!)jyJP!>G(f0N>8gX8yD`m6Unw_1U4t9(0 z`^R-SPl)q;AA1VsnwSfU>5DfL{NbJ}g%6z=Y!y2`Ha4b!&wZSu_228{Z}{|MX*t&j zZo(SpokR_TtlRpvN}qckDl^<=y9pd?++5B0pB~($m6=KGCJ#9-DB`AjX=;A-hyG_1 zN-BV`t*0W3!CXzHQVMc9m8MO9D`43PoZE#OT-5;IfBKm6Z09Y^y}%qG^SC?X#c8;% zmPW2zAT)v-cn0$>D6qi4bZ1++_WElMyK_xfRaTMM6*J>-K>W+fd8@3$k!07x#Wsa& zh6e@)sHdmL2_OEsyh5>94C^nU#%=(NtDNIFl9sXrroHe%Qf zR#RHk57Kf$F@4Ym6oL;2B#=yiGL}!B8j$3hx#l>m9^&~A$eWpY>x2()toyQ7R+pg( zF;^30j9tL+`*eCvE-0oC(tt4duu~>1a~uXx^37ax999qU{L_hv32JL=bHaz`K$0hxe2L3grw7Dy*V%vN z@pF89A^<;=&QMcR6D=$(V6A3ds#K@}eDzQ1v^=?>zyKfhChP(p#i(@(kW64QmQS4) zkXbK z3DUMSq1eYz6R-(fVy2zqKPCsu9LuLp3rKRrQR_M8gpZvtIXRj8-rL(t$z&3146={t za`hC1ryCPE8iCz_=YDAha^&$-WCO9ipLYNow%GtP4m$-%g{;#8a^T^2W)0ic`s=u3>eS(!53jy;Ap}TwK(!j{X4>h0jPj$#%z}oK71%7O)%j{Z2*9CjSurx-l4;Lit}qY m*JGpEo(&`nZYkjtQN=$$-bTw6(Xv|r0000h56vPVob(jDI0 zG-#Qb0?FyRj)r$%AgQp$a&cW)&zDv*d@jK)6Kpc})So(R-9(H$^3XUo_UXp6_huLB zS)e+`9g@Ho3p7m;$ru`&v!Lb)=EpLdTsRlrI5?d-HtePd0<>puKfXUW35hIFtWw_fNh?vO8@?3{4QvdnF5tY*_Rg(o9EjrfR^;xBOw z`rYicndk)Rx6SY@OX1O=b2j9%2J9v-vk3m$2b#8O=RuyqQ6T2s*_$kh#X_D8xhu@p z^hm$b>V`gp%@^~NX~n;@?C&AL-pXQ$``v2rUu^4XH`pM7PyTS+0r?|?6{yymfh|Kb zz((zaBY=S)&KIcG&w7be^M@%9p19Nh70$iBSMQ20)@g?3B7~|->p<}WFTUBAZ9~vWMy(7M{;3sXlY|} zAW(8|V`X!5Z*qUb?Oy-@0VGL8K~#9!rIN9ZL{JolPobgOm`0;fXl<+7Nj!i@5RD)z z9$=q0{FCTdow)GThotulH0juuOBfr Vg{Xj7NE!eD002ovPDHLkV1k+Ju7v;q literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/db.ico b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/db.ico new file mode 100644 index 0000000000000000000000000000000000000000..c996ee2dbcfb0140ce77eb79cd40ba3fe0f93e7f GIT binary patch literal 45451 zcmeHQ2V9fK`@c5?2r?3IAr1m6QWsbUPKbaLMQXK{76GjltuowFkpvfRq)re8>z-I~ zp-573U`0b+$WUkn2dE$-LrC(!3mm+j319@Izd!GX%X4?n`aaLQ?tR~TUjU$h7SPoN zXwhx14Zt>7v9v@@7C58_z+u?OyV>z!Y-;cs#`C z0&`mcj`qR!xZqG{0PZft_Fx;@SrUfrals5G03DA5u*S)8gl;pVX3&W4sFC*L0Yr%k zO9K*@xre5s*1Yi}Y{7}!?OwnJ(_`q^p#c05q+K=zVggz|Bc0~~pcjV8_eS#py!uq){g?ZR>ZudCVN`JGR|M-ROD$!AMsl&y=Y#UXn-c_Uud@bRo!hX^@P) z%)@J4^B1=z;*gMe9*(oUyv#r^Nhg^Wm&*Xm;Xoi_0gfRB7##u6oe5a$0SM3sTuX(_ z?pGwBr_1@g^cdE#g$oxtW)3@j#S;`Krt+96SzUqOb5B#ot2uM@c-F;!#jpOoG%M%@ z$osQsdC?#3&D2Di>0KV*eHx+-+OF}A5#IW`CFr-&aB=v~pUlAQ7JuaVTgBOfhlW%C zT^bqw9-P#_a;?0rn&vHl}c_%yjmx2BJ$4CA?%ARM{mpb%5PI%_b)(+Nw@tSUwX~g!6n+2zm z+?<_96}^7+BrbAAJFiF4^A654{7&<>)_UC&Yb4bRmAYp>ye-C=M>oHx)YJvxjqu|ZH`AqK0EVEFN2JBK!?kCX96q(Sof9# zk&da;5C-^mHSY`yB$zPnL&h4`1jy)a>ePV}%(Rba#{h3vi;7vmh0Azi0(_RU)^7x& zmZp|Q46tamC=W7B8F7%Yj-@jkWEko9hk8rwBMd1X%Ra(}A+YSk=+>>9@9`hL>&OF~ zwS!0e#%gB*Sb_52HLNlL;C45K9G3zX2drp4fWZWdd;G#=flb5K!`<+L{W|#jtNmK| z`+l`SK=YkDcl!R({%3xh?G|pg9iEiDe`Do)xWmukLEaK!(;FW z(tBm?O3#Mh6wRYD9^{-quqfTvDw2`~f&L5fGj9|;h)&;k_n>(Gwg7*Y;M-?n;jZl) z_0$EfOwr+@6EWMjkN@@Axpo?Gg=8ca6chxllAQ8;`fd+MTnGBk&&uB#Ge7greg|Kz z{KXpv#0|}i zw?e<&Qb{;JYf{SlaflQr}SEisx-u#iGP3ip@i3V(WS4YqzYBB0!Ga>~0 z?HH@dVmY95_jU%BnMHxXeD9l00u!MdlV>s(i7)L4M$hcu$vr;Tm~wJl^@zWuEGgze zyOKp;XBGtk!@O%2kK-L~&3ux+=BYl&%Dnh~qF*k5LRuHD1|uRYO~~J}L^^4uhvpR? z*fQ&_R5Eyw$c7QIBklCJuhY|8?QWj|t&WLXTI#z{;LYUq(k*)RESZYc2m3SqB}S{# zp|}+zV#|TjcW++;AxmKEIl0v0au^UU?#a6)RyPa`TU@?j6zd)2@QeQ(vCHOWasE+@ zJMh5idh~WgIzKtx`w`zptj^2&%ay;~J5Tav+_^g`DL*_jcJ5hv%l0X=*dA>8YRN0N z!uR>QvGDL(Haffe%~?OkPPh^V!dZf^pSUi{eVo(!t3gKYjshDdFJ#V%i$$rhqjyC| z@HdeXc2ttZ*SBW~22fHC7&bimvGrfB!ubAsDQMpoY%wfM;fGxE5B_GjT7p*IN?_hA zp-6i4VNUBd3;T$cGW<-y=yr>CUD^mmrpQH>19P9WGqQn2?}uq@(Ad#DLz8lfNPqXv z40dd6t83Xsq{)cj<-U8@ukih_wQ`jJaQawjif|RQ@%V2rkKxA!JqE>`I59KQZQr6k zqA*a(;@zA!?#O~jw@jZtqBXqI^TvY9rIh{n!Xmd;MQVW4O5q9n+F-%9NV~n06O>9+ zd%kZa^#{B*X>1^HhKIY&fg|>Yutfz0^IaLC@1E`y{^hU`wv(eg-Wntx3kh+1*7;(B zW=8h?qrO@*9=v=x+x67ZcVNp9?SXy!ZoM7O9~4R5+GIB_x$xM$IR<$tXKXS%N3@x^ zesF3m)7*vWK7G0wJXmG*jc}b?$oKcRj!b@P3Z_n(VlsBjn9RNr)>ht+6C4T;vv@7- z_T0E}V?I3f#%SEL8y?!)!Zl%5VRRdcHK4`!E-nePcxN)Nq~EzS-nH9^xHm$dmcZot zbOTCH)2VaxozpQfVM%39%>`Z8nd@(|TIamX++krSE3dSX;Y$mj-JWv5>Nvmc$sd!w zH439*V|RZyY0}+4{~YSCZaBue`0Kw%SeH$7%T4;ato0EFH+!|~R zXz{G33I;A7Trj^4Jg!qu@`?j;Tf!0X``*3~Uf)j`@Kv09j%|@@`hm-7UH0kTg#%eI zYM7(_30wDNa8wP@sN5YEI1q-vaM3C!^560ivb<_*YYWDX9Sgqy{(JD#)SrNtmlyC| zycn!lz8vh^yAMR3hy)j+FMvd`7~H#e4?NAx0y#N3;7x8GfcXZ+#lp<&QK`NRs6Y zUAbxbPqp?b7MrcB%Vx96MdcyDs*-#{4zoN;W^LuwpmFFzt(Ni{a&f2t!!Gw!ZGIqn zys&B`4^dEBY_=AnwaPyfQ)jcwH||>HA1Y{TBkQ%cPibmm`SMs`OG*B5tRK?)H`AFyE6O2-E`3VO4P_WR?LiD-aAMpfiDkSj!q7P z%rA-x;evl?(fEju!C^LS`;x2D`B1x(4bb+5nQ|A%coq9&{)cQiU+%QxhhRg#{Ms6e zkZd?Nf>>z2@g6{z!23mA(DLzvOa{jz#_(=4JFjkwF|=m`3m+C)9vr$9!(mGqU}Lv3 zG*02b!iA-BoPx$Ccu_D;L1Pm%E(r?@laEc%{d08h9N#y`s!g;h15FwD?`J^iIHmk3 zf&)aCLue_dA6^{6-ik{lq=T-a6tye$<$PpGE{%j0%9r!2?2-EAZ3IdFSJ{-eVIN+q z5Tl;*R(Y+$e|cxIF#s8w00`hQv9<-tBfWZ=%BP)u+vt6^{+&`DXMR zy1fr`V7rTh99Il_vFVUcrwb7eeRK`R&)qt&<+hQ5EzVyX=r|g*@4PWGZo7u#Yu)3M z_y3WaR+hfAwd>=Qw zVe7QQJ*ocB&VDO3d@IJtrId}J#s!=hl+lMw@00eXknz=;1h zD`4AUJz!)L*2U|`g+uf1X0+&aSQqgB%+1QsS-B+Zthz1NdMlM-By@Sc2*91Sf@jD8 z$sL)Y9f3Q;BvFR~y;%Xt`oMA}XNN8Y=CJ}^z{VQR4m}D)u>zjJ#s*G*BMQ77$O@RX z{B9WsPUF34lE+QraDkJKR=~S=3;3-jZ!_V62=n|7qii#JFu+w4=3`Uf)XCOe0C<0} z;Jm(--G;#Vf-NF5p%yrJ5B)}7fxiO%{VU;sYyDSWLALv{@wOT5h2yR*)wd~)8{X43 z=6O(PiS*)i>7n*}a<7XeGK&K7IM10g5C7oo{Kn(&9!0-i3Y7NO>IyPgo|72<;V_zZ zd$Twr*8*_By)Uvjx|N*(fa&f%P-FNuTi7rgsJSkTw8!9v0 zu>x3*Hj*X!n1l5l!TJlurRS1{x9VxBBbvq(3_Un*mvmyX#dYKJdw}IeU^(MXLOi3j zS}%%nPkdg?A88F|YrgdmfgG^@xY{Ode=BR@KVtt^kFARC9oOprx|A*PPnEuP)&vu$ zy%y@tVjvsS`WLwc_N5F*0K>Txo)}LZ3x?~1RqJm{lBUS3!`F)|s|jDXy&MX3^uh2k zy`@NW6$_|kUVhwN_Xp`CXNKBBeW1~Tbfosv@zyOtzpdTa@A>B|KJr_UM5yAf`|;8G5DjM35< zeX!!=ARK)sgh&P!junk?s+){Q{ zAI=*@dZ{CTd6%Dy_VTUsJst(i%sLB~GI<(~F-5y=vK`mT%q~Fw_H6yfgS$lNFa>iD z8=2JsV)e+ypox&OSn_ROlxd0t%SE0d&t z`-SW|xjUEKfAD}U?Y{d-tSmA2+$)>#A_n(DVo8y-z27;n?}9o=_6l#zdA@7qF|Ctp zfRow$*KWT`-e|}ixXiQ(S3V`!;&R8r(T7u;cXD{@hC zPSSuQ$gM71Nl)J9eD$kj;DY;L7GpLS7_{A0nv|H6)Fu*nRiidN^l_d1ZKRt=3{>Dr zS%NG3y4+8J{O{CUSP8~rHK*dig5Os7%l0hp00dK&900Bj6kK_mIC9+r0M-txIKn6q z#RnjQ{rwxU8nDe93_!9e5Ug_CJ@`dXK0Fus=a&wD`s|rRKk@k8gX2o~`psksCi$nw zhxGO+gMBRF67MqWHo6q2ptH+``8SNIM+5oN7@J?#10QKl(T4bLN5s1ZJrfJO;uCvc z&iPvlJWKaaH=GDAw0g0q=b^XjOngDXuS23WIP*=Mu1$4taFFWE*zO{6b8#u~7`p5P z|7ye@2ItR-A~@ImXms=dzQ*Yh{z+4PcDd!{E;a8#<=x9|yZIXb+3og_W7qZ8$fU5} zto-+M2D^)wa@sUIcH+eQ-rSzidFM`@`d7S6ebKMI4za+bW;gl@0+&Zwe%)^~$GyK` z$G#-DAAfx7@s0h90^82QHZz{*<>f6)_0+w6`PJ*!-@&Q7#;#AN_Q$*D#i6rk>4Lr4wEAc6Pc5kKseP zH@||T(EDKgW>+_(*tLOv38txl6Khm_$8+vd@I17SpL1%Y|1q~NIlwS~DEGdANwuU> z%=SyuC&x{C;}pa(W4Lb-I+=@SZyPd2U^s1zMb@Rk*BrJLOz(ZoW@9uk%(~3$+2XI` zSA`39wsY9eZELw^OTnp8YTG>uZ*KMT{WZu>11Me+1CG2mHuvrx+%6&FC=#L1faJlp z02T^x;V)d^3r0;#QwEwc(3AmHG61hbIk5P^B8ElQ$O^(FfCb&CuJZ-jwS*-dmc|x0 zi6<9gbg#<MAYL9_g zRI8EpuzyT34oq=Bou($IRK|$p(E7&f9P1$&x(=>mK5k>Gte?cITGUlqq&@5(Q;Y*s z+)t-utXP&#kqli2*Xc5f>R1j_5^q%`s?|t)*bk;8CfrY_@U4vx)<3C(+DL}3gX@Z9 z>3vuZQxdOgQCDe^_OKsJ=~z%5_mh;|2k3grwtZxSE~ltY`XTXFMWR}bv`6|QF_C<< zUg^g;QXaRFjG}D-^OaH3ABk7BsH?O{d!#=S7o88kq9KDbersHZ*anhCI&>SDr;O5N zQJutF6^Uv!(jMuL#D)3r%OSOno3w#+u^o~}wy_+hBwp2`uF@jyVLzDGga^wZiq7|> zyrOeHT?fn4`%qn3KZ&<064h#?J!LqQ;UVSe$HD53dst7IU1j|wUe%(m(jx6)T$o}U znBsnAG-%_-%5|sgoKM$PW>;B1iMJ{e)oP?YIyO|tI4~voWSc$~P;|T}<(1i0)=%P9 zE$S*Q(w;JW%J7i#s13iSr0`l#ku0{WjFLJe-l|ActC99de7Il>tX^-?r;%VqM ziHF2n6^Uv!(jMurq2nd}k$6bFszqI;McO0%k$4)qP2wT(Rz;#(jkHJlYv_1MeZ&f6!)ku3J4jeB@KUa>_uWg&et6J1mTBJP^2N^eR zf36&XU8U97r z1-%dR!7&lGKR70CMLKJ??T7W40xV4;C zegzGG4Xufy^i+Kvj>w1nqu`J&|0p=5Ft11&eQ8rpjVq{41?5*zxONa9s>>-cci~S9PX;b0C93*LF3HY=BqyCK6yPr+~F8Ix-c!KSWi)U#X96HZ-jd{59R5{aijhM@{(4k3IC9d~SYg(x>~X z&-~NrCjMdtZa+w^s&sICY*Tn|2t z<@lorGwxG@-ThOsBYFC^hwUT!sre@5>9*+gy2Rel`0E;bL*lOw>gpLxLtwAKkDi-;a1O7hwmb4y9}C2bo}bp|Gf4OP zz)iOa@uTOc;q?$lyoyPK;QDXgM)*W-Yfpp@g=fV5mRnWIl!@hs*jrF zvE5JgPhKZ}Y8&JFulvVw)I`brVENCDAKM|n4~?Fq(!T?Z{9{>qy{`P@XIbc5boe{9 z^k-UhpY(cN`KLdNLiSOiKa;|JnBrX2m4Eci6x+tMy632M>A$+?qRO6w)}?=JtGaLU zp`2hjdcCglk8LaaCLY}%U8QeEU9=aQa(dLOPU zqF>TK{oUC5JpU_-o9-LtAiN>{f2wbU4X-C03w>SJRL44qs^Yt@{Hy9)k$-wjwW)uO z?+X9&@i($l8-H|}&-Gp5A6@(4@w%!s2-#9~f&S4okUS46U~yN~@Bc?V`E3LEQw-k* zgRg+G>$o7BHn8wvk>$ZV9(nLxwqo=iTg8IzQ*dD6!h-Kp@R+bsPs^unPb3VaPv7UN zt0P%u`n5Th)})Wep_n3@2oI(;>ErKdD;ifLJJspa=YS&rJqgcQTXd+q?}7xl-RGHZUBs0@}df>FVdQ&MBb@0Al+&6z)J|ZZ4sy$Kj=5pE|=@d^weT4e7$-X~P zdIzpgPJhyjsC+)xr%Y=TEnCL*$?3g-=bg&+$?5S=0htd}^_i2sb|V_UMpd6VePV<1 zUo=wIhcwE07dBGXXHE$^L}h0hDeE(*@lO(szuJh3AZf|0D$8A>toD;y(@HflweiIr*>DqqBUukKX-Ppp~qbydrhleOI6` zP$bTre%~$7PEJWlPF45}zE1>nd=eAW5*7E2fFe32CFR}ZB!l~d5A^4zB%=X}`=g+a zB2kfu|33HGfW&C;lw_cvoCL*EchFi^Ef0VrC=`lhz4|nuQT6gnJPCnRMfF$JAW6wP zGNq)X#RGrP&%GYywU$>$G9^t$-^ZsuohUK28W8Pdu>akZR7EmEO$b+gwtRXu_}bk5 z;i-x=g^y3&5~P({ok=YHDXEFyfB?yLmruL{N9~lkip04rfB0V&*BVmE%d5kunK)KBR^4eG#IGxQTQaK)(KxnFX@i*fX=K- zLKEtQpPZU}M|qb2G_a5PSB?hKZ(FXy2rr*81R%&vpTh$to(v}Gb{F9d7!Q3jjbwHyUAb|f8@$tu?O8)AJ zq}0@!dRTNCG$4de0qRbxUPdFWl?o}*NULro>0u5i6fJ5%PnC^y6sbuy!Pmj)k;dYe znv@iz&VA<%s*A4O6U5b$}v_69KecS;YJ*Mas1 zd?t_kaDGr@VDxJuA4>ofKoSO!1&F9>j#G35XWn+(kIFzmd8>7k|#6rt*pC9JO#y$_^1^13=+}OHCYD&h^)b znG6jgcvEZhQ6M@=(!r3Tnv{SZF!QMqF%>NC#AqUe>2OB_(DQ+P z&BCv&fIA@yqj>W2j;cykR|)&Oq7M;3^C7>e5J zfvGnb$RRnkLp2d#u}Dp-R;j9O>MOI5J0WtrSK$;C2P1F?Rn;Zs8*T0cJ`Br8QAJXK zJG!Q#TJ}4Wi3`wym!pE@xxjTdipw z2$58jFZW12sZt=$E#Tro(`p4%>kF+^K*v9><({dBT9^B9QTgA!Q;!rrLEyhc0E1Qr zwPIP@3!UXb;2eYJ&hy+oN)KrzGv`o4D#&Nh!o5RWZGdWi4#ZP24oUbk4Gr{a&R5G* zg*)Vqfiv^ah*WpY!K{`-m5+6nLtm#F0C$;$AVjNrDqpTdD=A39R0HHxpH>nPQ(M$u zgjjH3rbGQO@z90ww-ppoC4P6mOV*P#cPfgb4&0+YScC@kodV=K2 zl4e55NhvbTc|e5q12MWg=M;+gc<+ue@MOUmhe10vQJJ63LZGAQa91ISPEJXTk7h?G z3S;a^R)R+*u*{R#zj(J6#H7Z=FNuzhiCzF-M!e*VtVEYBYnWuowawnZrlgp}C5IE2 z06fr#+@(~4N1sSZ#QYQp46dxR%AHnXbYeo{l7y7_1&K?d;m?5pXl6)UvI0IL5VB?- zXeD+;@r1;9urG!w0BCWV!&=WQ%q@*OUD+k_$#A<*bhMVE$Obn`t z2XOrYI)Ep{E0!cM0x5T7(*a}Au9-E6aYAx@LP|_xd_w%p!~`&Kb971#Zm7fr6i-OG zvjqw4{@jwXWdWL>usJ3M$S1~BX}p|BMe|ZNE2_>6z&S+>LyS*Mh>1z@PGK2NNvoka z>82!XNlA%Mt|mo^F{m~Ls6~T+F(3o(<7z5TIw{eBk~mZDR>~~8pm;o(AA=Yltw@*| zk3LvqaZJ!q9E5sFlepRmDVtN0!JCwr&8Q-p*;h+(bOaz6pOB=`1OWI;6p8U$5&<|N zdTz|zTCkTYO@k% zQxoedYt&AKd?moJtbCNfeC-I)jRAY_(s;Q9Dp-<|&{1PLqMN|&pUd#^zY?)Z2vzQM zQ_Nop=? zC)`L}5)+dUQ@`SngOr2?iPIJODj?bk9AXkw={m34sfvVX_;OVlbrTZe>n5ElH(#|= zp%B$A(0tQy-#~$fM*-{sc)+1?)%tGpHUo`tgJLyOLR3&dm2?@IRZHtuNvBiQbR20_ zc^^kr5unQS?O5c*b_!Mg>gik6-rtbZ>IPIGeH*M%m9L&I!wb##={2Nz$Azjqzt>F9 zuOlrXj`Fdb51^!m)}Fp4y^mApzabF{=>Vy?kkjevbcIA%q|M~_Wi_VDNX3A3DId~G z2E<9}ipq2V*K2us9{!Kv+tvnxSmKZB;Xs2;U;9c|s@=zM)Dh5v-JBAc%HXrh#Cr5M?U1 z38VvrNLMz8@3^Wsb-GMKs8UQNgl<=gF%Z%M7HTmELXAOYWpgAEYy|L9qkxDkV(A)b zMkr2&KHdX?0JRh#4FpUz(?Fo9lIUC=QvgA_mHsdVD$&KG>ghN5MY;^> zN_3faRnrX64Ea=n0S2fNd__7|BduhK`U#g;Cvd~{Yo^Ppm5)Q(Od|u5n)pfW*T5eP zsnWhOPAjF6Yl-8u20$rUi7;1(U26dk`t7KgN1nVO&y^#dx@03~c< z@mEjR|Ma)sQySY^5lIf1XTI<5eSYI2q!_w3s9zJXdc_NyT#_rD zOT_;$60%pV26+-& z!H4F4k2btYqJTbswrU4y~ak3Gv zTq->lX+W(A!0vg}enS`em~M^H&RAT}FkB9mSKiTXju?oj8fVz?eo&z_DO zXJp+b7f@P%8)_?t%NGoK?}-DoxlzBw?QRUpl4BEWdYv(Hw}9el_jDRFfxHIN=>5` zAH7*x4UoIP7M!?=lB-R73zvw8OIPW6(@sFUbrosq{vOYM_#5gZ_j^q&H8E7*%W@~g zDctNtOc&xL;%dYlhym%bw`0pV2Hc9RFuNgcm{o{dx~If#tuvTXFA$;;x(N$43p6W( zvH)e5!mO*&0#VU;rzq2^fNggp0A0fjokt6B7@QPX&h-)95LI$+j;}as4sj4_yn%2_ z7yQNTUz2l{^r2dKI{B{@V2&tnKt_d9WLd6Klwt?kt9T~Kd1Kj0%vo4w`6Abl$U}zG z$kFC;COM8@LSR#;=_o74ijc-;K@3)LQV#slsr=9Zi=FD>3!OrtL@*{gHBMU=o*1~M ziJsvXkee;cd|n=a1jXSNH^4+CJrvKc)d9>Pj#-Gi5f_Lb5c6<CP;Ar4H% z8!%V8;4g0Pjn7KzXh{qKOOm*zXUJk*WFT)W&8Lt{X|uelr<5euMN@q`xCQ z$M4D5Wh+@&e@s@6YstCYN4Q@{*3O@kgY#$P?EVqixve7ykM-2i_Y<&d6f zX6n)Va|#MtPhGoyL;d<~q@KODQ;z{@G;q*&H0ZhQH01fO@%~#H7W^Fr2d7b3_!ZVQTGMNQNGTWM#FRY#eu!gX1o=D+l*E3dq@` zh^%~(_A4ZFuOqlGA$$L$)ZVj*JbVg4k3)z@NXPaxwQxC0hMs51s`FWL>2iQNcHcvt zduNh+mu%|X^#D0_DI%wCN6Ed%LGlkgOdh?9$!9`nO3AU? zIr8jxo;nXXMZQDIse7+I)PHCe4GYSouH6c$ci&>_+WjbX?_END`?93% z?l|=fE}?!SkI}H<$0>O9J{k~yn1aWY(3tUiX!5i@q?nUUqsJeiaWhM3=A0wc<%QGK zXXt6_9)#CBAWq7QKCy-buZPYXvP| zb)8myaD`Gox=w4>UZyWMUZt-$T%$E#{79dE{UdGs?q}Mz>laGj^#f(>`;~GJ-k`$6 zztM$@zssE-e_2mAga!&cP82xY&)>i2ut$cGe~7iYsdez^=N<_LM?y?>yaK$N>)HkP zcmxO>3ATS@%Z@EuHox6Y*FEr|BTzcd`|X`OcWl}G-_*Cgb=@C21;))>o0++D$7aA! zP4d|0A->e@Wyp~64?>f5`x`Dp)pDak8VOxJas@h}mX zvt>(e=B^9||6X$Piuv;=>jpnWJy8Df_N=VTT`Yc^L4LrW?`k*tfe~OtT~)2$mXVva zD`O{mpA!7MNxI`+cu)wKj;f=kg_)UIU_XmLvmec$Kh4$Azm8J%ecdIvE@A#Ca~Igp z;J-Z)y&*nkRR+%eUF|Jxvm4%tPOn$JRrGEv(kDBN8V6^bK(c`T9)&(EZ&+sAr%>FnAA2rFY4z%xHsq*b7 zA>%^oB7ga-fWLF+PKo^z{Q*Ae#Rnk(=R!s)Lh2I#E8ss%zs!Cne{2*m(5(yadJy0p zg<_OvUEQDNF#CDzW%4hD`~iCSH2VhtUxDV2u7mwV3lE_8ZQp_3Cv`utKPo&b`~kp! z^<}`XyBX`UGST}stCTN`f7G;a`?~m6H~rE4QQq}{pPq^4Z(;2tcmF7aaM!vE)`5Xy zPKaXE*jaVtfMV(@In44*T1TOHp~ebHEL=-T5*02w;$vOd=@`QA3}TUK6PS# z*9;-!LllaM^?+agPVUa_AirdL%%3+6@(%*o+T+lmzYylk2K8SV^L{<5NY7%^>pgY% z1N87Hn`ZSuz4ppC%^9zVRfN||h|h1^xm~UO=A-@0|8V=i#DI{wikC;lj<25*e>HDA z$j`lhsl@(yEC80xf@^PHU2k5Ut9T_gKD?eJOh2H457R?tKM>Hqe*%21h+GsI5izEo z@XOcaqW!ADS7JXC;QohzkhzN@76JYTb* z()LsmpBWHlc^^t>_SC3&NZ-hNYCf!h{8h5;s{udUM%(;e=i*<@nU}!akC=0BbI6}Q z$pis-@R77ncqIOXhg&oYIaC{+Yksbnjt_$tjT{+P&%Up&W$%HsWFGyP@ahoO#%_!{ zM}2O_O`RJb9~m(+a_YTsU#j`F{L~~h0^EEifQ`0w&-%bs=9xWlUP3H1PekOsHXjvy zoRz#33P7en6l(!sV0JG`;LADF`Ma!$(8#H8-UHUktmk*_NK(R=8_#SAYtyVw3t9!L zY~1uXG(R#TH0nN@Pqb$Ldr4?N%nwNgfdU|aO%v<-_JNSe^U-{OkDU6s3a5LzF3d?* zBA}8$nFICnhK!s1N@7B6WMpXM+?%nt)I54eJ3$P^C zM-6^3X7UPdet2lawELw#qp~Jvtt=HyngrM3mi}rqWG^u`Dk3~0eCdCxw&~td z3v=F1QW78{9JPf<0s$Cx_`|x5i|2)fhfCn4_QNCM zr8~NN&G?77g7=BB@lg?BVd1ZAs5#R;JuP3qCy6-_3i`7EU_u@@uYE0EVTt(M^TNU+ z!saVCYuppKJ2RKB-^C&j3JjP5pnu%_`S!Xs86y&Sv_3o{A~bB?{cE18NSxobXEDnj zvj9Yhnl~?Q**x7EIzfonD=Q&;03Q|>8aeMlP+!92{H|R~88#DuIWRA7>59cV_SMJY z5c`D^cu0O|MA*E)Ec=yIDA=%To{9mXG68^qW7QdLh}TjEpMWtJxJEq~<|}b1*tJK4 z0^q>16)R@yy8Bh4cq~`~pBNvxC@d7spZmb5FSB5M);t@D1)xJXOTda1zPgq6;E`bP z9!j4rj);*XLmwpdB?QXX?OUoA0U)q+S@H@mU2CNp7$}2>!LulAWKd9O)VNB@JfOQD z*5)i{3AB-f5IPYQfEtjN=K`(0_#0}e^`Rq!Lc^wRd_Yh&s`=$VIZ2EF;6ooW3zjXl z*9{&_G}gcq;2Apl{m7t^p^IPDDEHuQF&aX)Z14{lfC88yGy?)5Z9V6)xe*l+83yn{ zq0|40(Q!9)lXBh$`4Mcw!fe8)0flMWI>9<)qGA)`quADtkeL4fdww-+Ud>q>7OKxO z00dx@!#!?k6BdQG!`eZ&4+;tz88-XDcD*Vne3<>kB#8hvpp!0d3P`~w0w`dllk~j|Jt*{z2den)#J=FOjnhJbff9$XP>3V~Hyt5# z=HDfIYD})YowJw`kTH<2GVq`v{b?_sRcHL$ZWeBQ-6m9@Ng)4ILe~fQS2q1^P&F!k zdDlFUJV-);fdexBvF!aNb6*2O9k)}bF*tqhZ%WX7u~_`~_53ObeF>Rk&8pQg*j0&2Oz$-6E@RmG_cwtaTH8 zjB#oVDpAmHr1Q5U(0^Q;)}bRY%xEB>6oMfA)=y}UzU$QVUfNk>UNoM~D-KmLP*S0h zcF52g3qFvCea5xbk65$_9!(_zDjAfaBc5evqu>$sDT3L1VEq; z_r!f7*JDmoE0`HTAcEIZloU|)gGx#?e)4`C^>raN;#GIMs6-r8!w5(VIxw<90`3N| zMIz~01y%h%dScTt^D(;t1`+~H1SSE7-O#W%US9upxS9Y#K}{N)-{)eH z8eY|#4;I>ay^`|oyP61$#HtDq0Qe*Yy}I#>C=~*DX42U70V;wKAG+Et-uzwKDj5NG zDzgysy240UoXI@qtY5cbo-`sbJ4TMwZ`}5QDT38+HlMj==l1R2tx_VuLLegm0z{_B z=2rQ_O>c*@ILIOBskR{xq#q7k=j{3!@5$M|6%=3$_^c>30`W@lAi( zAOQHlAOjR&1Xjx3FfnoKoz~X*h57Gc$!!s!C$3DKrqed~J{B#}kfZ1Ow)>#y>eZ`7 zfL~Z#1PbzT@O_vdXz{RV8UtC;R zoS&bIy-B;bZ%s?%POyE|-kQPVyR4TBbJH07s#UAL+x$jzyO4Vt5Kmm`*=6H}YnQL# zKO?|000cmR+}upaAP`u!Dr4o9+Q8%anr+3q)81W`mbU%7?K{@$HXp6wr@BiqepPbi zOScUdE?mA0=n@HvK>$zy1ONh=5COnX%c$cE@N0953U?#l_U$_}GIw@v?p|MQeEPiG z=Ld@}UcD+IAmMOPrhrU?H;m2*gU^_!|Uf84Cd%Gty4B?JnKE);7b zz@tD`eqnmmLiI^qn^XKVV*ok6x~UaNP|F1A=FOa}jS_q%1%Lo(Z~;w60Qk(}%uDqF zct@VSuU-2YY`A*$+O-RPL4uk`q?>>IrbZxJ5&)wd zf<2%B>jCZu_)~nX@cKP~swL}BAANfb7@)@d&zm>59$kZFbPFUXmJnbL00HI#^e{eX zejwqK^a949Fb^YweXxHGVsP{3@4w_!VgTS36&G$i5a3cJ1>5#s1Q!Z(*SqPu2hVun zj++1Y?f09%6lL!L0gA3w{PJ_fli%a$Q>Bm{Pp*nzsjMa z;>VkJy#MPDept6=+uow9MR{2Pj=|&Z+#Gc4_g{bE@Y~-3T#0`9x{qF4^X)ptoHchd zr2cwa8)|5vKm!FDDDaq5Ksr3>o7xEydaJ*5q^!z%~jg;?W z`HExGBub;cSSfi&y5S^Zi7x5NlTFi=f?0;cuJ}b94xHjpp-ig|Fh!c*G@L{%QAbIk zrfMm}1L<^GwG>Nd#^O97b$0nw5zTZQgj7>4fF&wwOQp(?mUyD911zYLW`JfI_1{K1 zKqJkaDpn)S?=_MV!kTHWUo%}+t$ZBPW*Qlg)Wk<>zfyWQmt?4Gw6BcwYqUR((;5J! zWF^8}-4hxOV(hdu0G1)$a1t?}0UW@85Mh7KkxRRE`&>H*e@tzOd8FdhxWAHO=P%>bc}E{+D}iI6w;IC8T5>GCN;6x zPtVxwCtdqoYHPEL4DEJPE5|G{cGyL&ZT8|kuUs<3xm|iV-%H>90P^P}e<3w_E}*vVC1lk8D4F_{lC9HjvOqo7Zkc4$KARjm zV|IP0tcXP=!UJI{Qa0>+@(i_gIYZ4|u2CEJvt;CPmQ20RQrq^I$jt2$**Kji8;2{>xnE9xXUL-C z6|(TV2>x6rJO5wFxl0~(?v{xwpZ`@t?YkZ%x2{Fx-J^io_vZ7zaPC+4QtAA!P6Llq zr@<%5r5oxDyo__eE>Va6N4~M&h9!wLq;B^ z&~b<8h0&!Hg0sHD$7E2{gj||7YZv%+n8L@FP}HPj)OFAWobM%{_0=ut9Q7P|j{1!{ zi}SuNQs1!4G<4Ky8WDDi28UdtzCl0Iz{qnnFru6WjlM)f$Ku?t(WmK!31?^o&i@)R z7SG09p%-4fj5EM4Q|OG#G-~=48W#C04STTyQBc^7pJ~F>%Qyq<9KAT>481t_JVng9 zigUm&(X`p8XvUn=H20NrG=1JB3V-Q3ji31&O?vq{jh_7{y%Lv0bK}m@%mtU}<<~CK z+{IUDa@>zJePIR7PW**lUQ$8PiGR|9h5wT^==YuUty++G%U6FE$R;|87uf6>fz46{pv>-{) z8_756t@nSX_g7a?@&`Xs>RLgmpWdW(U!0}2|Gh$M)?cUW1HV#s!7Vy;_*W`9ag$0< z-DGvE(gu&&)v&F_Jz#YF^^KpzH>-bvwcFD^SvuOdz6CzswQa-FC5yuEmfu_B<&LZ^ zpDbN8X~JEa;M%%M{%<&cu%5=VYPa)!G#-4leZ$hF6M{!QtMRPr?c|x7>GeQ=>7?M` zTF;6oeK}k+|Ced&mM)qQ92}1OvQOE~|CzBW~#%cW@#Y zm=HX0;J^`KcgjSk*r~HlRL@Tb76JW%1N--Kto~}EVrpddXGpJ`5H(_8{}KIR|5XWN z;)czt@<5sRZRLb0G+@NQ##P>$z7;ZTVU;JU#HlxfqtJp8eXUhbaBctAs1eZ`Y0cZB z`2GWXa)HVwxGfqre3q|fCe8bOiw5@SF(M>bO;oS9;zka;%Ub-t2|arB2%a=r$!4!* z%ZEQ#8#WT4%n99lj0j$|2u3rEmqp8m4<1%4Hd29o!GYaSVDytj?OutS^<4My(&O6y z9E|Yq5f;2C+_=@K*b##RYb1S@(q|U=cO5t|IBeALA%p#fcdqiT#>CY(yZU$Q+M`ET zfB#`0)R?3C!+1Y`DGYY6{-)-1zwS~2oxU}{uJ+U=pnITPe-o=}uWCp-^%^#1@ZiAi zegNUu#H@xKRUVm)dTHv^DTBKN`t|Tf3GG%@-d0aIj9Kzl+?;7spC8<1WWjp_{Q|q| zNSv;oPfnM(Z%qGs#j@qm)22>|#Ut>#%kzV^oNLZap5Goil$Ew|#iF?A8LvutuD&^J z%Jh-X*ws{^# z3?Toc>bdfICFk&w!>N@xo&IG@M#i4v@{1SCkCY#)Y3cXu#UFlH(^B25|JW-PC@wE9 zuPCTixiVSwv)uYuP7vD#T!-eHMU#&UZIQzr3ReCCI{O8TXdkQc8{9Da=l}|4p zIrMH@m2SHI`|mtCt|MGN`%xV^9>8mPQl*-DR$d!^$KX-?j)At!QRs7ZXoNeC2+fSv z;V}3e^t93UWQMt=SLct(+-Vz`JL6nvkMF6Y|F_gR@I&(J{ylZ=@g5BrltKdsC)0C7 zk|-=JnSw)B(uk4oV_vy}#*JG+VJ zWM@*FcG=X*`2em5$iNBDUGvD)eHZ4PdD6VIsU7B>=EW#qOpPs$QWMKkde)(o+BhAg z)~*LJ_dG=Ut~~$bd1o=spw5@(p(Z#h+Q9uV8G99BZg?1T!y}~Uc@lLVC9@94$*j{c zviHg($IjVg@0UmJh!#8t^*Km3ensSrd8l*egJd6Ym@GSqZJTE;*E!?k?uH$vmarli|wf~6> zJ62$RdYSA3PT~CP^W+e4fgA(M$=v-{vhu%9mj1tyTi`D0(Bl9(1mdh~oJH;2?HJ~s zrR3WC1m>qjaQ@Ui9e z-1sXLJOT4h#1WG&QpmIm6gKlJ4V`dITaovbHX&Nnl^Lw0AT}tnMSW4@^%B1)=Fb`dJ zO*)(U^<|f6G3KGKCtsyER$is$$(L|;^^X*vd>!-CU+MLg*J*Le4O*Uhosw7oOv_f^ zr2l?;l|K988h!EQ5A@mBztHZS+f-0|_c225<#+ylK=V|yk3u!4UDe@arfoyzPxCn zx;^<>!os0LmBzH{;d^WvDZ}Rp3;hRGLtu88>MgbazcsYmpy%Q7uMCm1HRo)*77p_7 z8mL$K+B9ZpWde7p-MS6xTB)2Z;-*$JK;G!)KWM;H$}-l=r@d39I1>0dsIEcEiR&u^ zf~vo!tFLwR37)`gDtdE9pVfD~$AOwo{)-~@$oiETy<|JDdY(~EoyTe$jG5+M+d01< zb@1{Z)ZM*%^@8ej7bmADo^V&0H|oc#n-=bP?NoJQrh12~?_>{mCxk{CgsgmRJWnyH zmxsrKQBDqx+f+VQ-dUz@S@Y)HNmD?#cfCEkSDWD%ugcHe`Bl>LxMa?Le8x*JtLI|; z!0znjbJ=^-*M0Inrx3ngySCEfTev&-!s(OevU9$x+#z%(BWGoEId4h9x7)KzOS20; zkkiV)Cog9!MZRL&7u&M3&mF7sn&|4q@?>4<+4VDfPuIAa@>2RUZL5{K_oQs6JubgP zBiku~n$s6eJH>1hY=G_5G2m0Oa{nH`L9rI`GwRs&I~onXCw81CBpGC6d; zPJM^x(U7nM7_SRyXjnc4M;*dgdYE3Ewv#5$-cOTe=Ti8jlhkd*Md}rNow|(pg$6~Q zr@oOF@%s>0;R7ziSX)lRCtjnVDZgOs{f#EhK21|%$|!2)HJUK%5{*~$P8S|0Bh6e6s>$>n)nI{_Re%%UMy6QK2ZN=~Sd7<01 z@`LmA&WFEH3gXHS|Df$VRpZCK_nC$g50?V>XQzZlRU5OFNY5DiLR<~_&!6=CfU0JS zticyg7}8li>F087Tgs)!JlCncW<9->iD?7ddo-zh(Z9dyeu$fEd-c$y*G=`9mUVLQ zR1f|=HQZ0L+BQy)!A_~#m1($G=>f85vuu|A}n2oVrUxFrDK)HC}Gv!`&pj= zr)rP!J4qH+E>2bp?s!hN22Yr%ERM>zt!>Rrj0_r886WYs#qci9W+O(JnkXllasmCR z6C;Op8AILF)b#?PJg zX1tVH{_~bXb_^xHw0xn)W85Zhmm#uA=m8e{F!(kmUmO;kV@-dHbnI)%C6WsEC47c3(qFRWQ&4%nes_t4O&gEVI9ZkmocTFl&C6g36u z8TmAJ+F|JQBAPJ!81)))hPniu#Tw!j%-MdSp)cN~$ync;jyU(#Z4{e$T$)GC!F*}? zikqo!==T=?3)j4N86gM|$Vun^hUvkZPd7zmNhok7FJVRhsJFp{h~u z<6)&5W?VR9cbnEK^Vn1>=-5iBTP-`u71=bG^p2K=oFr=59K(yVu__5W*Qkk(iRM_) z=2?Ba%GcOF)$D1r%CwfDfrZ;MDyaV69lh-F(pDZFT)TDglUI|vw&Nl_ItTJa3ISDy z1L+Y|?*sguK64q4wx*($A2s}Kpg;o!8Yu7=D8R~#O-(i`StoO34;ovn)eT@gY6$-# z3NVk^LC4NY9@cmW_CRz+)0LFz;E%vpw$Lw(aBvCZ-=`nwouc&J5Ai^glUzdb8feyI{m2 zh}{u+ZxQQ)YAXtO(h&Yh6j1Trv1Q9)QKn{F&Ka9z2@|vLgsJ(L!qnnRVP>&Kn3`q^ z6VuG!4UJw~kH(Ea?2X9d0?R;y9sm*kp@D5Y2ScOy*YTU{DJqU|rA$k?jMv7aHtB5aAyd*w(W)G)`QM-<-g`E?M9_Wea zjHveS{WA%tUq17(}drkVliy|Ir03s3t~{zIq?6i=oxZaba~;F z@O!>gcn>%%TsnO#%YY5bz-PSfKMXMdk>?96PYvOpL4nqmR*`)zEOT#p1nd@p&m9sY zCY=|^!p8&`vw|9?G)ht z!M-)tm5-{gwCL4$dy2bPk?>YGg^nraBKI5VYQSyK2g!2;r`@;6)u|IIwY2o`^neZA= zD%^V?7cM=H3CFHSgnbu`1HQXq3#7sh$PfkwFRw;JSO+*DDt7=r^rk)T0NF<7#Yf(w z!t$q_4hQ8kg{0}%RZ2b;Opu3yle!H69Y**Dk_s#1WrS=(AzE?Nyg z$_?E6A(|sTR9$KB@J;7{E`>)11)YYicNu;ElEiwcd1oe^Cz_WKPvDZB@s z6drxh_o4e8yBw8y?|)d>_#F~_6R+_smsxxKtxN#2A>d!pbYFIHFt0b zA7f_z;V7C1*_CGfU{0~1T zdhxs;{O=6@bj7Cbxbn;F>cnAG<}rCyB_Cxpc zyq|49p7-NhBx&C7``k&$~$n&D_sMDf5`o2HU`vybz_dOxn^*n~LAN&uH`@W?w_x&P) zJ^RAk>wvJZTaEs|6K#9*Gc>3Zq7mXlmFuK|26M9wc9VO?Dk^~1>>dZ zjvw*d9`T{u$vu1LFZS+qM2wtvSwzgdj4|MnTK7LcMmg^vg?Zm__W6~Gj~9CV z->K_SVF&(m-{*dB;aw!mIu;63MEed{C$QRx^?|QT&@LX^Oc7c4{Xd5`ef!6TTUzD{ z3)@VrqvZ$-tF7Swx;-EY&;QsD^H4*tJ_i$he2<7x;J>mZXEZ1f@uAx`50#L0 z17qHr4;Wl@)6g&4u>)3qwi1SzJF2j`3}X{ z&$eG59{Vvj2pC!hpD%oV{Z9z@J|$BB$G6cE|5^8&bu5zlJ@ekU!$D#0xd-!r4~4PG z-dku}7j8S^L$z%I?{Nw(74vp1G&ar$P4b0>eIdri9F^_&NXC99PDk(j*IeC-W!oR) zzsl!31iF9FXrA|aDC>QyLAz$yAS;5 zG2f&EWE#9T@+=T09=XEGajlB~yg$ea@&DBa(7J<9La+sRZfL}PA2c$~6P8xr3uDvI zGeMU}Ha5Dn%bV8G`|uxQXQA&;QI7rN%CX*yc^~HeJ>m1~Caw3v?*qS|hvf5@Z9n^f zL(uRQNRgLyyu{Mqk= z^3&)7Gw%(hctBV?t;PH{Pc&}aY#OZrzWZ9X0l>Wcv-1*8AA!&+Gl{_c?_% zAK3ojzt?~hvhCj;V}F;!!pwkgu;1|(O zUf=kC^8vBX)4|fZ;Fg0+zA&-K6XxjqCT97<(PamGVJ0NBl~zB%W;Qom@~DwOAa zkF-y~_VeiMSNvHYtm%%NdPSP^OFmz$`Sjv7AC>KgvA+ZO?*`jXTJwYLZ|7eOpD*lL z@Sp8|=0Ep)RkUcg0egnASJ>>M{b(oKfd5Z6fS#Shw4r9^`NG;h8*^dweYX8A4+
    +oNB)4E|&6XP>X+^T%E<$@as357_>^-@{e%`?BqS2!4O| z`4&R|AC&mdK0e!y2Qk+>C>*>F-{v`=iN`Tv<(i3ovKc=C33J4U z?(eUy@qT_qvpRG*B*xFVD*A?FuOH_9JoftyJyp5i2mI%~eokHGvELfDzXkffDcWhw zwjb+%W#5-|0Q}odn}xBt><4b#xM>LBcR~EO?hS8&w%I#4<^62q347S75PPE!{b`B0 zUn}RMqJ;y-M05B>%@SrI-(xin+B@WV4jOX&?D*+C_bV4Yq`h9)@9{kIUtaTd?ZvkL z5zPHnwja;^l>AqY{VLs$Gh_uv{dSq6wc$JPcYFsO@cv%3oBbWUCyd9wf74um$24=# zjvGFM-n~Eckn~+3w?SY9BjaSf74JKJEh>KVs$; z^#60%>j%FN_WJT(PxaUj-S2?Cp0<9lW7zgb-^Y2slFyHAKNbJ^D#?Irt}t-eD2&Xp zAH*onPl#rOw2{%T-3HZ(OGIncxu^L)tt(>5idiPcHO6QZ%%VbRPU zb0vpNVQsUC$HB*PKP20Mz4{!xJ~`&1=sl_&{O7U1Oxo|`-Wz*9c+J1tVcGVB?q~i> zwtp@BSIa=VEYaEs`+_aMg6`XN7VRH`$o>HKeLOZ}AaJ?g&>97uEUj~Yw`!j)p0zzB znpl>B_od+dQQRLAhHMML?n6F4GvSe}_0*?vF9aP=88G;S2%mXXbQyjYKL0XlzYl(w z31h#!?!$gx9{VjjDf>Uq{j2GJnfFQ^z+-{qR(waAiZNi1Xw!De+rXs{Vmri#zUQev zbhw8+%u8!`&s_)Y-42L0&c#C8nt6|CSt9YjsU7sCTb8i4-E{$ZAB#C(ZS7+_V8Eb~ zOA}|Y4NxwP{q3wtoOCm z8_*e*KJ-0a^=XJ^o|&`DhIZ+8?Dm-GYohaWXQlq%uKRK5e(d#z-;epvdp*s;e^c;Z z-S;J)GvBN6p83zwIbF0eOok1-9rReS4KUd!#Ct<|Jmj^Ke^Ow4^_%HBb}})|yKU1k zTeNgKDxR@B4gRb8K5RgY1-9+?3LD$ZE6D#SzVEm%nvMuLQ8;!o)_@}}!|!_%c0cy| zOZ)w>=L7rwEIY}2{fssGekI>)=6_q)9HD3Tl`u404gT-{Q(N0{9FXgVXphKqr+-qA z)^;46_y6GJl_QMX9}+E`Pm8DRPC@^(%_sMLJy+PrrU$SWZW^zFKK6ZI#ekVF9WvldfV6I4Svl_&YBf{>}sZHM&&JiL!C<33U%H$KDVA=7ZOLdEHO;{ixRb z>dk-1M_ZS@qO~b}f)@V;eWd-tBLGk}4m{320iNfxt>SKOk$cOz(>{Fba75_2pAjux zPKjm?$I}7%fhx)B&s`9CwJ8`s^3P8X?XT1F}30_#&DkKCbISJXdwLbJ%mm z#S8N}pJHL?d0Mn_JB|L&eg7!XfIrzZC7 zU2;2g`Xy;D;0zy-T>#dz*#Cp?{n-C!h`G4wcz&Nmy_lVza)jDD^5Mf%i zN96wUxcP=zFWI$o`(~#j=Cby_`B?WX69%4VMH|;rq3cir{>!}AwJ#8kunC=9_MS%> z9@GBuAtdxrgks;Y6C(T69+$vlx3#^)8?Rbg=Li?SZ1_J;2$POygn>tyXz6?$y8noH z+PVlbfHfZY!g$TUWvh-ZDEGMPvU{d&_a4W7njCW;-+`UPHvst7JD?D@AinkRMw`9x zT?6I<_zgg54N#>ED#wIMzN`4p*S3zkgl-$24{XLbu(l9L4MpVd#dwYIaj==#H)XD` z|NQeNCI>{j&Kbhi_bBw<8DZ>o3Vk28pVJZed<((<16b$F7Y^-ngm{|V8$-7)C? zBG`KcSmVhTmfRQM4?-Dp#DBxu2AWYBrc5iF*rWHc+fg&vFL(rJKNU;oepvYysPzEL zfNCEA^Sx?BpLbP8?*DEDq7A-oKfZ1EKP4I$kEButH25#cL4hO#ZJqas zX06|r_6wSrZvP2{3qtIP$YUt)m3Wwb0k%EaZfj>_x2@FCeYe2x(P6)9sj%@s4WD-@ z#<>!-s~GG22gS4CeJdyI=>`p~tn>arxqsW<1~jQ^z<#l#V<(@&K7nJ{7gi+6fKBHD z$N=o(j<5yT9)t|&E9ZqQ1L_FAw`s=_ymw{(AH@1l0p^71@D1{u@EgpXq%&oCjfnRP zv46N#RSf>N6w4XQo3pLm*L&=oGK5oS*!uy;g7HzOs0Ov>DHZWND84zN>fFC07nRyuY zAlqz?HntypVr8>OIQwP_2Y;M%5eU8C=_LAo3C6ZVkliBmeR<4h*>&|R6t3>sJl|v4 z`M(G=XCHI)@j3ka)VZheZRjEF55YLVI-nE2Zm+*ah0qsRL$_Qf3{BsY`~odog(QHOgAmysG)Me9=TkiAbTBnv_?nr;KJY#r_8#wd zISGGfDdzhnkm2~zb@zJmcdld@DK%Nic zTPGd^+8>bChT5Y4w}x$u-v-8f8CUF!=g6|aGSH@-%zu6NBKVSug^7C>{KIeKJNb1O z3%;*t-1r$DSNS_)S46hW9;APed2iRIZRB`9zt+KXGkA})45farZN_wBi zeO}*jh7ZKnF7GDF{}cBx0PP18CQLfHsQ;jn+flR1gd4^IJHG;92L2mK^8ncY%zx&+ zV=ns60V%e?Rh9vzEr|ZFk1;^ve+PV1?zT&`HC_R`itWMAj{#FYON_rGb3%Mjz7^)Z zt#0!^LHw<{gXgz6%eD}ETu;H)FGIgSA=!H>-nVpu-p4$j@wUKx$HJ;Wcy?UQ{))eI zTtfAae~21ex@zd~<05?eN!S87-vYitWB3B}-Ld8iKTj*CT#5h9>~k@8s$_u20@wlQ zOKbzE_;1<~XG&pR-O}wl>=#MKHxoNx54`mqsKEZgK*R?zCs6XfH+Y|O+tK42;e`I| z*yXga34o8syA-m>{r)iYQz3XR+xyMzS*INkt~mF=yYv2B;PQW|_tEYMzK30p z@xO%w&I7>ruubi9;4{bBSCEC~kO8&_*(ady&T9y~w}khYV6Q;{=3dapCU*F(8SD39 z5AOT3l{_b4oy+UR{5|2ltgrI?p2rS*@cudc#?7DhZX1M4Kt9&A&R~vz7H3+h{Ch_s zv&9&z4obe=rnY&K-eSFPh4p=3|JCfHdX)ZYfPXwg@W>N8!p5A$c~aOn)U8)B=j zv(a+iQ>R)dsL%MT^6fb4>h=m|oo@@>!n}9xej2<#C;N6iPoUqIK;It%zuCW6fNy#7 z5Obw*%mrs1b@Jc02e2FT{$0dxM9A@7;qVa$O)P_6Ee3D%!GH95^!=tb`^7WXh|mGg z+GRs0aE-H1i*FzDtF>BvL(iyY7|JV)RAG!u)W1Z+7VQIS#zccWC1>grG_Caiq$bR>l{4e~B z`Q@UgH(g3#-h7+*lYKP&NG&;2;|avep#F9Lq~*w1r7XjvS9yyi-N zZJgx-n{Ne=J$I8eylx083JiVWcy9QZQ?Lh4N&ALc!QN|XlOuF2_oH9QGVrY3KJXvw zfEXXxPT>8-{7o^RE6U#+@Hz9Y&;cI!2DzQz9?S_K1J;`$1792moDqmB-vIMj(?7)H z0{e{I^z@@&H8$RR+s^H4;T%|iy^J#NEqu=i6Yo>d`6r})uZz7LI@SlVkL!SFVxEI5 zF@aY(51K4+-2i|83ZTMMrtoA`3_Cg2j z$8-4poO0kV$d&dHm||}k?=|N0M)>;^x1Ri)Q#g0t8|P=4Cu9DN-=#GBkmq3R8{oY| z?GRZ8cnyZ<2Ih#K28ORLH8$CE+ZMK-6V@r5x}Ak>c}|#j0`EJPVeJ9^o^`&%Vf6Wf z;Crrk(kurt8{Jb$oK$^f4|XNz5Nl1_fMJS zipHinf{gZwCKmW!AAT%z?CI>#F_Gn~LGObI_ZuRjN`}G{U3(l67S8J-11UIbKK-_# z(UOh8YZzj0ME*54*bd3UxjZD`FCa;@O|hoPXULk3JtGyZJTcE)NWNpDS`cUpM&FNCh$3q6nlJ&-BMKvNr84>Wh!3*XRw z*o6Cp0oI0%akj82_8Ob>`AV1{Si?tPiSKV)8>NW0M#(sDa<^z@@UAdvw*xu@XYO`9 zF6nxM_9d|M;M2qWt~t)*;ys%>nBz&jhporsJsD;RE$AZC4!Od?<)G-%XWJ`iX2Y2O z7kOP<@kvup40UN&bZe^Ol;}FF5OaUl0~z2!Cgz8GL{sZboS(Bt=-TZOEgf)<2xLT$ zKg414sC!S{3&zNJHwPp=uy z-j{ffxqTD-2FDX7`z5|J@1Hcyg0DJTxWm@)?{XjqcsGpswK4AjJ;xprSD#LYex87J z!vW!kz|;L02Qr}xSOyRw56@U-Vm#g>n%iMt0OX*R(_YwztP}7}Io1|pD@mp_)Ylj zJ&uixcER4mKFy+N>8K4^<+@47MTpJ=>G4KUjWPj+oafzN@a<7Q2O&&wk9Y20tFf?bz`rW_frP|2bt2es`pQ0p^EU67QIQPZ;eKjg5DTCm|D0n(Pu! zafD2$Bhvhw-*Z0B-^egskinhtDbt<82zw3P@hyAT9@*?e{MYZ@e-!+@ADE-Uc8B6@ z;#;F8lnCoi>?6vo?7K={HZo-1$~YjXN`^1;akWQo?Y@q2k!zto2|j# zyB|h9_%ghH$M%=4tNY|pI7j`4xhMN)*jCff-!=4SP5$2Pp7nvQ?QY@TC0E!xO6xkj zkElWKKX_i=YmGeL=Di%eju+_S{>3&k`~2IyKJbL`9`K)|Y_m(Uz%sxxagVa_q{&X4 z*N5LI#CffH`o6rU)B%zAgEoXmLjm5S!TWP;5xt*kVl>#;WcyG0hTn>3O}>C$=YF51 zj2isEPko?mvQg-xY^&B2lL3$Sb96@JGY1-E07Q6*f!ES`ou0q-cSG!ob-XpEI5(?h z+xNxO`fL8z-gUrLbu9f$6KNtKy=i*!sUp4GK%>m}pL6e}2@#B%Ne8cBKjfXVUs$}f-7V0H(?ze{BFpbvYuA5H&;mqWNSeco}lXZSN*>RE+`lr zCgo<4uqWIO+kw+hRn2F0rMY?IDk%g3yJ%cd2I`T2cWCD`L16q5hJOE z!RMIs`$<`R7W&y3_)(0*xL$~v+2SME$yK7s2B5ttOIlb zuq|0_Hl?`Tm>SRnEYq%4#=*5v_3$WWN?U-HKIt@XcOqb*%!LH;e5u3ZOQnoA@BXOU2&sq zh)#Ho#I&CIJ2L>wbe(kdhR<i?*@(dVRvGXTwj*shq@D6W5_ZV;W& zfW)@fOh4@b?E$?UosJ|q;~b!_@oxBkMEvtsx3NE;4qL1YYUXtRWgGx4ki}7utOZyP zD(C?7gqM+*+HApYhi!M{jL%j;rLLeRJ}@3szb9|_6Dezc03S5#aK?!33Ada;odW@V z0Br&0faZY4^v69=lh${$w)x;+?(Wyit!$5wo;mzI;!LQGcN&?s%Y_x*G+^iEOLOIKVc03<{>_u>ZsR!WUsLauIug=YbE^ z$GYa&OY+!fGW>;_Xls(DuL z=Y`Ui9HIN45sBntuQ- zIGQ6buQmqF^#ib;i0K*2hmEoUIzgIbe7%g;_x5c6e@R|AH(_D34|du=kSlEd+xcZs ztG-!?Bb`MqJ+dS?;4Q%crUQ%vdY}co7BC)E@&w=qm<|9WbRb@!1yyl?ZMoPlL)$*F z(CObS_YXK1;p!IqbP~>@4;Y&O`_U`dBb3?u$aINSuHYe9#~`dJunSVw|Ay4H*TFyS zx1a;RJXBV;n})Uy0{8-)0lc>Tuk(d08}VFVy2yNeH#hf9`?`0JD|hqwk<4trpq8Dl z3h@NHjmSYf;T*&ghc9_44!HHqBKt0x@U@YNGkDeM0Ivttap2{(K+&9K#W>jUu}_X0 zvq$LlP?-|>v8-3kU;pQ2!{_h@9Tm+NTm)*I{sD0p7l-4V<^J* zSK07KQq|f3e^g(xj^J4{O+VHV@EHR>3*rvoy^8-uzL04j>&ndmEF<|EoAjU7yU&$U z-!2yr=V=$Ybvi|UW75b!GzT#ybE$W54&n$@;y~N}5<0**;M^_iB^;>A6R6r%l?|%% z1Ikt$YXP*S-yOu*iYf0i;3(^It0kO8KJ3*gzI^I}RQM`me-3=k1NOcccLs@mk@bw= zDWG$b0P~u+s44b}RGM#wp6FlD5nOzsryubp3g41zcl*tB+15Iu20a5`;&=uST+=h+kZR&vdS4!2R>znpmD=eLe4ycmjI(`0hSBGU#r3NAI7=)@2`c_P;@)^Rj5-!h8yumoLN; z4GPbvz^QpOcw!!6%S-4$_mMf&Ww>N5sGtMAKnEBHd~g;YJOT5BRdJw_FO=Yb24b!0 zyC;(u;!;>x#*}yOwU7OQ{9y{8b=Ryr)`R~3cWJ`hRGdBG^G7U4$mTuE7aY5Z<9A~0 zIgXzde=i+2si>$IiVrfq;e7+vX>$Mkx9JPHJu=;0EBxQp zqxHNGg2%@H?&p7jEbVrYSFhhFbk2PWUz$(TBMWFsL_T6k=hKAwz=1jWpaXf8I50jJ zF{Z1p1?{ACz!f~93s9YGdQ8%%ICt=3+Pr(zV?+|p2}ok});9J`cbYqAkd9jh&ZWZVH}qB8O!vAOdENw{L>S!@ht1|-Yo0xeDw6(gM!CiE*d-j7CE>4lG=4S2EHnV z=C8`5d8-O&_VNOn^?m`(h$^6|iwkISL;+1$kdJtx5*!#hSxN_L!GSha_yGs-ge)6c zcmW66XClrz&!}Att=7BGwhsq7Mpz z2Zc0eMIp^zR!B3K7SOaM5?U}3IKXruC_ImbfgkV>&7}drfnGtCbfA3|xxfYMfF1M$ zEEn+jGZ?i2K7c0J_+(L!VVPuWfAe{VPHT8A`cn!1DNcHIN+_Sc2r-X`GM?QN^bfMJ zXFin2UfiC~jAy`KNG8r6rjt#3_$)H~7`*NtoIU-m+{E-_))&fjMKYd%Wh2&y{Zo=` zjc0yFSmXN**zxVc#cAb!gHDjM`{(38`Wi*7$)#nR3+eq$MYI$UxuK920}mFh1rDq( zr1w@92zU?pmEi3AdmWu%b}i99OyW>x@^d60poxz_yKVT&;wjs_Rgk0 z82gqUab+%Up}a5iM$)9o$y1zNVt=1FBa?qMe1Hgf?In-m6gdg+*4z%;j67&Ns6EN^v;L;EMdD#kpY zKG;@7t3N5EHJ=n!;=mTr0nmb_fF&D>By<34!Gbk~;0b^OSPz&dm=0RN{6NTi;0I>q z(THhz#5gc8s!v4{+Z&6p)L-F1L zuLrzV{hihWrb(>Bvs{W7&VAUfd!(+~Uedj=nqt^?c`P%(#>5_4(KD0pT9heCkfW8X|%cUMc*)(!`J`D&+p@D<$q@bRE8`&vzLh4p~`-k>`Eup~E+9{&Iiri|I4ZQkNdz((J_vG$S&Drbc8zZ<7T&osIPx zIIvoZ1DkpL3&8h-{{s%J-NtwzSp)dWJfUp-mxBffa-oz4$YcT@e~DaJNdu-pKNJcb zG4q0~AMQ6c7dqK|^6i52-xF?aM_u1FZG2__&wVe&p?9A<_xk%K(x#ooplwBho|}0Y zp7-1y9{b6Q^3j*v)dUESdI_!#dY^#L&N#k`?D;BE1? ztk1FCusJqk+s-ud^4UjW;TLH3(sY_IF9UVX1Yed3ot*>+W&sE0t;zxamWy>fA8R|- z0Rabi9Voz*t0AU zHYb;`SNmezgkQU$u7B$U|5Yo%7d&4OnMEJ&egJ((5&95(O^vbV_Re2jMDsvXgC@bJ z5OBcB)QG<4+8v|vRtg}#?g zA#*c8$1;Go8K760G#PlnI1mmxFo$tqr343}Hsncg0K6d6f;9p^AmIs^FJPU(%B_X8 z0^={}1bFNLJpW~~K*jhoA1Kui51pKg?-o#S=sgM?nOuN&zb*Vn(Qh`*Taaw#=YRKh z_nvoX%g#dDu(L#F zB2hEe9rp&vXu%uh3r_x)zv-9LkLj!LOK95S`_RMPr||&cI`_VS2esk=@Ro64(b`;M z99X`k0AtKNA=U#aJy<2^gLv!<@p~cg1iApsd!G9YtQU+}S0JJPf_@k>Am$45O0$6n z{)3Zf#;n9I(DpZt^C0e8LIe=w^KP~f~yY%SdnG2=#$rr`K znDe*`FuU?PUP=pO>p=w_U>pEH7{NHOQL+{+$9llPc)+ki0Lj?P=)a8i%k~BqtS$gw zfw_*glE*)MK{kyVo$_?b^kb}N{>P{BAt~S5+TARVT%Ju|9DD>Gxddw<#v8oiGQi4@ zia{rfv3>%eOPjeUo?P5_L%#ittgTN7v_M-TCo(NyzMvz(5nu%PQ~H7{*B{P1bN&fM zpDP7#l0oAz?qg@Cn#k>*1Vrdl0%J|!)g^NAVolil-6PugX$fd$NyYffaA57WV(g=2(4Y~~V!2qn`vMxov|tc` z?aWwTU;|*?;cLr^r_Vom8WaDNeu{pA`IiBHRWkNtX5k9pE91quIluv|2@~dLRPX~c zr8vNHVFYl1c|yhm2Bry&3rnFZ;A`ZD0?3XS`?VN%>DaU0cP4n@#Vhl`+ozRBL|*0n z^8ea2_q}_=eS8y22Kpz`r+bU(bI^k=dmeyau8s$c3#?Sa}i?k zsZu@tNn6lCtS=Y<@CC@$1Rea(@?3+`jkt%_Cx3hVBKG!EI(fcK;P06R@VE!hlw8Lk zuD1*a#xo9pFPy|Y;gT%u=VlAKf%%XN83&jr;4AA17#|oGuge$KdS35&-t#`-^d-y> z6w#ao&?_yupNdNVSIzl98ieWLX-g3!^~vxN$+YLoVqsliJXrIw1P_=eU|5EA;=SdW z*cMI#19MEP#x-@Pj?K_;H#6ID1|7$10_%-7m>A`FXpTIIA<3JeW0O-Js$ZY6{a=^>w3VNdVR^~!R z001Z04rn3xJZ{T|9mTX5a^%_#nK7v6Ka#gcz29h>Iz4SoN3ZzD1E4?J{7F9TJM@Sc z510llS%>jwT>)gIX%X2pWZX5xx!F!O4!hx#@;KX=Jk>W4?2LF#V4VT;2FyFl@PK87 zddtt(V@sF)a_TX~+mJ6YTBW8ES46o1NX(L&H4%J4u&4_H><^9Z~y z)N8&SKk>jX`pn~}m##_Hg9Aq&K@XfMP_Y)wmEgdng;~OSFavvHJm;4~-roe7 zch^@BX~$>K39id2|8!5*-WpAA%+}Ha^B1Od8#X-Y+TdX+<&&qU)2j7(^y&VGf{e)f zrff^gd*y@2-y!!7-y;Sh+n5}L-RXJo2gmaC^ro^NneC5xU$Fx~#v3$9Uc7kq$(ds( z9@EvBGCFm>l)gIr2)tVk_Glp|fCh}kS`aGb1DMvYgY2?%-$VN1z(e}#-~-yetAI9t zlvloYU*53|o8x(HYD^92fu-+fYEPP+y1hrwJ2}7wnldAumV>wc=(7^&)W91;zdR8- zlObWSLuteDP`4u{%>m%SIpD!Bc}B*|SL1VS0rmhRK!fGP|9}>pJoEU$&%ZpP^OsBM z%%w8=`Q#Hi^2-xCbnG$s1i(*^=@4Ikd`O?~E23SW6_oG$rttpP-xYjw;84M6e77}iy4|)9tCeyHyDHIZRk0O?V)(ZP6#o)sV1>1?XosYo=`8(zfpgXwm z3^s^2Ei4br`!iMezvB<)r`&t`&H2kuo_v4w0UbP4Lf`(oguXdg3@9o8_TR-%4<9Xw z|K{HXUwrv>e&qH~v)I0^F}3-*V>$dT*gG;0VgOX_A;AFBw zyfS--o6o(x6AA_oy}P?Zr&SHs4ZNkQHx~PrdSLFn`(0m{)$*w#RQ>aYyj; zRrA~*(tNSdQOHXNAXVttn)xV^YyhH#fk0k508v6dx*{(r2YKlLNb;$&e0gO)lB@Sz zQjcQ%?!);qNxrNyFP7XENjkV#a(Ry5g$ATbUaM$ebY)&>P_%U1@w~L+TpUr9G%u@W zw4?#$vSuOA4R|igry?K8)sy0(w8F)*ytKjPcHH{f#gDytqo9%d47?LcYrT+(A{pFVw$E{Uq(JEH9Ox zuNV$l|M|!s5Q?kvK}mO1eo#_eWrL!H;wn2NN|Kk2ue7*|4+_1ljEAHjOy$Qlqbpj3 z|M2nDiXP*v$OmspdRRI*xJX(k8N5omi5G>RqNE?dRd_X8(jrN1Fc@eB4~e8Wbf)wJ zlE$HG{2+c$#YIwe$t9YzLeuac9*g3vP?J=l1wx(+mKG@Fg|U*O@y}$O#1_3PrV*ql(krI(8imk~T(?6sK6dmP6 zs(dDhN9`ZAx2vk+zr@V^n;Z+9Lr-;EEV-bdpu={|4Yp1BD+WqOCu~joZprW+olV_G zq?1RN82AITnhD4p-eoS?`(x zG{{c9bMLsg;8~Ao)bt$c8+@O<2d7fYp2_ePeTQsaewqz(G!FhPhQeN}*Qj*(vPmK5u6N+i?k?H3iy=e9)mKp-`(SzN$mR7q~Lqndx{=0w%O~`~Ftb5e9UlKWXxlNWG;>o;y99h^Nc`h&4jL#*# z)nsEGGS9)egfyE^{;<9uvbNmrF>quqjfP)=0ps8&a!49{NhOlKZvuS&#=@^`Jek=a zCwY-pr}~!pI?t)7s%yEr$2<~SrjxR=+ravk;q07X7Z7w$@QcE@-wC+y-s>*ebwa&8 zZ<2A_I5KlU%o;ge_8;-qlA-a`C>w`-5?h>jEHAIDU*8Ye+uzXZACOWwbPD^(xlbMa zQ>bMR;Jx=PGHVOmZxu@xE|)NeJHEB^ASx;*_BQs{pISS>pQFLb@9SH4*>hcb-Z?yM zGW(`XhtDU(q3?bh@k-*zv`q~BL*67)*DIveJoFnpUoV;-s%lWKK%=QSh>ERT}1lI7^v{YK6AEbYF!+}x#*6hL!~?Jqo3QdHNi`AkFdfupZ|&%W5K zJ4$fh(ES?fEd|CSr}LzzyW$4Qp$6H^SFMXdo zwYl=x!aI*N9PT2P!adT{3;t6!#5F51dhCsrodc4UvZ~YuW4@c=|$Hrx$tkCj2L)vByN3=bX)Y| zbKh?z1%;$v^5_+dHQ*}788Mcf0f?ES>lRCf7zb0EUoaPXe}s>}k~cLpS@WYa{PS9N zOhf#(Skh~m2A_AIa{J#}3J=d{F>+jTvU9gs)cp!++5;TmhuInPqICjUfHyU_IZ92H z-RGhb8g*4f&tTEFu3UF-_9q?>zw+^9+xljynyQ(&u6N$l{c+=xO-F>J+_Uq!iP&Tp zNzLXG+HeJP`Uc`2B$7j?n}{#4|A~@@6VOby_^3=j7TyYIWFa{8P)}k8K_}i$_Bo3-EWWx@nWppV;-xknwY$s zT37$dgwPaiwBd?*yK9Jjcbb~no<|!lk+|Ir_)Shk-Of;p7LnKVjkl!ObVx@$h5MK{ zh;@K?Ng|_*h{FfGF&fI}2>-G)BRpL#czn{&&YdM~P_g`tbR5r-f!kH^tH2|yZ^j-8 zhz)lK^W-LCb6g>j!8ye6xl5KdOSk=H6|eE(py14H9S5W!9@QDd89R-+eFm|Nfme2r zbuh=3EzXm?8RE_9pTa%FPiS>0x<(OydA5`Hin*@7vCl;Y93S~4$s0>R&L~=lmn_mh zLCWTr$iCI_RCQJTH^z6rp@yq#sCHkhZFT;+$cW>-N!lQ)7W@4q;&+^SuAyrCTD;O5 zs^?3^C@UKEY@xUMlA6gm5}90<#HA8q6P}i|Lx^8}5@T?hRP^?fwpQ42IXQ)PFBSBT zZ^*%aw6<2@hx+CxNYyfh6fBZS9x=P+O|PL17g2Y#hvTg3qaB9Qn5)1mRsDmctGnd7 zg1idrFlw%G@1zxKD$XNK%s);LdnAGf%_SAcd&<^nq=eW%ibC9Zw82Eu26dZjq$I}N z)#LHN)$liJs{aG&>#s>tQqW|6txjI!O*f{AqE=f|vpI)acDO>V`(%@I&wTi&&l2LJ zaEv5w1II6tM;k<@H$Xe@z~AE!`+En(J1wkXejFW zR_8Nt#ni}X;Ocfh#~uv`hJS;}#ndaffI1A!7X18kycdrD*vu(Ih`FR-nM4+zd5H57 z8OePZ6qIZ~WK?3THDm~0yF|vZByWzmkci!+XZYH#%vHw-} zSvqJ!uHbi_W3dTw_5%n7O;CHdu|CKyVaPVD&QNgK4`j5_{j)QZ_E1-aS10UOUzX6_Td$xkS z%`~*ZpsqfsQ8G`%@e;rHIDNEuoV}Gyf;OliY>d*c?Io=2R^_#b&Rm>FGneDM`M@^KvtVL1IfLeWX^yul=>f#M5 zp9bG5L&DPFgNOaDWC;Ft*cWpod_%CWHTJU=v95%cZ6O*z<-!$HQ&09A`$p5qprl3f zmt>WEwC5ph|N1HXfoCHg#5s&bf&G3bfHVmI~Pw*YV zzJu6T%pCX(dVlj1TD$e>vp)TnE_$Ptu2EQ@KDYIT1tzXq5Sdf3Y1d;~^~oa&3{56m zha=FbkNytisUKc>X?|b1_Eh)M)zW`|d9XzAcgDVvXXEVsD)=`21ipIKZj3)_Y30HG zn%_wpJot`!*p##hv*u-8h*(`rQy1k>?|=mO6+cWGniG%6%ZmdKEDyGfJNCk-B+{`r^*d8fQOU5fVX@Y_4v z%dMkYjknPQ5-X+3>vJEzBNCN~CD&r$&s`wO>Gd7`EK6sO87 z+i95td;t}9TFsI98z(iD0PQAC+D~ty0?%vm^xmFk#jG#u`o4j|DCc1l@}3Q!ida3cuVC92i;j25 z-1!74%ImkO>%IEiZ>FiQ=iqcMRZBZ!bzRRpIbE zd&bmy@7Lz;Pe@ZI_?7$Kty;&n>lbwYi5qaw+ACJFx9xF@jBNi?*0hO3gY|3LI{uS1 z9ZRU0)#V&zC4+kHC-)zG_QN*)?hAG$2H2a{!ybwu`k;luiYw4J)LWm?OvA&?#N~Q{ zibE;s7%l#|w!W$Do}+z#twF)}W39XsggsedZ`mC-E>2f?Pq|+E*UAd|I+o4{F6wwZ zBptgeMQWHQ zZMQ6Hp+6ZbQ^QkeSVC}z{V~~`_uHgr^6_1HIrTdA8G1%jH#k9epo{%0 zQ|D9hYE6xF8~%048xz9rMYQY@E9|B5ewuE}SQ58MBwhXaC$XaH*DO~@Hz>l%C!6$J zr(mz)F6<(Q52^V~L-Rr7QdT(l-XtaS3qn1_9qy2$R|4dwF>EVTF`u<{gQA=}bBxh+ z?71hC*nZDv4gFSK&yN_Lvf8SB40N#Pu*Z7^u}oqA;}rwlQtu6TM_WgC;(AA)95O@< zWd)1dq-%F9t%Xkem*k+j%CFD;@e@<$+H|<~yOP-%?2})D-D4t|yZonA*LdA^OV1SG zXPTfR*0PIvW@J2aKz+(==ra>0=ZbTq@b-U{%Z*m^@;>gB% z_mYN|+mPpdI;|aG%Vy~MGpE_k--USVtR>;t(Je*kg^*3tdg9#P19!K-zk|~ zcp>QFp?4Pvdm*Pt#rPM}RQGu$jc@2T`FSOI9WBk~gCle-Pd{n`J1RNs2gvcB2J6iY zc>fFg0ocb-)&J(1x>~ojpwspCS^KK`G*!0iXKDZO1qZ~4Hu5YcH3#UDEt5&k>?RZPZv+6PUP)bwrb z1D6d8K9f6tRT<6y;0gTn7799Dj#uf_EereArDWUoT#TLl0vp-8p`poU0|S!}nt9$Q zE%ySlZjTu2W}6e_M23B2&-~HV(7>vxlVh)tVL=COFWvBfHtl%^{Yr@t>t*)xLg=kv zdmEBZ-A2BkHoiapVrdymME{DYjpTXY0fX9UT+< z{sY$@ow+!h7H@chICLe5y(5W9%&|u}-r%eiWi)zbDYfdb{zF4O&kDL*TOGy(C%KLd zyZ8OX1;sRDc^M5H5eFVB6#Ahi>`V2fv}nn{KAjJ};mGhT!B;NFN@U$4$3fwkN0FPJ z(fII$?CyQ`Hi!>||Id(lQMq?E?RiRz-~-sjeP^8X(Gr-_nzFUg%Z_g7uLtCpMR z{-Zrdl#pGkqxnio7H?G7ZtJ*U#+cd9sL!|@a_f~xhT^r$UZ?gN8tsNEDjL2-uiE?W z|0H;JDRml@f<3w<61$!{r6h0MAiLBSdhI>M7T;XeXcpp7vu-}!Z?6vsLtJFYz?K~o z$i(deDL1iu>A9NkRn41O>^@*v$)q|Jcmut^0z1Y#&R;u(MQG@5wZ= zUP(tcpud$%+B41O0b^==p;fCy-Cjd8Z@9t6+>GU?R(D9(Y-hZJoT_nc&sV+IOx?*; z$L8Ga=2oW@l@)dB)VcU{`D%z~zvLH&?l&Nt-6X@7@zC1`tgl*DZT}lsZu+db+Y8dr z8UIS1($L^rpIG61g{~{kcX`|!y3HNNg`zBmh zw!8ot^(MJ=NrUacq|fn$x<)haK{oAT^0nOyskzOs_Y4dJtSaBE|9_zqb1Z!O$DdS% zO{8J#c(V4qN-c~dkBdF76gPLxA{8sx&6`XdS^pAWescD_-wk>WO4zGr75%$9zSG<> zj+$CsCuQ;ZGAq{~mcRT)!|&MHg$HU_oDgIek>Ri4*&)*!Zi#8p!WUZY*G~!}eKVD2 z(|0Nuo-PuZ!bZjD0?IxIx!@cr>K=NeqS9j%N`GlT>s4RW*7ngbwU`v<+Tq6}hc2wo zz&Qwu6xhMQX4~z|6&J5daf-&5NkRWIsWqGUwVX)F@Kt5Xem4{M?djWN+p+ODPZ>D< zF?AgdeJ|v9z1EMQb3AdXO`EM|W5*_#bsu>9Yi;LrQn$|~U6VCumEBDwj zN$%sPXCIoi;yDF{#lsFZ@FRpDt40&ofB5sJMeCm<268IORAt$lbU5_M|pwLMNz$t4(V73%cK_I=H+#Jq@%T$hs_9+mxM-L}VBQ)eI9 z(zEwcldApks{cofOw^k;Gb?!Us%K~Y0%MEBmWvKIZR%L3ZueE?)%SNWOQLfC=D3zo zmS`!R16%`a6h)DyD4N8g)Fl8fA5pPEB=37+kBLO(*i0e-{|{FK*k|$)MVVkjsgp7` ziAE zR;@Tw^|Q*#W)(75%Ql-e`vqRS+GA8cnYF(0+{EpC&#KSX{9jAk-BDX7Y?17~SLa*J z`VLRM&^ZwMJUx=gq~*E&rXE+#WxvABz3v)85Df?n0-((h_&U0>1_swtc6>p5Lc zR5x7yLB)$z{uvVZQ%{$!cOGiH-XT5f?~)YcbSmU=9bJDF6UQ(9&%pJ1j)s~`opfo; z#QPye9@m~WcS$B=>y5v{22_xfO&xZBX56-rS{P0mRppbl{yS`R)F^kti}az=+9TkCcaSbOKnG4mc+gom_=I?2Xuu2Bwz*_$usI Q?P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;T}ebiRCwB?lg~?(K^VuMnfKk-UDsWI6yd?p4D$yf zYOZ0$QY(_!uJ+^5Av^{Z5naMdr=W=PQuqhtr4E6I&=wIa=+aFHj0|y!T+P>AZGXJ) zyz|cc&eNq`(%nGl3v-xfzVn%9_|6bSgo`61-IBm0AUvi7KFrO%lW;)MNMuOi!a2p6 z7_@DBmH-`##-d6&^O^8@_3D+&&BMbN?iK+6K%|Spl`?Lawl8n;H?AWmMx%QnEgijH zLTQ+Ddzo{ms|Z+JTyOv&u2A~W=dFkfM<^y^k0^zi(b1S60HA*$>^t66|B?dC>)Yum zeJ6Xb03e81JS7qt(g5JLM0|!4)nK*%bvm7WLI7_lRNl!L)|ADa2P?}#JWsv%mc%fP%VvLgx@+-tYHmhG8VKdDfR${jyV% zLb=U-p->ZJ)(b?}W10*!O*>ZURX>%DaetxrWPf8W&*lK2LkN2&xseR%dMd7ITFZ&H z&RhHad#=#l*;Q{C=37E&s5(&fF{N)^%9(kts2bGN)J@g~1LKD6wtrh*`ccwBd(VK^ zH2G5@WNWahDk)Lk+}KR+~1%-b%kgVP+NOQvzd9?5e#hGT3BCSpH>uQPh3Jc zGNo@N>go>9N|zr2@}~(z1Vn^}#+F`>R`DDN4J)b|DAe~408lBVm4*2~-@$=@BmAd+ Z4*-2yJbG5Si6sC4002ovPDHLkV1i;-Ntgft literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/magnify.ico b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/magnify.ico new file mode 100644 index 0000000000000000000000000000000000000000..2d2cf60452bf235b47d0770252ef12818264764b GIT binary patch literal 114349 zcmbrm1z1#D7chKg7#gHQL>d8U5CKU+1wkYQq*D;2rE6#qq)Vg}5D}z9I;BelhVBrN zt|8|?gZJLo_xD>}FURft%hJ@=_PY(DqtIPg#!U9I_g=pxF|F*&!81x(6ZtGG31ahD{p zefc@IOPzQsKo@umscD*oW$lKX*h#_tircK(it_UHrJoK-YCZ5cKRrKZ1@;dPf@WuD zjiL<=4d2axmJtZ5%_A`%U*Db6({R*jBdWF07iHf#yR$VbyosuwJ6)&eK^+q{G+u-k zZSi`cj;^83Pg)R1!VRm-jYYg?r$?_*Q@qHOqsG~-FM2%4^K-(Em=4s*iNXbF6asIX zwMoKX5#iQ@-13+3?!vHE?nfj_GcXY|p4}}V>!aitg;eMdL;5z13&nh|h(W1?{Z4Jt zquyQ7yXwUtj;oE$HVz&8I2Jl~Eow1za@pUQnvY=7ELoaQ6L-PC`0OD;@(($Z)+lY1 zdYd%vb0E-|nm-c5w(6Q~mF|x$aqJ8A)wQrTB7aT*<4$2x^m5f?cII=JRoHyq>PemC z6@$}BDt#HI5%LXnjB0QNc?j2DpF@ZgGVObSD-%A3Fp@D%q-&=?C9(_Ke)Z`?+ zulvoPUooNWV0n~WBZ(vvLn?9oIUm7?W(8g%;AJgq zFy~zbsGYPft>5ixT*Qjg!sYbXG}*TQI%Fu`-fq6XwiX_z1?W1qlLHv1b5! zIbdi}F*`WwWwLEyD_v^6J71ybJM5;Z8LPS0gI7B~h7~h-`MguB$K`Rw!2`NvewH0! zb3r@LVZ@|f5pCOkbI|c^IrF*tusc2S^g<^1V57!kFDskwjYPHNLbwWspa?mjM_7k1 z=?`!f@s`al^7-eESPp2#B6EJ#wQB~?1PI-WV}`!jvlrTyM8cqa^^#GG>Vv0;_WGKK z;mLP??ZE~vxXSl=S@=p)5t(7|xR63D1N<#Xylo5fBgmX%b+#!|UU2o!VqtSTZ^)5Z zeTu^xZQ$8dt*v)|!qf8}Le*UyXkP~ITBx6fs?<)+v3xWBJU4~(!(AtrMwTOl{8?lJ z_l?;lNnK^U(MnyL%J(1eNbeJ)6o-Kj7(Cxkt7(!0usIuACo-{&3aN&h7i0)}kUlIP z4U?E68mE8y%zJdb^z#(XgF+?uUo?)N;D{Wi=sl)v8om`mk;f5LOh6B^2(iwx7-CE} z@m3sV`MQtjyN_tp?9CnSfYI|OMBGowJ6aSE!pVSRXv%}87<{bQtwRD!u9eN zd49(m2zHSFK$gFhxoGBw4Mmm_Fgz>bFhfF&$EtJJhx?>vwm!J7n0I9%VqI(cENJR6 zl_YoTbVzQHJA?`u+MU~z#KFm$tG9o`h=Y%p`XnEIN0u81_(@5zfM?gP=~jwK2fBcZ}$MZrR`=OOq^DP-XH-W9j9+chLA|p=00P_F6MhF(Ja?~ zq8TwulcnoyHIw!&4yk*MXFpYr!$F%V_#Up2=%XJj_H=c$km6N@@Z2reG~hk;R*%Ix z1qm0-GuSGurSg&f%{OWH*rnPZbDGLvUAhu^K!Q% zI$rZiL$(vR*X_EMWzRb2qHn8_Wvgn2MC&w5@qVcynAt3IvVp5jJ;d|{CQf`h`LP6*Hu*6R3t|pLMQ7F%bWgv0 zNUJCg<#F}SA>GcN+W{MCcja*8-Rq(*i$76M+fO^rvXYxEmUy7~D&NVw>gU6)>7n$I zsPw^{+%zFY?|x0~Vil--0z3qIy4VZbW|LrHFp$5ij(K<}aF|qT7zrDWX!zP>?d&v! z`sP7dd25C{aa5>Z-<9DBw6rj;sX>GlqW5G-x&8c1_U*UrC%=k+-IDB&!}#oAo%{S!>> zY9O3^sd^`CnhsB#D3=l7J|90-9?Ag5%FdVCG9J~|er=R^FfGfJvp0dK8-iEu)VIMl z+xO#LlaB~G`HWAOG1dBfLD-J0Isc-vqz=9otJ;9S*oK;Qal;ktaMigXK^|G-xc zoTmMYg=IQ|n(2jt#+FuzPaAy^#X>wjntJtz+T1+`S$3cEClgP*?~s1L%Um#bC}`ur zk-pZp;qumSQ3)7Acm(ko&9JeZ(+8Pq9&2F^ZF#yp|Q{W z$9(vPg9yZOi~eqSjpK|IGuyfFui4i0`do?pO~I3D)|g=&zn+)cMt+UTikQW+_Af$O zahqyL_KPzfA)gWE3^jRG@TeeeGY9<2i1Un%JkP03mh zt7pgjv(^_vGpuXXn3V!U>DfBCo_T&19R>PwUT9C;_OQ<|U$PvrSg#mwa zK3$J)Avz>Q4vN`~A!hO!2T)DadQu2(8fRI|!!OUTJJUV{9_&UnEzBw)E1GJ?4HgHL~UJCcaC%IczVKV*RBhB{ItC*!mXVpqjNIp z$aA6-Khddl=J+DuJ8@Is{!?F|OWjxcxZ{rVI9+g?8_O+r8_z@?j;jSvG=EwYUQFo0 zVR4NtE=?h@suopPaWrZHvk`c@sXE8)>2uk4uK1V2DW^d_LFFfIkS+Sh6^d zfCsW+R5f#u15*3U2Pl!quG1y#d2W^^!mN5&(biSGg0ShWql;>!CpW9k`qN2|Q0c^| zqf;iTw)LgG0QzpQ(d96g~S9Yv>em&$4HVAihH_YGisMX^=SpHNvndOeZp3G`zJ5tuK zoV0%1@qF>&-N+7mYDge&MzPzb+(qn`<&;}}sc-&;PO*vpIJUJu54UNT4dQ|Ehz(-` zWsu2L%f8TM(WOqlqcrVo)+8O0-TFnAZR*1ta0UeO!=SqFvRc;tL*22Ko*v1b(%9z8 zeL*=`&TU7!Doul*Ww%|Xu|LZ=roZiRWR&57aVB8kd~c$17AJ7S3AqUX_?RjlU$vB& z5>0+2UJOUnJS)(ocbwtTdX}bTQ~wNE)0Y|>y`DnLjcGJeHZi!)x)kc4kSRp_Lpw@V z4zjRqc+Y0WH$T3x`PKIWezWPRRl3FU6K#Bm4&t+EB|AK|0O4IKgYQmY^W(FcVN%lY z8&TRHux;WijPQLd2B4?vV(GBUU1B}I$cClz*TreQI)8%BavP&?rw;G{4+DBsl@biegCkeC{B~Da)#gkMz7Jv;|pde;BzWtu% zZKXA~;osuTJd2KaV^s1A9x$;+>2dbhaHiSi`BM7Dw*ZB2@rCyr67l5kuJF@3r#^;& z+gP1<{&2#_gmu%Zw*Akq7%V=HT5!_weC-w$%?KC~&ZnnNxjRVtipt8lm~c8 zHkppS29V*3jq;y15hjDxU(|VY4_9|%UsO#D?v!sfnx_iM7N2DGSWPONF8xe6$?9sE zFdQxG{Q7C&ysTf#xAIx&Px?sba#LaGATBM?g>0m|unyC&HV7yE_;4pRJKtRG*vh-speX!w$)mo1D>ifCSmXsQB~+Ui zh$*fsXJzF!CcyoL=-B0mMENDKSrb`VSXC5 z*B+CA&51aLA|9p-#psEb3K3bfen36>uR_4r_2vHR@;bx&#jDj zM%2O5Ku(g6q{*3tnl^pWNK=7}CxJbo@%CYgt6u&~h4Ybv{mO~ep~_L873n4NVys$X zxYw(23cy#FdmN?7Y!_1#Aw=p$=po@|O^=9H+TvHV%3O6Cs3aXq6IN?IW?Mwp1AMj9+n^G$UXhx>@CSkI@P_W$g1u?qP!+jK%d}H zZtRNLWYqkO18$I)F*&oKsw-h>tNYn|U8Md~W_i5}S3Yrw^tYQxqN|#za_Z%=hWIe9_ z;;>KKr0|Op%I6R5G_$de9jw_guQuSV81W#`mqN5_mNq;odExz7NVcNCN+YCd%_GNj zsq-_Iui)SvS^)~}h8`s;=0TG|JziG~0V^zvkvN+wYQ3meA1g*o>Ll8=)gM=z_IPlg zCPZc>>GUHaYRMn4F!(Z961osUkcuoNgz|)j@9!@lvMVaMwPx>BR`gjFeI?dC8N1p1 zxio#xdS^ihnm1CCnA4D`!i0bB!XbCfMH#xAq)mf4=OKYLL<5bld)n7psj#Sb`niqe zbY|hedR417vgUQ{S!MtCpN)qT710bKn*I#FOqLW^Jn4bHSfv|II_AFl1a>29%ixM|+DlocGOl)*A${t_U zJrWy}i1U64;*8Rff$KHuye%vb*!U*2f*o|jbl_lP_N~96o^;qJsw3nAAe$goy{Ub!Wg5dDmr3DIfNh)Qt5V) zQd%0(aFEPxAeHN{uuW_vapl}b`aErf1x2ZtDIuD)o@6V##rrx&Rlu!2ojE~IbW8WA zR{rXMyR$bz{`G1lUqtn}6+-{;n~Ym|YHwd8o=XNUPTRG+jT9d{l4HhswQRf0^p%UM zXdd-Zd!D3BHr~7a8Sm>IpM1Zh30p>(weCjEQiQ=4FCAAc^~iP1UwJ^H;gy^s$DapF zqduC|XL`HhId5x5_NqRG>t#5duJ-3YAbsSK)36fBImsFGpzntwi|M<2+ z#hy5sWPU2l5Z%r*+Nb3TgPKt~Oc>Le>opJZ19=Z>KQQTJdnsK_5cggaVI3+zDfy8V z1&9Z>`q0KV-aDR_XhkY!5B|(qKBTit5wqAxQ^aCARa*~vqQzUqw=h&;E$X6#8DAI> z%m&c68t(y{N2ew%nKu%S_%2eoM$fHmdhW=rrCA4me4XP0ULJF=o^U}q+);GzaiS8$ zAO-D(u*}tSjAXh+jf3)}NgC_dzI`tBg<)B_)7+;D}otd@rfxfNcbbc_eNexpzKKn@1lGT6cFr`^gA^qiNhZTadoY@K|_7Q8L6-|n!j$a2CN2mG( zsJN#csvYlO_KmqkII9ARJa(9$u}0;eZ=}7fk0lXjn)f7hB>c7{UUo*O)6a&m-ApYY zmZsM-@hIWayO0W<#)a6_d~fx_n4!@Np{T0+KUD7okBp|6uGv(amv?Nc zLPVMRy*nz;T*dvF$)$~~FNWN2Ne^HHCuWt-rpt*_A0!Q;$g2`HeGB&7mcCGuRD22@ zb+JaYpFH+>0&g%lxwF!+etNzMD<-)@2my9juWezmyAybmjYQ1IdS+oZ)Jorv;qt>EW4{MiVxa<@E=yF)oCgp zHa`2In+K;|+mDr1!hL$0q@l4nv9_o)c>27;qT5#sAX;R{j4nPr?~n6eSWO|YQN>`5 zuX|shE;t%H?5%;hPZ}id(j~TfqN|2g-$N>@Gl*zpNAa&lfKQIw=NW-4vo=Zrg5)dT(mAEB_R_fVa9*^N|l?{$yPMeW^MO41j3fKHw7^V-caQ?b+s zkf|-#v$L~gUfgdzLrOeHoDWZRLXEH2K9Ni!sJusBv6vK@An4fh!}^suJ_SRR?(W5? z=n}#7>V;jDIx#SS`(<{E`o2HkYJ!unLU>hC9(<^8*6J54lw(8J%2Vk)mY{0l8{$Nj z!sy^(>xm@G(ruaDa5Wy3aML>&apOI!1`;mQ(g?pDE{fun6}#zNM3c^G%6im{raF*g zQ}ej*bbU*2lecQxR`}>bxe2^28E%z6+nd+H1QeCk!UN3f6R(xByj|X@+#QN4w@dTQ z`}S$pNhg=r|SVZ;L;TfcJOh9RiDk0vZ(^{rKsKZVw_Lp zu1PH3ec%&~!mbr&agQy2E4<7Dq=Y*(zZb8Si>b?o$mw3^YhUYB83<5@2N+Y|lTrBy z7`cC!Uy7*tYMu5F^1?mBz^>t0WBU4}BZ1MwTZ?A}IL)|5)~Rw3pbK9Hyn{69E)LFt zxfwpS9a;9!6wgOEm6n@V=g1l60|ljWPo&qzs>K!8sCQ`;30kR5e1$JI9B42BdmcDn zs9ca;)it;W5B%FgpRR-tccIPKvL~&H{Ph)vicXk{4HZMoo@C9Vt)fLW{ai|fPDfSZK=-xyeqKbPGf$4>aDV;qUK*Vx?+@}&lPua$qoU7v_Q1n&TB-(EBnRGNu- z=-yfDc#V1^k_H7#cz}Dz<6~Sf+VCt7>~p+zE05X->czTQF^Ir;LEN?swUxq0}q>S>~fDUsZ2)YHzA6m<)fU-B#z!373ymA)upM%l{eE; zU6a`LF$jI<}E_M;`r%t8l zbDsdMe0qGI(Ayq>AAwcdlUK%mw^>!xARf9!t6a-;I*t$t^Un@GiWf|-{ne=ojXSM5 zs7R5|P{7TFp$TIA7`NPQ$zY)F{;!50Y~RXPKWtE{=By>XCvgMF$*Z7s={nq{TIko? zz_J%GSO{A>p~)(qNTgFm^jxnUHpnxu)m1jg%9XJ0EP6@n{W!e97rENr$oBX%Kz&xu zz%I!Nv_&`!ltCrvevxdQTIx-!S0Q>3CaBRv#|@nW)J~frEip$BG>##lJWqwr3&ptmHuSCm@Z; z2z;&8M?SpnX=Jx$H!^7wpXCg@D{~Dc5)t>yby13d_Z4ICXEee!;zN zI2eRq3^$v%8ygzztM#_GW~IO!rpH6&50B?xPjlA6H*D8Nl@>E(YmBL_9u;m83b*VOq#%m`Jjg zTzVY#B_+!C98WE8eLWNZ*0Fk=fyJ8-&fWzO^U$D|Y|b%LA6GurIeSjELXD#9(6 zaVKm0nY_>7cZ#MRx2K@>;CUwBn>wTu;5$kgjHZ5D#Nc`f{rw&@8vP<6L)A}7Jrw0M zjTPRs?MU^Ryq)m8naHf|T|78{ zF-qB-jhKq2hg7Ko5e%F`OT)}Cr}`=tjHo3x4+~asx9mW;-)-n~Ey>`7JI&dU1I$y8 znD{@+;q0?FZ@73q6&e({qq=ut9hDz-Jt8AxJxjhJ!PK2+j-f6MYGlbO4LnGoDjo*5 zCtkrzzINVU-#7CK*t%6jpKQ2v_2+76*OR6l=&`^>u6Qkz1khORF@Z12W+#j2R=Fhw zjbeVitY6z9b0}z;YGSzEFF=!PH}~ug`QPqN;jJwzmf^e8Gx!iK@*ypo`jPBVqwRfTQPrR_1oyqn5#ZX$Rf@a# zcM}Luj$x0-J(A_5#^O8+bUtB7>$MI(>l^@IB7{b<0MdC7(*B4WcJa*qv{#F~T%sar@m;|P z7R_jqwX2%MOzPq0;ib~E{qFdxLM~#loW6?twHUPoYG)@bR?^Om1Kf7sE=(OesVD%$ z0tEriaoR-A?6-t7Uaw-__UDAZj;063a5g@R@UJuLW91ezYqI=Zsivvd^^RT%wazCIP6Pt7OiCQ3^-IZ6CwtN~{O)wb^qkVTM zQL_^esl=a0tf23%4Sg|A9wF-S@}gJ#-5#t?ILzLN_H5iwZVog;>jwkQ2KD6ShvECk zHPUb|zbVRHR`Q1?wBDtIIwBB}betA$H=odQY3(pv$sGln3k%JLlht(v&+q7P%|EtGrP9c-% zF%WrO8o-g#6p2=ZIz}t2(D~j*R+AXC*F1(w*hB5bDZnS4Eq-$oSs@5g-@8DNO)u;* z)CMiNzSGwTlMckVg%S>daR>7vq0f=U1lY9BV26irYDyM%8+s?GSr8y_FO!7`$i`B3 z>Z)644Itcp1CN}JeoU6$IY$}c%adDO%7D4f`wLqAm`OZY7Lz#mn+5*L99~n2AdU+= zU_2Gyeh^F}ACdkx8qatJYj@nA73{$!z{^ZK7|O^YVyD}ScdHe`(#|7`VWLJnAK0kV z3w}als>O%f=?)QogD*ei`7PP}O~o@3X%%dz?}e~L(0y8%|L}#!2L=wNkE(u;m^-8W zWFaZ2qxoiXa7d<&gP>t}bHC`WNxVxTlb69_;2^4oG_m1vfIVOFqrij7WFkciyI~o( zy}F5|Q?PMrMQ~wg8CF>18)E;1_g24p1lrz7cM|)_h%zqWOQyrXPkTa)uj0X_`V|#$ zq=NxU2#fQoi&{X23?7fzF4fz9C>zl6u2{y8?_TFIkkUQ=R<!Dsa-JC7s)Afq?!!&-5K*QH8W1zvD`h|KvTd*Cq-BmRkMXPq*)~ zp!=Yhm}R)@%7t__%IpJx$lgpSd7NMK2kR*VTHng0AiU*vg=+@ zTyWU>aTW<>n*4!#1Ow(D&aiXZmEXP8Bvv5VHvVz`5bc^m`D?u1Yvb`$>FK1cRoyF3 z-jTDz7~L1xH}5SvFu%WG)1!m9M)=;&W=-smcT8JUCwq>;{~Lc20lo+$U@d zT#Yix&u}6af%y|tVyU9CyJgEfxbUN#ZC^e&88u4T(6K|Y*97318$bofLyv(rrlwmb z_jbd#rP;6^jxyT5TA2{Y=S!%=M~{vH*2q);y7c5ib}}=g5FDI0zED!8Pz8AWD>oao z7;ky@>OH>A=R%`#Ga18IRuVBu+GrtK9wGB+hw~ZVu!;~c2kJ)owxy>bNE|Wi(pT`_ zlj2M=b~Aholu_qZhJv$`6p+d)5@~wUBg3M_PRZIHg$dC%ZYnQgf-2FvZRBF70kphf z$wb7B9Dr#l@w4Z4?0%VB)%^?V1vf)*tAk(se8Pq&3OYjzW4M9wouf6Lx;Em_l!7#- zRgG~_&zI-byJkHa9B7fK02n52Pdnc=FA>Tl?Zt-3kPnn{stYkVog3)Dx`M_Mn&Hn24YOzV}P>|sAQO*NrjN6 z;sf>lmjS|Uw2Uz{f7joBdd`e)OLk8nY>kTXZjEvacS%rE3Nza6Yn|`zN-I-+(7;vs zc|IP;1}px^)=hk5I-qTxDpWp?6gG!|N?IuQ+mcrIgeQULm>z5t*R~ z$CWWomwpd}59_VkIOS20cGgLgV%g)fXh5iXl`?G1(BoSfeGKH`47o$K17X>T>J&GZ zVC>KRUmI$WaW>h%$3|xyJHlfb)!Qc;xD1LwbPpvINaENUFrQy^kM#$`h6uuK$PgO{ zCI8uF4_`5V5j>lb`7`gaNd>`Un#f;vTpVBA19j#53 zL4;nu%$Xrr%L9=)QCF0mW7`bh5YUnL3 z1ru)tLVbl`6^rWW6sqW0NYFF5sjmh4bRH7lgh#g@)@8TZ#EpGnfW-<~zJs-#0jj?4 z5zl9{E<;MS*w-j9ks^R!eR~YNEF6uCxfg$0XW{r!C3Dmj+&2~%88T?#DDUhu_h^*1(DFg;_Lp?U}Hx)Jn>L8Y7RJH&+<9h)68D;P^3fmW|F z`_jnbLR_P}Fq0?-9(I}ry~kygM}DA3S*jks(rzOnR5{PYKa)Tos(hqv^{>WUo4)Uq z&4hhXY$%C7`JK-5Zk1Sk;u7B!BI%ED!PwvL_w(SdO%!oY^RmK3%d zd++SA!b!G>35Xb={JKE|6}sPCKPUjh>X^RUth z*nkkz2RmB9W+Kv|rS#H#FJ(!hk&j9r1!0%0QB(c`PbEZFy73-MFb0bwWY1#bn93bc zAP>;f+4a?lGAov20++_TiuPktD4=sO7`nf&h9BKY#MR>WGL6uu`RcB=G8hc4F_?E> z?JQA+#E<+8%sfk#N10t)C}_%L`clt5z)S@8(F#vxiEnr)e?BNL150c)KlS$xAMoso0(c_kdpXWddw?uYr8)>WI;943GS!Hm*Bl&$U8@AJ4 z8I!u(@B5Hlnu9~-5ox>9>9xyF3xa)G`7-4&Gc}~Sma=EdkEs{2;XNXea?L?aM*=qZq02nd2;GJrJ^PCR;Ki=J7azLKKi?>$oBW}C=KH9;nc(J@2qXA$H1P2L z<9mfNM*i$z9sH^rFaiPn={UN;f1}I#e;?qW5aht&zY%x@t02IErluxPfV%t#pit-< z2;d)@g+BaW7i=f{f7NwzaQ!zvwv!Xtzwuo~9l$T#|Br&>IxPzt^ZQTb`1>;MTWS#hVcCt-!(J}oa)d} zw~+rbgMG|c$fmZ&oj@EDsvHXFI3|;-xI+~9Y8WLg=67s+5 zU|?RJ*Pp?FR!0|C*MH;wmi^c9GSYtMA`}wz6HRYR{l;^D;ikVZ{BP|0TYj0=P^b$C z>XJUg_-~BF{!MQa{e|g&<2k9{xXJe~j8227Ga|oBJO^N0VmN?(iNUi(;|l;FLgTZ) zF!C=xIO3Ob5MQ>N`wxbo^+Ea)H~pXZG6#eF|Hc2+?(g=0W3Zn~`QQEh?Z@AKfqv5e z<+s!&h6BErcn)lKd7hvcjV}uTp!XRD5Trr)d!GTopCSEwfrFb0C;|7CO9URl>i_?J z=6`k;Y$0K=lm8S~L8|`{U^oi@ce2Iiclc8bW>MllX>4JkKS?0uf3l{NgZ-cKKRXX` zg#)f+|A<}P&{_8%-$KB|hYWH1Ta4{?nFasJr6HFj>YtqJ297v7@45Z%4V?!;4J7KX z)PfBrzsuZr^xGgdI^UuH{xSfj3NT}Wfc!0YMJGQr`4^2&Gw6c)D>+~0Q*;9ROMbal zk>IlbYZ+s2q0l9dD=(5C?z&u9XXL-CTfc>Wm&71u68Z2f-JGnnR(Qo52vpK%Ie03kfc} zZ4hsRGyf#Hvara$0s-fua^r9Qgd83-2uXcmq_q2rty1U?Y{j&lacAI|<)6%Gb9 z$N+=;5`jms`u{)9L6g9L;s<@Pg63QnY(e6`t6%{CQ^j@?`A=Q+@2LO)C#~OX@Jb*= z@HZPf6pY58-|Wj+bGxjAaRrv&vxa7agAGRu+|a>-{9Q+H_+ao|+Ht#N|HTJm>L2~f zT>qON@;mS@?O^{vfm*+V1_!;Lh0dYPgK04`H1x;sDi{iGe^tSr(76YMRuBR}2myfz z07C%;dN2=5fw|TfK!VAA8-zI!nn3#h4bXBhwE;*l`Ge7Pna|K8$pFIN^9%>;|6btW zq=FJ~axW2h1grla<{9I!nfWV~V4!mZj$4SZ3L1rmI)Nm3v2}UXft~|!3F4rK7R2DJ zT`p;m2G=UccSB#IfKGsNBzo2^FCWn6B10oVHrgN>UFPs(5buDn2mnZIaIXP>Y1)Ja zunzwpxa5PfIeJjn7yMc2|NT!if7QE3vmm@@kGr~SH-E0Z*%YnCcESjNNRtZV#J*=y z%jQs@(x)TUy36@XUzDqh(e8!F?UuvX#DZe2o&?%hL4z+UKby3P z{QyAy=tyr`;`?{~BmIO^xx*fhgF9uPJR;K}Dzl-Hz1?2!PY_3^Vl!Ly!*t&Js_oRK z5yEUH!Y5eh+O?1pAcDXBEww2G&F7D}=8a+J^6TxJgHORqb<>%8MV}`#Ug~up&^+wG zoEtt%tsFlRX}?Bg3i;A6;`XChtFve!h4SmjlU_4u(I_B2d*^<2D%%>;MsQs3hp0fL zY_37BUJ<{L&@zO4H>lyZLo0)@s3>J9|LwpMK+p7%l9GGjb5(1h9V@~+2Y24Qi2P#1 z&o6ZU<{OpBWIB)j2lbH~kAgNi6FB30mZceJCwG1l&c@llNb<;%qzvR|;-`e?w>7+Z zs_Zf?I8N(e?Z4)RJ?Y@T@!BKpS#4{}f?BaswC0y%;Ikv9;2WGoC==`>&24pDv9ZlB zJd?SIa9LyLgrFSOA)$_1ZM_@=>*(U^clg`=`5wSQ?;vJF>yfR8k7zoaFcH}&D`BMti=k#Y#a4;PU%$%K;Tz=_^^XjQ1s!=H1jjcUp)-iB2PFZ@hU#DtMi=($@|@T#+k7tmBQ~ z>Y5vO=^NVgJhVstB|zZZ+`HEF&;c;4h)soma%=8#Le}U#PoC0&=}yGSDqW^Qdg_3? zDn=gDY+$J}=CMU*wxIS0Khw8uFR{P>x^L(}c8fC%!F4n(r?0r+c0T!udr&;%$H9Ye zkF5Los!WEqC+{`5?T;67Bvs|tloYOqW7JkTA<|s86UFQ-T(({?SVGwzr_SvM^=R-dYCV zzxkH6-Wgw0ystmalh1_Tv6^=0i`_AIR)F<*0MCZu_fdACI-`0$?)kN@25-k}2gy2R zYy>$Ac*|CA5=NfPs(&d5UNhb2zCXbk^H!qCyNYh!V&>RI&C}N08v3FGHa9gTUR3Y# z3V(Gqlugj=23v>BHr7{d0A9OUi_n#Dh3F$N7Q#0x&RUqhK1ieYK|Pd29oVVsHH^uf zgnbqp7bpq3CvgAHnkP`L;W&3t{`ji0GM1vd?&tBQiWi@_X9Yw3Z&H@B>;tvNBiRbRF6}Q zE)rJXh}yrTrK$7V{y+iu7A&JfPP>tf697q+N$d#g-hsZo>VXSUDddg=K@X!u_3Qmn z?%v)_wkq>iFK)=)pqmM}8D}6Jt*!rxy0MVeLFr>flRk58T?2_*ANY!r7)tC)_G9`c zkfxn#^|{5WYk-@JD}8=p=sw=D*Br$oGr_teeWKk$*GA7YV)32xEp~g*RF?F+Hc(=LYA7MDi`@A@iXJ|L-0zHHF|y&cZX-1Kii+f7+f=^08OVt& z<@t)Y*=$w(qGd^wS2oxZ(tj}fXrD>qJY!O<9l6rULpJT`Iki)MD@BWC#Wq)0mtn=0 z%|=+8yS&Ss;MHq`&~JHKgK4ld57zyZlvOr?AQc=&t5F1k2prusZCZFw5Cu)rz|L8< zR|fIa?XuUd^{4f9%YL43I-eC^4{7;%Gs=5iw>RzSTx8XhB&8pMV}=}Rzgl8C(=tQ~ zZX{tZf`hU0S9yvx>~<&AXBUqyT36XAHQ$VtgoLGujny6zPv%w`i%B+P9?OMw1O>S| z6ZNdcXtLHaI8WHleI2r#Hknns-x8?6xsWo=)K{4SFL3p6#+aUfrmtiuhRT$U?m+_? zaO|W*@5U30+pjW8BAbayRufI{YHv@eORb#F`jQ*bQr2DB38n%_)^i1(mw!<-uaIVJ z>>e6oLT%2TiA6TL;R&WcTlMn>qpxh&J~&;Ot#1D}1^*2z(cVIQFx zo2Gf4Jh>|L@%>L@y%Lx!ocL{h86AX>swF zHq+UQ+lqTmQ|_p9Qxdo9^Mu?$%ksd+grC-D)tltiDtS8_a`cPJs3m;A+Qy?FX}=~t z@!vd(%roP4O3#r`7iv*pVj!a%jgw5;nLdB;`5Lj|joN1)plVgljhYOCGA8vZN1Y-% z#kA#iIdd6}Lsn$D4=AXLmXj!jIo)pw-mU*m2)j!e5Ha#@aGw+N?EzNBF6kbd@^*_! z%t{OGoa^F*8pOwW&d z^3T?1QNpP{Yb?*i`)0&87b;~>-%M48biMSqvUyFwxKrPm?P}t%Z%ZMuNmO2_Vn~b(gAV#7IB%ZvI*=K|tG_S_z@F^D;q)p;y?@ z0x9RQOf<{co1;dyPQtqVeL=6in4(iuNQtoh_eDZB!2fJA_ru@<&(|PU9u2Fy!(R?Q zt49~?!#_Lvn!6;vHO_>6Euj?)UDX%67CjT5^DtDeIfav`p@+vbnxZi=loZd;q*|fn z*2i)$M`6zUk9x94USOI;5AVf`JzdyHXkzXxDvUN1`MRTS!O`1@)#U9u-4!CW53v<> zkkVgFZaYt?7QVOuENQpId&r@$Q|Z`6S8x zsyAuwaQ!OebdVwPyVPPulJai}_XnS1g+AsIoD-;PMU3 z4YQAvOD?J%BEi9?mbWH|1z*w%N6x!zdqfo4l76od*&&~floOb_zxU!(y6jDojuEjR z4^p{xtKx=g^$IjT8a8w~@ur$7-hOa1>8mrXt(c2g(k`aYS=yGD<6)DZvJEohPP=o* zwH6HG@Al?wXJ5{if>^D3!q0kUFRrgpf|F7&x3zRQx%oq^{}v%>i9nazry`R=vhcXx z<2X;22p(MFNvcVFD&Odw*^jJ^6VXQGywbLDl@k4wMy|m|Z+}vRZUbIL429MjKYbu- z-9H^SP5hqKH@6&)OFVx#J=(1bq>46}4a1ILciTWEz@= za?B|Q4Cm%zWVM6)Y&s&~keUH3pYxg8e z$8E;KxN=%pAAN7XbuM|DJ$@s-6Z46^ZTJ3XpY8``FBe==Zt`#-c&C+EhP17}N@c}9 zwRNrUA_{CjH_^Y~s)M{ad!Odj=$PJA`RGMY+xkn(wq9u*@xJ!3k&^3Fh;4=j%v}9k zjhm%)UT^kR`vq$)*lfkSK<`Swc)6#NeF@vHAqVbWY^bYi^o*$NHZF4?@$;7i*;Xm$ zKFJ-i!denm3JCiWZ0^h-chxbEI{1xg%K_g4S#t2}#S=|K){9D*<%FeKLt=K6!b;Ev zzAh0NbR0iaf#!ib%pfKVBo3$Q5MOr#CUwA!@)sMDxa6ku!+B1p47mOpvIOwZ#gHGC>pmY7+U$wmwTMqa^KOv zjUX-g-J<)04B{6V#l_dD^rK8C?ZLabiSC=Lyj%{*QQ7R+hmkWr@nshMyZb~we3X9I zA`m0BkozrLgOLYIMG1Jcb*Srgd+)Hr)*jC~?6~2Hm1usZ5|&?~<6C`0Q97h!>5vozq(MYby1PMA0g0s>=@3|! zg=P1-zrW}6e|Nt-bIzHWGjq)~b5o5-nB+bs-S+xn%htrkgMTinuB~(*$2|LQ$IP=D zmIy&T)6bm<*OO(S`5{wNnmtyIKWp7EB$@g+WB~&B97)AyX0MmfPF!sJ78KU};Y?RQ z^TlMs0#hQOi?|I$DA+Z8zpI*f46TYiuN zjm{e;+@7%a!ajS@pUfibGda9W({mD^w-i8AV11t1I;ZDdR zW{mK~nIt+v!%SGjo+wEiB`=Xg5ODLmm>gxor5PHe5=!SCF_a?>E#2uDN$nCLA8 z)30FpOOWt~pqV<7^=a&7@v@pxj{L$Mp9I9w)JPKN@|OokAl`ZmUYug~5AUq+`neI! zY#jC2%K4<<@x0LWg{`4?Gl&1Fiuq{>_}8Kx+uh-5!YfN!cRkV`0EDWZ-*3fKdPad^ zCuAL>&9P4#3j$AClg9^KpH)*E!Je-&Y)||}Lw>zisb?_?P8YVqC*{)BPY|@xuI^1A z!03cir5{r|JuPG7s35fbv|SLy_6A>916+f#UJ&$|%B?ioe+R{?}v>E$(Lznu{#+@PaYHF`DFc#*h!1`*r7=3I(kj0HKI6UUsxPKy{F*Q8y?1*X+nf*G6r=3|nYY^` zFo!DDmwaA+^n5HYEe|7;GFL`YZW9Y5^SI3 z>OOhISJ|m5we>bw1j`XG8(YI%+hs_KSU&f=D?79OjG*Mga6DoEd*U`D1%eQ9P^k^w zL^BN`2xELsH&=_BrwYe5M@iQLH{&?yuJ@6!&uG=_K+2yjJ}vwBg>R~AxTd`BAh*M7 z?*BGv^a3f}_tvdgmW~2niOY?v61sMCbUWX5-joy`*C>3}kqNUh_v{zFJho*ZvAzJk#1MqK`CSzA)+YA>= zVFmvvxn6%tPgvwh(nF3d5qy!3leZR8ozj{Qj`SySY?3|jpJ_65yqm2l)<%v9o#RY` z3B|yKO!JN0gGDc&rmQM7FKv&U%F2H?dkDDNRp>RG#&Q7>fa6LIM0^#P%rwpJg0q{HLvkYd36wXJc#G za)&OdFB6}Gz6?l=pOY!x85PgH8I$F+O(`?;w=I6a-bYuB879P+A*FRfg=W zM%aaJZeiETq0qB>m!Yb{%D-Y|O=yWzO$R|wrnO_Dn_+MT>?hz+N#c`tO0w@$E`h=Q zSNBwfl%nqGEWnJ-`eJ2X&(9n>KidLRUCB_4inN$WoDoJ6aqtp7miy@{`Y~_2XG&_{ zh%i$qmvS^RdD)vt8L3fY_Q6kNlhH6LM*(DznJJPMas)l<8C$!3V(}a$3Mgoe!|q8} zQ@%Zs2MmBM-@RjzQ5r?a;5Lp?Ml-Z48dvjup`;;a;*TTRAtC%IGg?9!Na4N2*C#{26w3!p9JEZ-u8euTOMOB z*kSfZ1ZFnN?l|*ZrzwUm&3K2WbNuK92^ewD@eqZ`Q<<<*-tS^}6|m*YN|;bFkqTs5 z^v=4#HrKj!kr%hPWkAQJFX>}ugaU#0s0&IG#mH1=8R^ecyga6)5Gqehn^fkI*hYj3 z;C#rJ!N~&Rz+?3acjg&8T3u-%&#^D+8Jp+^U3P?y?nHe&g(Xb6_Y)M>`mqV7%lo4L z-L3^+y|R$S2>f>}zNhMIIRR#4->OjNA^90>j7T6mmqkLAKB=+H*=tKf_#R5C3R%vJ z=xjs=U`1u#G*>Io5cdfNqPl=DV8{4gPH9FgH3-H?R?xu zM4qRY96WkQPx>EX5DKxC%=uO4zQJN+Cbg`M^ZE6o&K4{DTI|7sf5+?3!F| z{RZ!?L2BfEGK*dp6P}UA5m~!ox86=&2KqjdYBt(Naw+J1Yw=vnO4^Nd@I<%#AIg`X z45_cii{Qk|%iV7~vkj!b!1#d-p>f+Y__YwfX5h zobGp_XO)Ks#5|t{0%~C5V|jOPx+lQ_Kphuk zT~gv@$6rusTkbL`;pd^)q4f7qTD?sOeE|r|z8R`@Y$S~`JrL#!Jp79PK0Mx4KKUdIY z=D83=sv6D9npDeF^A4>`*JqVTcoc0RV5 zc9v(H>-Cbw9`f1IE$xze`7QzRuo#XQSZUU*Pp)scUHpPH!Mp$ra`{8{d6DBQg8|ybamXA~LzU6SLcGa7p z1}2sC$4ZT_B-dT*ph9a-9ks7%uUOyk4;Iofa>&DkIBX{7~xtZA^ z4PAP~%D1R@`|6r@-{10}f}(U63fR|yxK1KKdSnwdIO)J<^M08MC-$(i=MJe#&;?8- z_0VIocW}5_Y9$dE`Z@jQnY9oJ?T?oE=ryr28jCCZzP}(w?kR4r1l!^inbDiEU1F}N zWla|V^a|6Bnb)UrsR&PakbP9-U>Y6*MH{#}vYM zi0&c{9|FtM6Am95+A#J1F3wlu=_||)MKdV9M&vU4|1Jw;eFd6zDK>&3jB4LEx~>xp zUtnhb)D|}PG&HOa0{C_>dO2wFB%f&Y)o9aCtDZM~jH}y=oCOnGEuD`$*>3+mwcRvX z$3zr>W-1eBO~V4Ncer2m8?-V9r%J zlHO!a=0q8q>2)Owmos1GMeZ;YR>nkeTj7chb3GP+X7ATLM{z z%=19+(r|K8@laT|cSP>x$6Bp^qy1qN!9;qCWl)%AC*u*1RA#U8aEcVFC9GS zdrnjT^uG*kz~qg==p8tW)y8IihRV_h?pkf`BHY<1A-`J>?ixS3V#(TnocfRMv1#$l zSq%&GCl2%0|L7F|wP=pbPLAW-mmYVAn8e*J1@IdstAe791^wF(G|9$-nlaO=`h*!MA#jej(=*vu6#@Xf?B% zrrkD{0zM=Z6R^qsoSO5;v8pP+;iYobw-8JTIw_3E78*1OJlUc3fXJ+D?EcOuU11j^j>iYT0-iJK$qO7W=`M z2>#8idSi}1_p|9h4GV?Knu7cfwAx=5X+e!Xl`1KVj>WOPPn?1|q3*k6-pQP4)uw&r zDFs%OzQW^pREKpOv6;aXv{}N6h_?;d7JCJu4+tL>YSE>RJW?rs$uC7>kUL8Ndwo`^ zoO}a+OeYakZFAj%vl1!<5E)#WjkBfV?2U{_y7^{mykFEx{>sK~z1=4?{X?JVQw=ZF zM&iPuR7JXv32zG_D6!Zx!*j0g1z|o3kzqXTPMnsIHRWH2_pgVmI?={LWClYCL&y4(~9kSuroi(^i4v&=7Etc~r{x9q;)477+A|lmg9*H|Aw(=67x0 z2G-k5ONZ`|sRb86UwCJ2+Z}sL=3PB;5YPUW8jDza zmk|++tHTzSP0(#Z?%Cdt8R%+Q2~1ka!l<`(ur+D9&|We42>G{4yFD#kRpVFnGZWA=I~H1+%spRN-BiV=*1Zs|W*;;hQLGV+&H96$X@}+PBk# z9#$)!It!?>A6;d3GX-dY^QTF;#^jC`35uL6aIzGnN$?nHr;5VBUXNpIsOhOU>SVqx z@srCGfAR&$FkFK+)Up26=v8H#Y5Am}*|+bd3wBNW^GxLJrDsjd{YTdq1PutfIK>wn zZP!!8hQ^V2ljYdV$~Jz|J}+%ra~;Ku!B^NNxp}}6cMDrZtVkB<|Twdf+%=+Y@TKzYx)CB5FsuN2~L^>ohwn}+zH}T{t zh$hjebZ8@Q`aoHeeO@WFR_D9IPlU|g6IUZ*-YU4!S=lv42v^*=a+Unryg6^( zxg}kaCH_`Yd7C!DMH)sE_e^Ys9V4hHrzB8I0Cy}d2}(~i<;iRGCA4kU!b|z0S+W2b z8E5RT{f@i-;BT8tmh(i+vouVb%~h-*FLoxpfbSudb>UB>&cE*1?l7 zvFxBlqm9wR8#DzwPO;wp{(^&Y(E`MEyr4^ekOEy>`j|jE+9kTO*r_u=^jMz6KTWB; zmyx;u8);~sI{ur`iS7W|d0D2@m7n@FfE!9$ipTac;4UCCRlt#QjYoC79PMXyB@ABw z#;Tl*mIZ`I=W)ZVZiyP1-!F6Y&hr&1BX9{<+R0mCFuJeLMrcEUoFi6YDA#gve-_Q` z(SFME&A;EF8Mb1r*VP)Q_@~&o|xUS=*{{z+3|By#nw5i+gXQ$LfF^!pw)~CkgHaA2EE^{LqS5u9NxhH@+*7#Q;W32uI^QRG0UqDrajrQ>Y z-qND(#q)GH!@C!s31^n^0X!^#of($M&cuElQ%*%9mvyZ`jQ^}u;*a}e zGK628qCU6S1STfW7%eY? zq~y4Hx_z|ML3HLY?@3#X#8Y6y28IAPZdzQQtxGbPj1>P$etR-=y04cb6pc z7HkG<#nncD3NwE(cwmJO#fNtoZi`dxiv5Un2K1?U)X!xR4_kqgn7M@wA zcz3U+$b{mn8lPnoX(OCfU9eq8im5?XVsGm%dd#<2dhT26;mh@(7F0GZ0bDF&_}BT2 zW%MVl^G~yG1T$T*S`DGUk7qh%n;{jR;DeYdnkNF^=o#%@l<#pxbCVEpbHtc)9T@j3 z5Fr+=zOrYWwHpA-c|Q+rwAidzXzx}kNvNtk)vapa?1&ZNtbL5DU4AuV;^lJQNDu4^ zu9|Wlw4>Rw&}B1o)P00QEOK^`84!$2WmumDqkwL6O33Izc|ozjfs!cJQ&jlJN}*Fs zBMFz?Cr0vf!oEH(@8Ejruuqq-`|z}B!+!Zp#5d5Yyil#31VV;i`*LDwGbR{_`W49Y z*y7HoBx5L*2aj5jVSpi}6ZhA`V$P^4KbrcmKV-g`ILs(1^)MzM*1LN zzNwtM)5)dcLG|oqcmQngBa{M9)ju|i;&DGL-=}fv6zAE{2{zr@3xENCimV`(DkU2m z_q%9ZGdxXs8?W$a6q64VyCy8|bPE_#JQ`%RQ$0pZ#z_9fSGY4|s{T zTgvP$wpOrHg51c+zm_5-T#FvBR^x;u#S0g=I8`qw1DTvkte?z0$j$!h*_R|T(;tTs z`6@1fB~X&VO%i!U7|D%QM1zHg?IC#&$a8z_>X(mUsUl6KLFrf2=y5vfdjyL|r+nj9yRS7##S@~8PLO|}md?!+ zs*D;vk@3yZ!(x+JVFhK9q&7FMf0*Uuu%Y+TUqs-TOWtfx|+;4}N;cQ9{*)0JqB&T{YDpEqNxp{jlh zv?)mW_r9wfhJK%_8WLOJ5!P2_$NknV8p4e$iZDOlK} z*+8ML<(ggVF!y_DEmKl!=jQ}wV=RWa7C3IN~2X;*0jX3`WH$1sk}s% zQqJfmn}KXN*ZDR-g5y2oLciieXS2{Y*#zMTGZ)l_@F5HLGadhMowN)%R}(uOTzL=~ zArNdNg+q-yY=eXQfB{(c%nP)jp5a=oR=LurepPW-?f{Jb7`L6UVX=AU>^S$;{pwMp zL0ZGHrG21EZjeJIX~o}Uj9xw3uD@VknabqXxw3Hp;{Jx!A#OjuwUN-ngiq%IMv~M% ztMaQoH7;;modJU)(q3UTFiog6%s;fuMqZNis$TbD`H;I)*A@eu`4P>#AB|(6 zFe*A`6DYB^^V`GC;B-r?h;V(gN&;5IwR~%|Jb@H^v2UzQEb-%3u)Jl~nPYRlmg1=oHWKQN*`XSVUYm5FmbGsl3vBTRbuQmfx?dc*ll0<&Q)EXmYhrKD6#D{;x z2a7KB2jI?#>ri#$Q)72cAFPbpb(hbd^QPCbb{nooG31B&(8}aL+DdB2mH41R3-WSN zm;`vS^gpcV{~nf+nRg80^+2~YC4cTG6? zza{f8u$FYHZVDGs{e#V2&P7qf`*CGN)M~Z2AQ1Xn7xIP_EIJ z@Ucex_?4j>qjNUsNX8vhX=-1x$dfl#>uXORy6NaPnyKI`So_ucmL@c+Z*d?$YoxH! z2v`|O0^YEv4rh)lv&{=VI8ojK6|Vh=_s*KBnzb+_MBn^M4b zltSbu5QdeI%QoU2mM|6@vWG4CBMrjN@Aa1vZCApZF|D_beOiqN=WQI`fBpbB9C}?x zRG4olkTH;Pv z0t&1gjmw%8M7GFoXLViYx01)H0j5Q~lHOSJwROP`|Gp;#__!|(- z_ebfvS+iajz}o;Y&2fy3f9bXQ@$liFA7s96%6!b6hBNYtn1d!_y<3ztV3UIwJiw8b zbwoz=r%8F`wFq(XWn#?3(LYLgUh`trU(G-5u)lY6Btcr>5b*bsf8^g&%ftYTRhmn}CUqpWNhA88bym{ietb<=NY-_oAxAvH z>pAE-NO2>X_H>5?NX>$~GP;&bTB7Ug7gjduGnqBS#l#dHCycLrg zs3f_ZQ%%{9z_@mFRh(s~XQ~MGMU+iAG73B9$~eCks9?vHA~hy5f9YLb+;p#gU36sD z`(sPm!}thw_o+NyBz~ET;z~LTw*Tg&Tes_!>$@`y3%TY}tZ$21ovon>0VedDZG1mP z;jXttq_x?Q|NKT4x^;8m-FbCBV!0F?gRD&jyZ`HZ&fiEg`&YF_%MEqN`3MBL1;+|h zbO@0CklV7idg5W5hg=?=6tA;Fr!G%STF^=eP{fYJR+|ho&8a_wa+FQHqqVeCwgOR zlMo5W1(;!_zRRu5>kA@kP9Fl$DDPa>YqcIe0$v9EtyaysHE)E&AOq zb<85_ZS{xH*H_<{woD?L=*ikH2QHyjb5Q5<0CAUJ1-UB?Rz?ZG#XYCyic@STjeC_0+XatzBL7r@cblh z@<>At3-O0nBgeKyv7E(=c09gLB;;PzZ>)c0-PEKm)Ue36wps+uT>VhC3=D8*&8qO+ z)Ra~Fg;#cLt0fQc?Vn#tCw|_?UwbKs!I_1v`(nM{5-9b&XVq=B@a<*59u{ajHO*($ zUau3utd1~HZr9HsX>>l)2?Un?ml+D_J6ye8i(YXSmGFHKsw<)5>#}Y6)79F#&9rxrM+7>V<|X>k{|VkOlWA~N4qrNZ-b@p0~ECP@Ap|NH`3nPh3SyU zk}C+{`}Y@`1hoeL`4jFn+={ce!x+tt1qr-#_@~QOt>5$R_UY@>>^vNFFU0G@!Cf%z z$d9nlDV!O@4>Xg}l#h)8Jz|tAFbD`>4Q*Va-*rEkyljtDl$@+Iqj(LT6ye1c(ayxJ z^CKpv4%-Ocwz6ga6r}g`NXNC?S*JLIzjoHhJVjSV$$S6J@Uh}rClxJXdFLC$gIlsX z-?s$edaeQTv(UNAmIm=5c;Pm5+;KCjE3_e-^&s&Z_$c}-!7i-mgEZu&4T};s?iKIp?Ei3BWfLbOKm`9PNwecV#kkoQ8#|#tk1K zWSQo{vP^wH$R1KDz{e;re`kp;^*ZPf%Dkq-k3=M@)9%lT(7HBp`Y%qI&qBZFrIS|d$D&-IbT!bELLFOUoQ)PUftIs)#f+6 zuAc~|2;G+HJiD{M(e;SW~d&^ zg5{c)MQdjj3d+J1wa^= zOAK(i*JUVIqgQda1}^T^HuoS4+K#SYZ~C>OLw)>-ipUD6Pm(DL)3Oip{PI5|J+HN z4ZP+2^ug9Qs!-pq32dn>a+_8_K=9+}S5zyqD@L8CKaTw_cKV|9arzVBbI`hNv(p0oeLlwak`6V?uZZY4Z?q-< zK}EO8!H*q4meSvqJq)FV=G>ReD%7uX2ejQ`bQ0*(N&{LZIpbhsc( zDa?AVau?d}ELERb12Z?#Ng28|RIpQms{b^%ic9-6&--Gu5wJQ&PbSeRqC_IlXH~=| ztkqP_d=%ohXKb53Aor-1;Cmmb=l0jagH60(+xxhjbHxHMqv~kMYIIOE{MeKTO8&}P zOI9h!&~uqR<618UBfg|zR<2R2aDwqX5=R`GCb!@%6Rzv0f`VtHKpNyxIhDCW z`Etf*52!5O?OT=9)G1T_O~NaRj0pKd#_9XEvVNvcczDi~p5OTM_Eu!NmdS$`_Hrhz zW4g|?2Az<<$f-H&VDku*a$4dD)etL0)Dl?h8V6HjrE_uG!2I@AjZP{GRV zDv;G2V0PxF zqe;^Imp;fP69FnAW9b2LxFeAo3KhxAkrbDuDHnqH1+jA91h{_Dgbv{98`_XX%raHq z4FoxpjQT0T*4wCV@2i<~dsj{C%8zs169f6O(E!*Pp^c+c8M;RUE4V${{hWh@(%0YieDpYi0ryYRLnMo)uKaVL zTkd;}hM|D}2%P%MkEJ`VTr= z{}N>N4}(o%wfY3|Pq|L@bNgsyZY?4~XdAEWsQXbrph4=lW9OfRX znx%Lx)I<`_Y$4I|O)~RnWcZ={XUUN-IFnWHZ_QvhVu$ST2LtLcN}X&8h=~J{KTWjy zXq=#%X4zM@+CZ*Wb37*nzhfV2X#)7g>nA{HV7&iW*FN4Y2oW!k-z`^cu`6>LOj$2g z`nla~eZRE8?je+ve?oTzU+*y&G11IGp{h?Uo!6{9_G`MMg4#X2?eVtkb=pYs_#uMr zn=tv8?yqvnAdPvU>V7EMMH2yzdPyahOtDV6nHg`C{})k=DC*TRc)&a4`NTmhs&L(5 z=qSGjfgNYR!x<{@r-zGXt%^LYx?aLx{sf$492C{!Q#)yCSJG2}-S4Jsf*ozKJG@|X z2nk8j0~Z|Rh!NlP<1CDhDQ0G(GU)ZOBe(b)ua0{GBU4KmafQ_UJ}+PJU&xOBXu*vr zi-_!795Iio8>F9Lb4KLBxC2;?~T_AE;ud7 zJyaw8Ans_bO=a$VS8rdPqjr=gXg>b_MgeC*#`SGp&&^B7KilEjy4dNRtNzy^CBxZl zfG>|n6~6|rH3xLpS(a@ZKE-%0gGDh-HiWYw0T}64XTqmhdrz)WYuF7p5XK0*pEnKP zxn;DGadpJ;+tune&rwHh`)!-9?f&b=(1Y6T9j>F0-7%iuf43G$kJOi1kSP}GAV;{R zao~=~k0v29>0oj~=cT=fc;jL)q0V} zl#E!j1v(5sXAsQ!+H9MBuDwSbIOGcA;d-2?pnTF6f$YLM@EQKdl|}KF3RP6J9_ID9 zXmQi_+NOWOTC`jNq1d=wnj4e+S_9)Msp4-xvd+{EKI`wd;t^-eVH@7HGM&{T1(eTrcElPQnapK`hi49hMwA$#mTnF3U%_qx(re}@jSX6GxN<33)}AMW;5f1 z&{jPdY~g$v(KcX_O}6z%%ZSA}ob7S29#}2N&sLG2IYg76rJ1Zs;^8TJCfyI2y z`mOjdEBSU>E;c8<1Ea2-wW*P8wn6&&jJPQm?fvVLy6h8Ew82onXh2(5gN@%YMfOy0 zv08%D%bCc^>4VE*zUt(F@pO)8EIR3T8!2S3`KD=$c1<`?sQVjpOVX>7DXWb?q~*K2 z!fmX7lE$h`?NuE9fN~2U{ch;RY8)!9Z<2mX$2R9{pbjBvP-sCQ_O@Xl;~3O&eZYj- zV#lOet|>#VbduN>hWnPI(2Nqx%eoM&D9n+$lN+i{)McIWF) zGdQ+jK;a++VF5P0E?CrC^vKIf@!#7xJ5_rHWY{Qm4#mzL$=N;6%mN3ZI91vks z_f1*NN$=3esO^;Cb1kE}hUqQ|V>E>eWdx&O%deClF9>UNUu$R2}wRt!}g$pb>H%C-|WCq8N6}3>Wlvk=G_5 z7ijC#Hhw
    Wfq?bbpssf8kIzoAWjicSJE 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 N%g;ap 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 literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/refresh.ico b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/refresh.ico new file mode 100644 index 0000000000000000000000000000000000000000..3db4884c6c07556309eb97e59c0b512800e61019 GIT binary patch literal 894 zcmaiy%}WAN6veN!Xxl2<)w2H~TJ{$NEovJP)iPSf^a0jJqL7G!+!!tT0&yVeQyE6G zv?MDFHJQSsOw-V5wCL!A+h9a*<_%|l_q==F8-~b&tEq`FT4=C=s2Qpqvx?d6CH>1 zJrzS|_*p4~1e~Kxgm_EcqBHz4#c3{~IUw%3h)dZf`175g{i3%i;{@Q zr(@O4)I#x$?k~M2FJ2O7fY>>62oZ6z$CnZQOd=@!UV9&ZHwg17p01C%#Qv~rmLUX3 zD9in3o;=+V{hwneW)3YP(ouyu{wOSm|9oqLAqzw(D+Bym{wRiBGcX4?#w%rmxmn=& zdLi?0u^W+XUVASRvyWG11GL^sbe|$hszg2?<`iZ%-tuFVj))}Gj;nP{%}SJNB+6m! EHy+77CIA2c literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/sdv.ico b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/sdv.ico new file mode 100644 index 0000000000000000000000000000000000000000..7e01bb5ccdd585cabb8c78913182f3c2779835d9 GIT binary patch literal 15086 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 X8Xuz*DVouV00000NkvXXu0mjf6#Vt8 literal 0 HcmV?d00001 diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/zoom.png b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Icons/zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..875f7437f22c177582123221ebb3adef55ed2095 GIT binary patch literal 736 zcmV<60w4W}P)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;R!KxbRCwBy(oIN{0T>7H|NAk0_t9J0943~yoaUy1 z6%|2Imn3LyR+5C+!44S((WzqxX%rnKgAN_K6cIr)p&+G89})&C6r}0)ZgWeUv$oWH zzn@M)=@#~f|Lx(&!^6W65qj@E<(m)gY>p&m1M%cseQsgVm6^{v1gmwT#qg}e0V)|LBtfs^O1RUFvu4g0oL z?`qucVRe>+tQ*M6CX(qKMux{Q^zxNPhVC7Bcynqcz;?AC=`Jl5y|tby)>dSJonztP zcvv|G>+BBHG&aHQt+U9g-jQzu_S4k#o>FItqu6EzfdR)d;28!S7_daJ@I@%w>;@5Y zF)t8_r@W%eiACLntea2`f^3*jbQ6Y2&@~Mf-T{tdH{=8O^`aP!CDLv|EP-MWIEI0& z8CXzEEGY(LMMw7AS17VNnin84-%fmvRk*f#ge8Rl5LCm&vT7jrQ$sqPMM{cb%SN>} zFObgsxSY;N0kO;}RMq;xGb|Lt#Imd*Gnd2U#}Uj;$I!Xov={t?)~?WDMb*OPRh70) z)oxhrCCJPs@g*iOo)f_@sh86A$rhzmVVFt6Zo@* z5Eg4lo4<(aN_z4H{LvZjL{F$-#1umf-T4P0q6k`>I?UW{~K7DUjqO)u~39u SFDPdK0000 + { + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + this.pane.OutputStringThreadSafe(message); + }).FileAndForget("OutputWindowEvent"); + } + } + + public override void WriteLine(string message) + { +#pragma warning disable VSTHRD010 // Thread check inside this.Write(). + this.Write(Environment.NewLine + message); +#pragma warning restore VSTHRD010 + } + + private bool EnsurePane() + { + if (this.pane == null) + { +#pragma warning disable VSTHRD108 // Assert thread affinity unconditionally. + ThreadHelper.ThrowIfNotOnUIThread(); +#pragma warning restore VSTHRD108 + + var guid = Guid.NewGuid(); + this.outputWindowService.CreatePane(ref guid, this.paneName, fInitVisible: 1, fClearWithSolution: 1); + this.outputWindowService.GetPane(ref guid, out this.pane); + } + + return this.pane != null; + } + } +} diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/ProjectHelper.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs similarity index 100% rename from tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/ProjectHelper.cs rename to tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/Resources.Designer.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Resources.Designer.cs similarity index 100% rename from tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/Resources.Designer.cs rename to tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Resources.Designer.cs diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/Resources.resx b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Resources.resx similarity index 100% rename from tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio.Core/Resources.resx rename to tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Resources.resx diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Resources1.Designer.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Resources1.Designer.cs new file mode 100644 index 00000000..8c88ade5 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/Resources1.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace CodeQL.VisualStudio { + using System; + + + ///

    + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CodeQL.VisualStudio.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} From 576ca88eda28c514f9eb830fc79202767963115f Mon Sep 17 00:00:00 2001 From: Jacob Ronstadt Date: Fri, 27 Jun 2025 14:06:18 -0700 Subject: [PATCH 05/18] bug fixes and improvements --- .../CodeQL.VisualStudio.csproj | 9 +- .../CodeQL.VisualStudio/CodeQLCommand.cs | 35 ++++-- .../CodeQL.VisualStudio/CodeQLPackage.cs | 3 +- .../CodeQL.VisualStudio/CodeQLPackage.vsct | 11 +- .../CodeQL.VisualStudio/CodeQLRunner.cs | 106 +++++++++--------- .../CodeQL.VisualStudio/CodeQLService.cs | 67 +++++------ .../CodeQL.VisualStudio/InstallWindow.xaml.cs | 2 +- .../CodeQL.VisualStudio/ProjectHelper.cs | 12 ++ .../CodeQL.VisualStudio/VSPackage.resx | 4 +- 9 files changed, 137 insertions(+), 112 deletions(-) diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj index 147e4e76..2c786eea 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj @@ -128,6 +128,9 @@ 4.5.4 + + 3.0.115.5763 + @@ -138,7 +141,9 @@ Designer Resources1.Designer.cs - + + Designer + @@ -170,7 +175,7 @@ true - Menus.ctmenu + Menus.ctmenu diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs index 1c00cf51..ff4af9e3 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs @@ -1,6 +1,13 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Microsoft.CodeQL.Controls; +using Microsoft.CodeQL.Options; +using Microsoft.CodeQL.Views; +using Microsoft.Sarif.Viewer.Interop; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Threading; using System; using System.Collections.Generic; using System.ComponentModel.Design; @@ -10,13 +17,7 @@ using System.Runtime.InteropServices; using System.Security.Policy; using System.Threading.Tasks; - -using Microsoft.CodeQL.Options; -using Microsoft.CodeQL.Controls; -using Microsoft.CodeQL.Views; -using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Shell.Interop; -using Microsoft.VisualStudio.Threading; +using System.Windows; namespace Microsoft.CodeQL.Core @@ -191,6 +192,7 @@ private async System.Threading.Tasks.Task MenuItemCallbackAsync(object sender, E catch (Exception ex) { CodeQLService.Instance.ClearTask(); + MessageBox.Show(ex.GetType().ToString()); VsShellUtilities.ShowMessageBox(Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider, $"CodeQL database create failed. " + ex.Message + " See output for details.", null, // title @@ -206,7 +208,22 @@ private async System.Threading.Tasks.Task MenuItemCallbackAsync(object sender, E Trace.WriteLine($"Starting CodeQL analysis using {_currentDropDownComboChoice}"); try { - await CodeQLService.Instance.RunCodeQLQueryAsync(_currentDropDownComboChoice.Trim()); + var sarifResults = await CodeQLService.Instance.RunCodeQLQueryAsync(_currentDropDownComboChoice.Trim()); + var sarifViewer = new SarifViewerInterop(Package.GetGlobalService(typeof(SVsShell)) as IVsShell); + if (false && sarifViewer.IsSariferExtensionInstalled) + { + if (!sarifViewer.IsViewerExtensionLoaded) + { + sarifViewer.LoadSariferExtension(); + } + await sarifViewer.OpenSarifLogAsync(sarifResults); + } + else + { + //TODO + //if (CodeQLGeneralOptions.Instance.AutomaticallyOpenResults) { } + Microsoft.VisualStudio.Shell.VsShellUtilities.OpenDocument(this.ServiceProvider, sarifResults); + } } catch (Exception ex) { @@ -223,7 +240,7 @@ private async System.Threading.Tasks.Task MenuItemCallbackAsync(object sender, E break; case CodeQLStopCommandId: - CodeQLService.Instance.CancelIfRunning(); + CodeQLService.Instance.CancelIfRunningAsync().FileAndForget("Codeql.CancelIfRunning"); break; case CodeQLDatabaseCommandId: try diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs index 395db9e4..5c0dfc8e 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs @@ -46,12 +46,11 @@ public sealed class CodeQLPackage : AsyncPackage /// OpenSarifFileCommandPackage GUID string. /// public const string PackageGuidString = "3718ce5a-503f-4c55-8f70-3a4cc34fb1fb"; - public const string OptionCategoryName = "SARIF Viewer"; public const string CodeQLCategoryName = "CodeQL"; public const string OptionPageName = "General"; public const string CodeQLPageName = "General"; public const string ColorsPageName = "Colors"; - public const string OutputPaneName = "SARIF Viewer"; + public const string OutputPaneName = "CodeQL"; public const string CodeQLOptionCategoryName = "CodeQL"; public const string CodeQLOptionPageName = "General"; diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct index b6d8b3b0..e9686d8a 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct @@ -145,7 +145,16 @@ Run Selected CodeQL Suites - + diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs index c0ee5e87..5427f3c6 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs @@ -1,20 +1,22 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using Microsoft.VisualStudio.CodeAnalysis.CodeQL.Exceptions; +using Microsoft.VisualStudio.Shell; +using Newtonsoft.Json.Linq; using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Management; using System.Net.Http; using System.Net.Http.Headers; +using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using System.Windows.Documents; - -using Microsoft.VisualStudio.CodeAnalysis.CodeQL.Exceptions; - -using Newtonsoft.Json.Linq; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrackBar; namespace Microsoft.VisualStudio.CodeAnalysis.CodeQL.Runner { @@ -144,6 +146,13 @@ public sealed class CodeQLRunner } }; + // Packs, queries, suites, etc that should not be used + private static readonly HashSet ExclusionSet = new HashSet() + { + "windows_mustfix_partial.qls", // deprecated + "windows_recommended_partial.qls", // deprecated + }; + public void Initialize(string sourceDir = "", string buildEnv = "", Action outputFunc = null) { analysisDir = sourceDir; @@ -200,7 +209,18 @@ private CodeQLRunner() } } - + + public bool IsExclusion(string item) + { + foreach (var exclusion in ExclusionSet) + { + if (item.Contains(exclusion)) + { + return true; + } + } + return false; + } /// @@ -326,11 +346,12 @@ public async Task> FindQueriesAsync(string qlpack, bool queriesNSui if (line.Trim().Trim(new char[] { ',', '\"' }).Trim().EndsWith(ext)) { string query = line.Replace("\"", string.Empty).Replace("\\\\", "/").Replace("\\", "/").Trim(',').Trim(); - queries.Add(query); + if (!IsExclusion(query)) + { + queries.Add(query); + } } - } - return queries; // TODO do this with json } @@ -355,7 +376,11 @@ public async Task> FindPacksAsync(string additionalSearchPath = nul if (line.Contains("\"path\"") && line.Contains("qlpack.yml")) { - packs.Add(line.Replace("\"path\" : ", string.Empty).Replace("\"", string.Empty).Replace("\\\\", "/").Replace("\\", "/").Trim()); + string pack = line.Replace("\"path\" : ", string.Empty).Replace("\"", string.Empty).Replace("\\\\", "/").Replace("\\", "/").Trim(); + if (!IsExclusion(pack)) + { + packs.Add(pack); + } } } @@ -484,13 +509,12 @@ public async Task GetDBDiagAsync() public async Task RunCMDProcAsync(string strCmdText, Action proccessExitedFunc, CancellationToken ct) { using (var codeqlProc = new System.Diagnostics.Process()) - using (ct.Register(() => + using (ct.Register( () => { - if (codeqlProc != null) - { - KillProcessAndChildren(codeqlProc.Id); - } - _ = eventHandled.TrySetCanceled(); + codeqlProc.CancelOutputRead(); + codeqlProc.CancelErrorRead(); + codeqlProc.Close(); + eventHandled.TrySetCanceled(); })) { codeqlProc.StartInfo.FileName = "cmd.exe"; @@ -535,54 +559,22 @@ public async Task RunCMDProcAsync(string strCmdText, Action - /// Kills a process and all its child processes. - /// - /// The process ID to kill. - private void KillProcessAndChildren(int pid) - { - // Cannot close 'system idle process'. - if (pid == 0) - { - return; - } - - var searcher = new ManagementObjectSearcher( - "Select * From Win32_Process Where ParentProcessID=" + pid); - ManagementObjectCollection moc = searcher.Get(); - foreach (ManagementObject mo in moc) - { - KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"])); - } - - try - { - var proc = System.Diagnostics.Process.GetProcessById(pid); - proc.Kill(); - } - catch (ArgumentException) - { - // Process already exited. - } - } /// /// Generates a CodeQL database for the specified project file. @@ -627,6 +619,7 @@ public async Task GenerateDatabaseAsync(string buildCommand, CancellationToken c } await RunCMDProcAsync(strCmdText, proccessExitedFunc, ct); + DatabasePath = dbPath; } @@ -680,6 +673,7 @@ public async Task RunCodeQLQuerySetAsync(string query, CancellationToken codeQLExe, "database", "analyze", "\"" + dbPath + "\"", "-v", + "--no-sarif-minify", "--format=sarifv2.1.0", "--output=" + "\"" + resultsPath + "\"", useThreads, diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs index 838424fc..e0fbef99 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs @@ -1,6 +1,15 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using EnvDTE; +using Microsoft.CodeAnalysis.Sarif; +using Microsoft.CodeQL.Options; +using Microsoft.Sarif.Viewer.Interop; +using Microsoft.VisualStudio.CodeAnalysis.CodeQL.Runner; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Threading; +using Microsoft.VisualStudio.VSHelp; using System; using System.Collections.Generic; using System.Diagnostics; @@ -11,15 +20,6 @@ using System.Threading; using System.Threading.Tasks; -using EnvDTE; - -using Microsoft.CodeAnalysis.Sarif; -using Microsoft.CodeQL.Options; -using Microsoft.VisualStudio.CodeAnalysis.CodeQL.Runner; -using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Shell.Interop; -using Microsoft.VisualStudio.Threading; - namespace Microsoft.CodeQL.Core { @@ -105,21 +105,18 @@ public void InitTask() _cancelToken = new CancellationTokenSource(); } - public void CancelIfRunning() + public async Task CancelIfRunningAsync() { - if (_taskCompleted != null && _cancelToken != null) + if (_cancelToken != null && !_cancelToken.IsCancellationRequested) { - if (!_cancelToken.IsCancellationRequested) - { - _cancelToken.Cancel(); - } + _cancelToken.Cancel(); + } - if (!_taskCompleted.Task.IsCompleted) - { - _ = _taskCompleted.TrySetCanceled(); - } + if (_taskCompleted != null && !_taskCompleted.Task.IsCompleted) + { + _taskCompleted.TrySetCanceled(); } - ThreadHelper.JoinableTaskFactory.Run(() => ProjectHelper.HideProgressAsync()); + await ProjectHelper.HideProgressAsync(); } private void HandleKeyCollision(string existingKey, string newValue) { @@ -274,7 +271,7 @@ public static bool CodeQLIsInstalled() return CodeQLRunner.IsInstalled(); } - public async System.Threading.Tasks.Task RunCodeQLQueryAsync(string query) + public async System.Threading.Tasks.Task RunCodeQLQueryAsync(string query) { if (!_queryDict.TryGetValue(query, out string querySet)) { @@ -301,22 +298,9 @@ public async System.Threading.Tasks.Task RunCodeQLQueryAsync(string query) ram: CodeQLGeneralOptions.Instance.MemoryUsage, threads: CodeQLGeneralOptions.Instance.Threads, additionalSearchPath: CodeQLGeneralOptions.Instance.AdditionalQueryLocations); - try - { - //await ErrorListService.ProcessLogFileWithTracesAsync(sarifResults, ToolFormat.None, promptOnLogConversions: true, cleanErrors: true, openInEditor: false).ConfigureAwait(continueOnCapturedContext: false); - //new DataService().CloseEnhancedResultData(cookie: 0); - } - catch (InvalidOperationException) - { - VsShellUtilities.ShowMessageBox(Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider, - string.Format(Resources.LogOpenFail_InvalidFormat_DialogMessage, Path.GetFileName(sarifResults)), - null, // title - OLEMSGICON.OLEMSGICON_CRITICAL, - OLEMSGBUTTON.OLEMSGBUTTON_OK, - OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); - } - _ = _taskCompleted.TrySetResult(true); + _ = _taskCompleted.TrySetResult(true); + return sarifResults; } private void CodeQLOutput(string message) @@ -327,10 +311,15 @@ private void CodeQLOutput(string message) public async System.Threading.Tasks.Task GenerateCodeQLDatabaseAsync() { await ProjectHelper.ShowProgressAsync("Generating CodeQL Database..."); + // don't need to create again if the project is clean and a database exists. + if (await ProjectHelper.IsProjectDirtyAsync() && Directory.Exists(CodeQLRunner.Instance.DatabasePath)) + { + return true; + } string arch = ""; string configName = ""; - + string projectName = ""; await ThreadHelper.JoinableTaskFactory.RunAsync(async () => { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); @@ -342,7 +331,7 @@ await ThreadHelper.JoinableTaskFactory.RunAsync(async () => arch = config.PlatformName; configName = config.ConfigurationName; - + projectName = activeProject.UniqueName; string projectDir = ProjectHelper.GetProjectDirectory(activeProject); string startCommand = "\"" + Path.Combine(ProjectHelper.GetVisualStudioFolder(), @"VC\Auxiliary\Build\vcvarsall.bat") + "\" " + arch + " && cd /d \"" + projectDir + "\" &&"; @@ -355,7 +344,7 @@ await ThreadHelper.JoinableTaskFactory.RunAsync(async () => } else { - buildCmd = "msbuild /t:rebuild /p:Configuration=" + configName + " /p:Platform=" + arch; + buildCmd = "msbuild "+projectName+" /t:rebuild /p:Configuration=" + configName + " /p:Platform=" + arch; } diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/InstallWindow.xaml.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/InstallWindow.xaml.cs index beb9fe8c..5d223117 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/InstallWindow.xaml.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/InstallWindow.xaml.cs @@ -92,7 +92,7 @@ private void BackgroundWorkCompleted(object sender, RunWorkerCompletedEventArgs private void ButtonCancel_Click(object sender, RoutedEventArgs e) { backgroundWorker.CancelAsync(); - CodeQLService.Instance.CancelIfRunning(); + ThreadHelper.JoinableTaskFactory.Run(() => CodeQLService.Instance.CancelIfRunningAsync()); this.DialogResult = false; this.Close(); } diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs index 9419d97b..2ec10f50 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs @@ -291,6 +291,18 @@ internal static string GetVisualStudioFolder() return sc.GetInstanceForCurrentProcess().GetInstallationPath(); } + internal static async System.Threading.Tasks.Task IsProjectDirtyAsync() + { + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + + Project project = GetActiveProject(); + if (project != null) + { + return project.IsDirty; + } + return true; + } + internal static async System.Threading.Tasks.Task BuildProjectAsync() { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/VSPackage.resx b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/VSPackage.resx index bf73b12f..11bf518a 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/VSPackage.resx +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/VSPackage.resx @@ -118,9 +118,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Microsoft SARIF Viewer + Microsoft CodeQL - Visual Studio Static Analysis Results Interchange Format (SARIF) log file viewer + Visual Studio CodeQL \ No newline at end of file From 2a3043294e4ba0f9a404e0492cdf31e6be720500 Mon Sep 17 00:00:00 2001 From: Jacob Ronstadt Date: Mon, 30 Jun 2025 15:58:35 -0700 Subject: [PATCH 06/18] only regenerate database if project is dirty --- .../CodeQL.VisualStudio/BuildEvents.cs | 56 ++++++++++++ .../CodeQL.VisualStudio.csproj | 1 + .../CodeQL.VisualStudio/CodeQLCommand.cs | 2 +- .../CodeQL.VisualStudio/CodeQLPackage.cs | 30 +++--- .../CodeQL.VisualStudio/CodeQLPackage.vsct | 2 +- .../CodeQL.VisualStudio/CodeQLRunner.cs | 29 +++++- .../CodeQL.VisualStudio/CodeQLService.cs | 91 ++++++++++++++++++- .../CodeQL.VisualStudio/ProjectHelper.cs | 63 ++++++++++++- 8 files changed, 249 insertions(+), 25 deletions(-) create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/BuildEvents.cs diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/BuildEvents.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/BuildEvents.cs new file mode 100644 index 00000000..053c0b16 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/BuildEvents.cs @@ -0,0 +1,56 @@ +using Microsoft.CodeQL.Core; +using Microsoft.VisualStudio; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.CodeQL +{ + public class MyBuildEventsHandler : IVsUpdateSolutionEvents + { + public int UpdateProjectCfg_Begin(IVsHierarchy pHierarchy, IVsCfg pCfg) + { + return VSConstants.E_NOTIMPL; + } + + public int UpdateSolution_Begin(ref int pfCancelUpdate) + { + return VSConstants.E_NOTIMPL; + } + + public int UpdateSolution_Done(int fSucceeded, int fModified, int fCancelCommand) + { + //TODO check if build was successful + bool isProjDirty = true; + ThreadHelper.JoinableTaskFactory.Run(async () => isProjDirty = await ProjectHelper.IsProjectDirtyAsync()); + + if (isProjDirty) // update the buildguid if the code changed + { + Guid guid = Guid.NewGuid(); + CodeQLService.Instance.UpdateBuildInfo(guid.ToString()); + } + return VSConstants.S_OK; + } + + public int UpdateSolution_StartUpdate(ref int pfCancelUpdate) + { + return VSConstants.E_NOTIMPL; + } + + public int UpdateSolution_Cancel() + { + return VSConstants.E_NOTIMPL; + } + + public int OnActiveProjectCfgChange(IVsHierarchy pIVsHierarchy) + { + return VSConstants.E_NOTIMPL; + } + + // Implement other methods as needed (can return VSConstants.E_NOTIMPL if unused) + } +} \ No newline at end of file diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj index 2c786eea..f825dc9c 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj @@ -48,6 +48,7 @@ 4 + diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs index ff4af9e3..362d00fc 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs @@ -62,7 +62,7 @@ internal class CodeQLCommand /// /// Command menu group (command set GUID). /// - public static readonly Guid CommandSet = new Guid("4fc96981-3ec2-43c7-acf0-96d73b1203e8"); + public static readonly Guid CommandSet = new Guid("D62F3B56-93CF-4AC2-BCD7-ABDE6EF7FE25"); /// /// VS Package that provides this command, not null. diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs index 5c0dfc8e..ca9a7d9a 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs @@ -1,16 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using System.Collections.Generic; -using System.ComponentModel.Design; -using System.Configuration; -using System.IO; -using System.Runtime.InteropServices; -using System.Threading; - using EnvDTE80; - using Microsoft.CodeAnalysis.Sarif; using Microsoft.CodeQL.Core; using Microsoft.CodeQL.Options; @@ -20,9 +11,14 @@ using Microsoft.VisualStudio.Shell.Events; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Text.Tagging; - using Newtonsoft.Json; - +using System; +using System.Collections.Generic; +using System.ComponentModel.Design; +using System.Configuration; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; using Task = System.Threading.Tasks.Task; namespace Microsoft.CodeQL @@ -130,10 +126,20 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke SolutionEvents.OnAfterCloseSolution += this.SolutionEvents_OnAfterCloseSolution; SolutionEvents.OnAfterBackgroundSolutionLoadComplete += this.SolutionEvents_OnAfterBackgroundSolutionLoadComplete; SolutionEvents.OnBeforeOpenProject += this.SolutionEvents_OnBeforeOpenProject; - + + IVsSolutionBuildManager buildManager = (IVsSolutionBuildManager)ServiceProvider.GlobalProvider.GetService(typeof(SVsSolutionBuildManager)); + buildManager.AdviseUpdateSolutionEvents(new MyBuildEventsHandler(), out _); + return; } + private void OnBuildBegin() + { + ThreadHelper.ThrowIfNotOnUIThread(); + // this is called when build starts. + // this can be used to start the codeql file watcher. + //this.codeqlFileMonitor?.StartWatching(); + } private void SolutionEvents_OnBeforeOpenProject(object sender, EventArgs e) { // start watcher when the solution is opened. diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct index e9686d8a..dfa49c68 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct @@ -194,7 +194,7 @@ - + diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs index 5427f3c6..063de4de 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs @@ -156,6 +156,8 @@ public sealed class CodeQLRunner public void Initialize(string sourceDir = "", string buildEnv = "", Action outputFunc = null) { analysisDir = sourceDir; + DatabaseDirectory = Path.Combine(analysisDir, "codeql_db"); + if (!Directory.Exists(analysisDir)) { throw new Exception("Analysis directory does not exist: " + analysisDir); @@ -483,11 +485,30 @@ public async Task CountDBSourceCodeLinesAsync() /// Adds diagnostic information to the database. /// /// Diagnostic info to add to database. - /// SourceID to use. + /// Severity of the diagnostic information ("error", "warning", "note"). /// A representing the asynchronous operation. - public async Task AddDBDiagInfoAsync(string message, int sourceId) + public async Task AddDBDiagInfoAsync(string projectDir, string message, int sourceId, string severity="note", bool deletePrev = true) { - _ = await RunCodeQLProcAsync("database add-diagnostic --plaintext-message=\"" + message + "\" --source-id=" + sourceId.ToString() + " --source-name=CodeqlVSExt", workingDir: analysisDir); + try + { + if (deletePrev) + { + foreach (string f in Directory.EnumerateFiles(Path.Combine(projectDir, "codeql_db", "diagnostic"), "cli-diagnostics-add-*.json")) + { + File.Delete(f); + } + } + + if (severity != "error" && severity != "warning" && severity != "note") + { + throw new ArgumentException("Invalid severity level. Use 'error', 'warning', or 'note'."); + } + _ = await RunCodeQLProcAsync("database add-diagnostic --plaintext-message=\"" + message + "\" --source-id=" + sourceId.ToString() + " --source-name=CodeqlVSExt" + " --severity=" + severity + " codeql_db", workingDir: analysisDir); + } + catch (Exception ex) + { + throw new Exception("Error adding diagnostic information to database: " + ex.Message, ex); + } } /// @@ -597,7 +618,7 @@ public async Task GenerateDatabaseAsync(string buildCommand, CancellationToken c } string strCmdText = string.Empty; - string dbPath = Path.Combine(analysisDir, "codeql_db"); + string dbPath = System.IO.Path.Combine(analysisDir, "codeql_db"); string useThreads = string.IsNullOrWhiteSpace(threads) ? "" : " --threads=" + threads + " "; string useRam = string.IsNullOrWhiteSpace(ram) ? "" : " --ram=" + ram + " " ; diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs index e0fbef99..56447409 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs @@ -10,6 +10,7 @@ using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Threading; using Microsoft.VisualStudio.VSHelp; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; @@ -20,15 +21,52 @@ using System.Threading; using System.Threading.Tasks; - namespace Microsoft.CodeQL.Core { + internal class CodeQLService : IDisposable { private static CodeQLService _instance = null; private CancellationTokenSource _cancelToken; private TaskCompletionSource _taskCompleted; + // service per project? + + + private class BuildInfo + { + public BuildInfo() + { + BuildGuid = "-1"; + SourceId = -1; + ProjectName = null; + } + public int SourceId; + public string BuildGuid; + public string ProjectName; + + public class LogEntry + { + public DateTime timestamp { get; set; } + public Source source { get; set; } + public string plaintextMessage { get; set; } + public string severity { get; set; } + } + + public class Source + { + public string id { get; set; } + public string name { get; set; } + } + // override equals + + } + + + + + private BuildInfo _buildInfo; + /// /// Dictionary of query names to be displayed in the UI, and their full path. /// @@ -46,6 +84,21 @@ public List AvailableQueries set { } } + public void UpdateBuildInfo(string buildGuid, string projectName = null) + { + _buildInfo.BuildGuid = buildGuid; + if (projectName != null) + { + _buildInfo.ProjectName = projectName; + _buildInfo.SourceId = ProjectHelper.CreateNumericalHash(projectName); + } + else + { + _buildInfo.ProjectName = ProjectHelper.GetActiveProjectName(); + _buildInfo.SourceId = ProjectHelper.CreateNumericalHash(_buildInfo.ProjectName); + } + } + public void Dispose() { if (_taskCompleted != null) @@ -80,6 +133,7 @@ private CodeQLService() _taskCompleted = null; _cancelToken = null; _queryDict = new Dictionary(); + _buildInfo = new BuildInfo(); } public bool IsCodeQLTaskRunning() @@ -215,6 +269,29 @@ public void RemoveQuery(string query) } } + public async Task UpdateDatabaseBuildInfoAsync() + { + await CodeQLRunner.Instance.AddDBDiagInfoAsync(ProjectHelper.GetProjectDirectory(ProjectHelper.GetActiveProject()), + _buildInfo.BuildGuid, + _buildInfo.SourceId); + } + + private async Task GetDatabaseBuildGuidAsync() + { + string dbInfo = await CodeQLRunner.Instance.GetDBDiagAsync(); + + var entries = JsonConvert.DeserializeObject>(dbInfo); + var ret = entries + .Where(e => e.source?.name == "CodeqlVSExt" && !string.IsNullOrEmpty(e.plaintextMessage)) + .Select(e => e.plaintextMessage) + .ToList().FirstOrDefault(); + if(ret == null) + { + return ""; + } + return ret; + } + public async System.Threading.Tasks.Task InstallCodeQLPacksAsync(HashSet packs, bool prerelease) { await CodeQLRunner.Instance.InstallDefaultPacksAsync(packs, prerelease); @@ -262,6 +339,7 @@ public async System.Threading.Tasks.Task InstallCodeQLAsync(string version, stri } } + public static void CodeQLUpateExePath() { CodeQLRunner.UpdateCodeQLExePath( CodeQLGeneralOptions.Instance.CliPath ?? "" ); @@ -312,11 +390,12 @@ public async System.Threading.Tasks.Task GenerateCodeQLDatabaseAsync() { await ProjectHelper.ShowProgressAsync("Generating CodeQL Database..."); // don't need to create again if the project is clean and a database exists. - if (await ProjectHelper.IsProjectDirtyAsync() && Directory.Exists(CodeQLRunner.Instance.DatabasePath)) + + if(!(await ProjectHelper.IsProjectDirtyAsync()) && _buildInfo.BuildGuid.Equals((await GetDatabaseBuildGuidAsync()))) { + _taskCompleted.TrySetResult(true); return true; } - string arch = ""; string configName = ""; string projectName = ""; @@ -344,11 +423,13 @@ await ThreadHelper.JoinableTaskFactory.RunAsync(async () => } else { - buildCmd = "msbuild "+projectName+" /t:rebuild /p:Configuration=" + configName + " /p:Platform=" + arch; + buildCmd = "msbuild " + projectName + " /t:rebuild /p:Configuration=" + configName + " /p:Platform=" + arch; } - await CodeQLRunner.Instance.GenerateDatabaseAsync(buildCmd, _cancelToken.Token, ram: CodeQLGeneralOptions.Instance.MemoryUsage, threads: CodeQLGeneralOptions.Instance.Threads ); + await CodeQLRunner.Instance.GenerateDatabaseAsync(buildCmd, _cancelToken.Token, ram: CodeQLGeneralOptions.Instance.MemoryUsage, threads: CodeQLGeneralOptions.Instance.Threads); + + await UpdateDatabaseBuildInfoAsync(); _taskCompleted.TrySetResult(true); return true; } diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs index 2ec10f50..76f96588 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.IO; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -12,6 +13,11 @@ using Microsoft.VisualStudio.Setup.Configuration; using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.VCProjectEngine; +using System.Windows.Documents; +using System.Collections.Generic; +using System.Linq; + namespace Microsoft.CodeQL { @@ -199,6 +205,22 @@ internal static Project GetActiveProject() return activeSolutionProjects.GetValue(0) as Project; } + internal static VCProject GetVCProject() + { + ThreadHelper.ThrowIfNotOnUIThread(); + Project activeProject = GetActiveProject(); + if (activeProject != null && IsVCProject(activeProject)) + { + return activeProject.Object as VCProject; + } + return null; + } + + internal static string GetActiveProjectName() + { + ThreadHelper.ThrowIfNotOnUIThread(); + return GetActiveProject().UniqueName; + } internal static string GetProjectFileName(Project project) { @@ -227,6 +249,30 @@ internal static string GetProjectFileName(Project project) return fileName; } + /// + /// Creates a numerical hash from a string using FNV-1a algorithm. + /// + /// The input string to hash + /// A 32-bit integer hash of the string + internal static int CreateNumericalHash(string input) + { + if (string.IsNullOrEmpty(input)) + return 0; + + // FNV-1a algorithm constants for 32-bit hash + const uint FNV_PRIME = 16777619; + const uint FNV_OFFSET_BASIS = 2166136261; + + uint hash = FNV_OFFSET_BASIS; + + foreach (char c in input) + { + hash ^= c; + hash *= FNV_PRIME; + } + + return unchecked((int)hash); + } internal static string GetProjectDirectory(Project project) { ThreadHelper.ThrowIfNotOnUIThread(); @@ -291,18 +337,31 @@ internal static string GetVisualStudioFolder() return sc.GetInstanceForCurrentProcess().GetInstallationPath(); } + + /// + /// Is project dirty compared to associated codeql database + /// + /// internal static async System.Threading.Tasks.Task IsProjectDirtyAsync() { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - Project project = GetActiveProject(); + VCProject project = GetVCProject(); if (project != null) { - return project.IsDirty; + string projectPath = GetProjectDirectory(GetActiveProject()); + string dbPath = Path.Combine(projectPath, "codeql_db", "diagnostic"); + List dbFiles = new List(Directory.GetFiles(dbPath, "cli-diagnostics-add-*", SearchOption.TopDirectoryOnly)); + var lastBuildTime = dbFiles.Max(file => File.GetLastWriteTimeUtc(file)); + var sourceFiles = Directory.GetFiles(projectPath, "*.c*", SearchOption.AllDirectories) + .Concat(Directory.GetFiles(projectPath, "*.h", SearchOption.AllDirectories)); + + return sourceFiles.Any(file => File.GetLastWriteTimeUtc(file) > lastBuildTime); } return true; } + internal static async System.Threading.Tasks.Task BuildProjectAsync() { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); From f5c36c4fa173e97e93e9b909d25bc15ac33ad384 Mon Sep 17 00:00:00 2001 From: Jacob Ronstadt Date: Mon, 30 Jun 2025 16:36:48 -0700 Subject: [PATCH 07/18] bug fixes --- .../CodeQL.VisualStudio/BuildEvents.cs | 1 - .../CodeQL.VisualStudio.csproj | 1 - .../CodeQL.VisualStudio/CodeQLPackage.cs | 9 +-------- .../CodeQL.VisualStudio/CodeQLPackage.vsct | 8 ++++---- .../CodeQL.VisualStudio/ProjectHelper.cs | 19 ++++++++----------- .../source.extension.vsixmanifest | 2 +- 6 files changed, 14 insertions(+), 26 deletions(-) diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/BuildEvents.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/BuildEvents.cs index 053c0b16..ae230368 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/BuildEvents.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/BuildEvents.cs @@ -24,7 +24,6 @@ public int UpdateSolution_Begin(ref int pfCancelUpdate) public int UpdateSolution_Done(int fSucceeded, int fModified, int fCancelCommand) { - //TODO check if build was successful bool isProjDirty = true; ThreadHelper.JoinableTaskFactory.Run(async () => isProjDirty = await ProjectHelper.IsProjectDirtyAsync()); diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj index f825dc9c..d1a7a169 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj @@ -183,7 +183,6 @@ - VsixManifestGenerator diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs index ca9a7d9a..56dc2c7c 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.cs @@ -41,7 +41,7 @@ public sealed class CodeQLPackage : AsyncPackage /// /// OpenSarifFileCommandPackage GUID string. /// - public const string PackageGuidString = "3718ce5a-503f-4c55-8f70-3a4cc34fb1fb"; + public const string PackageGuidString = "19BD102D-9450-4BF2-A08A-DA4704F146AB"; public const string CodeQLCategoryName = "CodeQL"; public const string OptionPageName = "General"; public const string CodeQLPageName = "General"; @@ -133,13 +133,6 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke return; } - private void OnBuildBegin() - { - ThreadHelper.ThrowIfNotOnUIThread(); - // this is called when build starts. - // this can be used to start the codeql file watcher. - //this.codeqlFileMonitor?.StartWatching(); - } private void SolutionEvents_OnBeforeOpenProject(object sender, EventArgs e) { // start watcher when the solution is opened. diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct index dfa49c68..894b969c 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct @@ -191,7 +191,7 @@ - + @@ -209,7 +209,7 @@ - + @@ -221,11 +221,11 @@ - + - + diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs index 76f96588..0fa904d7 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs @@ -369,18 +369,15 @@ internal static async System.Threading.Tasks.Task BuildProjectAsync() Project project = GetActiveProject(); if (project != null ) { - if (project.IsDirty) + TaskCompletionSource buildTcs = new TaskCompletionSource(); + DTE2 dte = (DTE2)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(DTE)); + BuildEvents buildEvents = dte.Events.BuildEvents; + buildEvents.OnBuildDone += (scope, action) => { - TaskCompletionSource buildTcs = new TaskCompletionSource(); - DTE2 dte = (DTE2)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(DTE)); - BuildEvents buildEvents = dte.Events.BuildEvents; - buildEvents.OnBuildDone += (scope, action) => - { - buildTcs.TrySetResult(true); - }; - dte.ExecuteCommand("Build.BuildSelection"); - await buildTcs.Task; - } + buildTcs.TrySetResult(true); + }; + dte.ExecuteCommand("Build.BuildSelection"); + await buildTcs.Task; } else { diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/source.extension.vsixmanifest b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/source.extension.vsixmanifest index 821c1c08..25bf57a4 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/source.extension.vsixmanifest +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/source.extension.vsixmanifest @@ -1,7 +1,7 @@  - + CodeQL Visual Studio Extension CodeQL Visual Studio Extension License.txt From fc147d08b3d208c1b1cd2e0e8b38504351a90f9d Mon Sep 17 00:00:00 2001 From: Jacob Ronstadt Date: Wed, 23 Jul 2025 12:11:19 -0700 Subject: [PATCH 08/18] fixes to codeql install helper --- .../CodeQL.VisualStudio/CodeQLCommand.cs | 2 +- .../CodeQLInstallHelper.xaml | 24 +++-- .../CodeQLInstallHelper.xaml.cs | 98 ++++++++++++++----- .../CodeQL.VisualStudio/CodeQLRunner.cs | 19 ++++ .../CodeQL.VisualStudio/CodeQLService.cs | 21 +++- .../CodeQL.VisualStudio/InstallWindow.xaml.cs | 1 + 6 files changed, 134 insertions(+), 31 deletions(-) diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs index 362d00fc..2bcaa15f 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs @@ -115,7 +115,7 @@ private CodeQLCommand(Package package) new CommandID(CommandSet, ComboGetListId)); commandService.AddCommand(oleCommand); } - CodeQLService.CodeQLUpateExePath(); + CodeQLService.CodeQLUpdateExePath(); } /// diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLInstallHelper.xaml b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLInstallHelper.xaml index 9f999d84..8733b252 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLInstallHelper.xaml +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLInstallHelper.xaml @@ -8,16 +8,17 @@ Title="CodeQL Installer" WindowStyle="ToolWindow" ResizeMode="NoResize" Topmost="True" WindowStartupLocation="CenterScreen" SizeToContent="WidthAndHeight"> - + + - - - + + + @@ -29,16 +30,27 @@ - - + + + + + + + + + + + + + diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLInstallHelper.xaml.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLInstallHelper.xaml.cs index d7106796..cf4e8cb5 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLInstallHelper.xaml.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLInstallHelper.xaml.cs @@ -32,6 +32,11 @@ public CodeQLInstallHelper() DataContext = this; cliExpander.IsExpanded = true; packsExpander.IsExpanded = true; + if (CodeQLService.CodeQLIsInstalled()) + { + OverwriteExistingCheckbox.IsEnabled = true; + CurrentVersionTextBlock.Text = CodeQLService.Instance.GetCodeQLVersion(); + } } /// @@ -45,16 +50,41 @@ public CodeQLInstallHelper() /// private void ButtonInstall_Click(object sender, RoutedEventArgs e) { - InstallWindow iw = new InstallWindow(version: ___TextBoxVersion_.Text, - path: ___TextBoxPath_.Text, - addToPath: AddToPathCheckBox.IsChecked ?? false, - _languagePacks, - PreReleaseCheckBox.IsChecked ?? false); - iw.Owner = this; - iw.DataContext = this; - iw.backgroundWorker.RunWorkerAsync(); - this.DialogResult = iw.ShowDialog(); - Close(); + bool overwrite = OverwriteExistingCheckbox.IsChecked ?? false; + + // install codeql and packs + if (!string.IsNullOrEmpty(___TextBoxVersion_.Text) && + (overwrite || CurrentVersionTextBlock.Text == "None" )) + { + InstallWindow iw = new InstallWindow( + version: ___TextBoxVersion_.Text, + path: ___TextBoxPath_.Text, + addToPath: AddToPathCheckBox.IsChecked ?? false, + _languagePacks, + PreReleaseCheckBox.IsChecked ?? false + ); + iw.Owner = this; + iw.DataContext = this; + iw.backgroundWorker.RunWorkerAsync(); + this.DialogResult = iw.ShowDialog(); + Close(); + } + // just install packs + else if(_languagePacks.Count > 0) + { + InstallWindow iw = new InstallWindow( + _languagePacks + ); + iw.Owner = this; + iw.DataContext = this; + iw.backgroundWorker.RunWorkerAsync(); + this.DialogResult = iw.ShowDialog(); + Close(); + } + else + { + throw new Exception("No Selection"); + } } @@ -97,25 +127,26 @@ public async Task GetLatestVersionAsync() } private async Task SetVersionCheckBoxTextAsync() { - ___TextBoxVersion_.IsEnabled = !UseLatestCheckBox.IsChecked ?? true; ___TextBoxVersion_.Text = await GetLatestVersionAsync(); } + + private void UseLatestCheckBox_Unchecked(object sender, RoutedEventArgs e) + { + ___TextBoxVersion_.IsEnabled = !UseLatestCheckBox.IsChecked ?? true; + ___TextBoxVersion_.Text = ""; + } + + private void UseLatest_Checked(object sender, RoutedEventArgs e) { + ___TextBoxVersion_.IsEnabled = !UseLatestCheckBox.IsChecked ?? true; _ = SetVersionCheckBoxTextAsync(); } private void TextBoxVersion_TextChanged(object sender, TextChangedEventArgs e) { - if (_languagePacks.Count > 0 && Version.TryParse(___TextBoxVersion_.Text, out _)) - { - buttonInstall.IsEnabled = true; - } - else - { - buttonInstall.IsEnabled = false; - } + UpdateInstallButton(); } private void LanguagePack_Checked(object sender, RoutedEventArgs e) @@ -130,18 +161,41 @@ private void LanguagePack_Checked(object sender, RoutedEventArgs e) _languagePacks.Remove(checkBox.Content.ToString()); } - if (_languagePacks.Count > 0 && - (!string.IsNullOrEmpty(___TextBoxVersion_.Text) || CodeQLService.CodeQLIsInstalled())) + UpdateInstallButton(); + } + + private void OverwriteExisting_Checked(object sender, RoutedEventArgs e) + { + UpdateInstallButton(); + } + + private void UpdateInstallButton() + { + if (_languagePacks.Count > 0 && CodeQLService.CodeQLIsInstalled()) { + // just installing packs buttonInstall.IsEnabled = true; } + else if (Version.TryParse(___TextBoxVersion_.Text, out _)) + { + // installing cli, maybe packs + bool overwrite = OverwriteExistingCheckbox.IsChecked ?? false; + if (overwrite || CurrentVersionTextBlock.Text == "None") + { + buttonInstall.IsEnabled = true; + } + else + { + buttonInstall.IsEnabled = false; + } + } else { buttonInstall.IsEnabled = false; } } } - + public partial class CodeQLPackInstallHelper : CodeQLInstallHelper { public CodeQLPackInstallHelper() : base() diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs index 063de4de..5170761a 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLRunner.cs @@ -224,6 +224,25 @@ public bool IsExclusion(string item) return false; } + /// + /// + /// + public async Task GetCodeQLVersionAsync() + { + string output = await RunCodeQLProcAsync("version"); + output = output.Replace("CodeQL command-line toolchain release", "").Replace(" ", "").Trim(); + Version currVer; + Version.TryParse(output.Split('\r')[0].Trim('.'), out currVer); + if(currVer != null) + { + return currVer.ToString(); + } + else + { + throw new Exception("Could not get CodeQL version"); + } + } + /// /// Installs a CodeQL pack asynchronously. diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs index 56447409..801a44e7 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs @@ -310,7 +310,14 @@ public async System.Threading.Tasks.Task InstallCodeQLAsync(string version, stri if(Directory.Exists(System.IO.Path.Combine(installPath, "codeql"))) { // If codeql already exists, delete it - Directory.Delete(System.IO.Path.Combine(installPath, "codeql"), true); + try + { + Directory.Delete(System.IO.Path.Combine(installPath, "codeql"), true); + } + catch(Exception ex) + { + throw new Exception("Failed to delete existing CodeQL directory: " + ex.Message, ex); + } } if (!Version.TryParse(version, out _)) @@ -340,10 +347,11 @@ public async System.Threading.Tasks.Task InstallCodeQLAsync(string version, stri } - public static void CodeQLUpateExePath() + public static void CodeQLUpdateExePath() { CodeQLRunner.UpdateCodeQLExePath( CodeQLGeneralOptions.Instance.CliPath ?? "" ); } + public static bool CodeQLIsInstalled() { return CodeQLRunner.IsInstalled(); @@ -433,5 +441,14 @@ await ThreadHelper.JoinableTaskFactory.RunAsync(async () => _taskCompleted.TrySetResult(true); return true; } + + /// + /// + /// + /// + public string GetCodeQLVersion() + { + return ThreadHelper.JoinableTaskFactory.Run( async ()=> await CodeQLRunner.Instance.GetCodeQLVersionAsync()); + } } } diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/InstallWindow.xaml.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/InstallWindow.xaml.cs index 5d223117..dc9a59f4 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/InstallWindow.xaml.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/InstallWindow.xaml.cs @@ -26,6 +26,7 @@ public partial class InstallWindow : Window private readonly bool _addToPath; private readonly bool _prerelease; private readonly HashSet _packs; + private readonly bool _overwriteExisting; public InstallWindow(string version, string path, bool addToPath, HashSet packs, bool prerelease) { From 4b07c3433cb83ecaf6787a7053e62128b6fea41c Mon Sep 17 00:00:00 2001 From: Jacob Ronstadt Date: Thu, 24 Jul 2025 16:15:42 -0700 Subject: [PATCH 09/18] Updating query selection interface --- .../CodeQL.VisualStudio.csproj | 7 ++ .../CodeQL.VisualStudio/CodeQLCommand.cs | 14 +-- .../CodeQLQuerySelectorPage.xaml | 25 ++++ .../CodeQLQuerySelectorPage.xaml.cs | 119 ++++++++++++++++++ .../CodeQL.VisualStudio/CodeQLRunner.cs | 25 ++-- .../CodeQL.VisualStudio/CodeQLService.cs | 5 +- .../CodeQL.VisualStudio/ProjectHelper.cs | 2 + 7 files changed, 177 insertions(+), 20 deletions(-) create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLQuerySelectorPage.xaml create mode 100644 tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLQuerySelectorPage.xaml.cs diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj index d1a7a169..c6ee14e5 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQL.VisualStudio.csproj @@ -58,6 +58,9 @@ Component + + CodeQLQuerySelectorPage.xaml + CodeQLInstallHelper.xaml @@ -192,6 +195,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + MSBuild:Compile Designer diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs index 2bcaa15f..e7a11efe 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLCommand.cs @@ -163,7 +163,8 @@ private async System.Threading.Tasks.Task MenuItemCallbackAsync(object sender, E { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - + CodeQLQuerySelectorPage codeQLQueryPackSelector = new CodeQLQuerySelectorPage(); + codeQLQueryPackSelector.ShowDialog(); var menuCommand = (OleMenuCommand)sender; switch (menuCommand.CommandID.ID) { @@ -334,14 +335,7 @@ private void OnMenuMyDropDownComboGetList(object sender, EventArgs e) public async System.Threading.Tasks.Task CodeqlRefreshAvailableQueriesAsync() { - if (CodeQLService.CodeQLIsInstalled()) - { - _discoveredComboChoices = await CodeQLService.Instance.FindAvailableQueriesAsync(); - if (_discoveredComboChoices != null && _discoveredComboChoices.Length != 0) - { - _currentDropDownComboChoice = _discoveredComboChoices[0]; - } - } + } private static InfoBar noCodeQLInfoBar = null; @@ -371,7 +365,7 @@ public static async System.Threading.Tasks.Task CheckForCodeQLAsync() default); } } - else if ((await CodeQLService.Instance.FindAvailableQueriesAsync()).Length == 0 ) + else if ((await CodeQLService.Instance.FindAvailableQueriesAsync()).Count == 0 ) { if (noCodeQLInfoBar == null) { diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLQuerySelectorPage.xaml b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLQuerySelectorPage.xaml new file mode 100644 index 00000000..88ac7306 --- /dev/null +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLQuerySelectorPage.xaml @@ -0,0 +1,25 @@ + + + + + + + + + public async Task GetCodeQLVersionAsync() { - string output = await RunCodeQLProcAsync("version"); - output = output.Replace("CodeQL command-line toolchain release", "").Replace(" ", "").Trim(); + string output = await RunCodeQLProcAsync("version -q"); Version currVer; - Version.TryParse(output.Split('\r')[0].Trim('.'), out currVer); + Version.TryParse(output, out currVer); if(currVer != null) { return currVer.ToString(); @@ -336,15 +335,25 @@ public async Task RunCodeQLProcAsync(string cmd, string workingDir = nul public async Task> FindQueriesAsync(List qlpacks, bool queriesNSuites = true) { var queries = new List(); - + Stack packs = new Stack(qlpacks); // make async var tasks = new List(); - foreach (string pack in qlpacks) + do { - tasks.Add(Task.Run(async () => queries.AddRange(await FindQueriesAsync(pack, queriesNSuites)))); + // Limit sequential tasks to 5 + if (tasks.Count < 5) + { + string pack = packs.Pop(); + tasks.Add(Task.Run(async () => queries.AddRange(await FindQueriesAsync(pack, queriesNSuites)))); + } + else + { + await Task.WhenAll(tasks); + tasks.Clear(); + } } - - await Task.WhenAll(tasks); + while (packs.Count > 0); + return queries; } diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs index 801a44e7..dda9d00b 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLService.cs @@ -13,6 +13,7 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; @@ -228,7 +229,7 @@ private void HandleKeyCollision(string existingKey, string newValue) } } - public async Task FindAvailableQueriesAsync() + public async Task> FindAvailableQueriesAsync() { List packList = await CodeQLRunner.Instance.FindPacksAsync(CodeQLGeneralOptions.Instance.AdditionalQueryLocations); List queryList = await CodeQLRunner.Instance.FindQueriesAsync(packList, queriesNSuites: false); @@ -245,7 +246,7 @@ public async Task FindAvailableQueriesAsync() } } - return _queryDict.Keys.ToArray(); + return new ObservableCollection(_queryDict.Keys); } public void AddAdditionalQueries(List queries) diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs index 0fa904d7..f2dcab8f 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/ProjectHelper.cs @@ -349,9 +349,11 @@ internal static async System.Threading.Tasks.Task IsProjectDirtyAsync() VCProject project = GetVCProject(); if (project != null) { + // TODO if no cli-diagnostics, check timestamp of all db files string projectPath = GetProjectDirectory(GetActiveProject()); string dbPath = Path.Combine(projectPath, "codeql_db", "diagnostic"); List dbFiles = new List(Directory.GetFiles(dbPath, "cli-diagnostics-add-*", SearchOption.TopDirectoryOnly)); + // could do this with all db files instead of using diagnostic files var lastBuildTime = dbFiles.Max(file => File.GetLastWriteTimeUtc(file)); var sourceFiles = Directory.GetFiles(projectPath, "*.c*", SearchOption.AllDirectories) .Concat(Directory.GetFiles(projectPath, "*.h", SearchOption.AllDirectories)); From 3cfb09ddae045a97093e8aadbad132998e02b484 Mon Sep 17 00:00:00 2001 From: Jacob Ronstadt Date: Fri, 25 Jul 2025 09:40:43 -0700 Subject: [PATCH 10/18] Fix UI bug. remove dropdown and replace with button --- .../CodeQL.VisualStudio/CodeQLPackage.vsct | 51 +++++++++---------- .../CodeQLQuerySelectorPage.xaml | 6 +-- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct index 894b969c..bbb02ce7 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct @@ -107,9 +107,9 @@ cmdiCodeQLLoadQueriesCommand - Refresh Available Queries - Refresh Available Queries - Search for all locally available queries and load them into the drop-down + Select Available Queries + Select Available Queries + Search for all locally available queries and select which to run @@ -145,6 +145,16 @@ Run Selected CodeQL Suites + - - - - - - IconAndText - StretchHorizontally - - QuerySuite - CodeQL - - - - - - - - - - + + + + + + + diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLQuerySelectorPage.xaml b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLQuerySelectorPage.xaml index 88ac7306..57ed6807 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLQuerySelectorPage.xaml +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLQuerySelectorPage.xaml @@ -13,9 +13,9 @@ - private readonly Package package; - private static string _currentDropDownComboChoice; - private static string[] _discoveredComboChoices; - /// /// Initializes a new instance of the class. /// Adds our command handlers for menu (commands must exist in the command table file). @@ -104,16 +101,6 @@ private CodeQLCommand(Package package) new CommandID(CommandSet, CodeQLInstallerCommandID)); commandService.AddCommand(oleCommand); - // Combo box - oleCommand = new OleMenuCommand( - new EventHandler(this.OnMenuMyDropDownCombo), - new CommandID(CommandSet, CodeQLComboId)); - commandService.AddCommand(oleCommand); - - oleCommand = new OleMenuCommand( - new EventHandler(this.OnMenuMyDropDownComboGetList), - new CommandID(CommandSet, ComboGetListId)); - commandService.AddCommand(oleCommand); } CodeQLService.CodeQLUpdateExePath(); } @@ -163,8 +150,7 @@ private async System.Threading.Tasks.Task MenuItemCallbackAsync(object sender, E { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - CodeQLQuerySelectorPage codeQLQueryPackSelector = new CodeQLQuerySelectorPage(); - codeQLQueryPackSelector.ShowDialog(); + var menuCommand = (OleMenuCommand)sender; switch (menuCommand.CommandID.ID) { @@ -179,9 +165,9 @@ private async System.Threading.Tasks.Task MenuItemCallbackAsync(object sender, E { throw new Exception("CodeQL already running"); // FIXME } - if (string.IsNullOrEmpty(_currentDropDownComboChoice)) + if (string.IsNullOrEmpty(CodeQLService.Instance.SelectedQuery)) { - throw new Exception("No query selected"); + CodeqlRefreshAvailableQueries(); } CodeQLService.Instance.InitTask(); @@ -206,10 +192,10 @@ private async System.Threading.Tasks.Task MenuItemCallbackAsync(object sender, E && CodeQLService.Instance.IsCodeQLTaskCompleted()) { CodeQLService.Instance.InitTask(); // init again since starting a new CodeQL process - Trace.WriteLine($"Starting CodeQL analysis using {_currentDropDownComboChoice}"); + Trace.WriteLine($"Starting CodeQL analysis using {CodeQLService.Instance.SelectedQuery}"); try { - var sarifResults = await CodeQLService.Instance.RunCodeQLQueryAsync(_currentDropDownComboChoice.Trim()); + var sarifResults = await CodeQLService.Instance.RunCodeQLQueryAsync(CodeQLService.Instance.SelectedQuery.Trim()); var sarifViewer = new SarifViewerInterop(Package.GetGlobalService(typeof(SVsShell)) as IVsShell); if (false && sarifViewer.IsSariferExtensionInstalled) { @@ -263,7 +249,8 @@ private async System.Threading.Tasks.Task MenuItemCallbackAsync(object sender, E break; case CodeQLLoadQueriesCommandId: - await CodeqlRefreshAvailableQueriesAsync(); + + CodeqlRefreshAvailableQueries(); break; case CodeQLComboId: break; @@ -274,68 +261,10 @@ private async System.Threading.Tasks.Task MenuItemCallbackAsync(object sender, E } } - private void OnMenuMyDropDownCombo(object sender, EventArgs e) - { - if (e is OleMenuCmdEventArgs eventArgs) - { - IntPtr vOut = eventArgs.OutValue; - if (vOut != IntPtr.Zero) - { - // when vOut is non-NULL, the IDE is requesting the current value for the combo - Marshal.GetNativeVariantForObject(_currentDropDownComboChoice, vOut); - } - else - { - _currentDropDownComboChoice = eventArgs.InValue is string newChoice ? newChoice : throw new ArgumentException("Invalid Selection"); - } - } - else - { - // We should never get here; EventArgs are required. - throw new ArgumentException("EventArgs are required"); // force an exception to be thrown - } - } - - - private void OnMenuMyDropDownComboGetList(object sender, EventArgs e) + public void CodeqlRefreshAvailableQueries() { - if (e is OleMenuCmdEventArgs eventArgs) - { - object inParam = eventArgs.InValue; - IntPtr vOut = eventArgs.OutValue; - - if (inParam != null) - { - throw new ArgumentException("InParamIllegal"); // force an exception to be thrown - } - else if (vOut != IntPtr.Zero) - { - _discoveredComboChoices = CodeQLService.Instance.AvailableQueries.ToArray(); - if (_discoveredComboChoices == null) - { - _ = ThreadHelper.JoinableTaskFactory.RunAsync(async () => await CodeqlRefreshAvailableQueriesAsync()); - } - - if (!_discoveredComboChoices.Contains(_currentDropDownComboChoice)) - { - _currentDropDownComboChoice = _discoveredComboChoices[0]; - } - Marshal.GetNativeVariantForObject(_discoveredComboChoices, vOut); - } - else - { - throw new ArgumentException("OutParamRequired"); // force an exception to be thrown - } - } - else - { - throw new ArgumentException("InParamIllegal"); // force an exception to be thrown - } - } - - public async System.Threading.Tasks.Task CodeqlRefreshAvailableQueriesAsync() - { - + CodeQLQuerySelectorPage codeQLQueryPackSelector = new CodeQLQuerySelectorPage(); + codeQLQueryPackSelector.ShowDialog(); } private static InfoBar noCodeQLInfoBar = null; @@ -392,7 +321,6 @@ public static async System.Threading.Tasks.Task CheckForCodeQLAsync() { await noCodeQLInfoBar.ShowAsync(); } - await CodeQLCommand.Instance.CodeqlRefreshAvailableQueriesAsync(); } } } diff --git a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct index bbb02ce7..d3584d3f 100644 --- a/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct +++ b/tools/extensions/CodeQL.VisualStudio/CodeQL.VisualStudio/CodeQLPackage.vsct @@ -93,7 +93,7 @@ @@ -150,9 +150,9 @@ cmdiCodeQLLoadQueriesCommand - Select Available Queries - Select Available Queries - Select locally available queries to run + Select Available CodeQL Suites + Select Available CodeQL Suites + Select Locally Available CodeQL Query Suites to Run