驱动程序代码分析警告

本部分列出并介绍驱动程序代码分析在检测到驱动程序代码中可能出现的错误时报告的警告。 请注意,某些警告适用于内核模式代码,在分析用户模式驱动程序时可以忽略。

重要

驱动程序的代码分析在 Windows 24H2 WDK 和 EWDK 中可用,但建议它在将来的日期停用。
今后,CodeQL 将成为驱动程序的主要静态分析工具。 CodeQL 提供了一种功能强大的查询语言,可将代码视为要查询的数据库,使编写特定行为、模式等查询变得简单。 有关使用 CodeQL 的详细信息,请参阅 CodeQL 和静态工具徽标测试

驱动程序的代码分析报告以下类型的警告:

  • 常规警告 (6000-6999):C 和C++语法和常规编码实践中的潜在错误。 有关这些警告的说明,请参阅 C/C++ 警告的代码分析。

  • 特定于 Windows 的 警告(28600-28799):这些警告特定于 Windows 中使用的某些模式,但不特定于驱动程序。

  • 特定于驱动程序的 警告(28100-28199):驱动程序与应用程序交互、与其他驱动程序以及操作系统交互时出错。

  • 批注错误 (28200-28299 和 36000-36999):这些警告指示批注在不正确的上下文中已错误编码或使用。 在大多数情况下,存在此类警告表示批注没有所需的(或任何)效果。

  • 内存分配警告 (30029-30035):这些是内存分配警告。

本部分内容

主题 说明

C28101

警告 C28101:驱动程序模块推断当前函数不是正确的函数类型

C28110

警告 C28110:驱动程序必须保护浮点硬件状态。 请参阅 float 的使用

C28111

警告 C28111:保存浮点状态的 IRQL 与当前 IRQL 不匹配(对于此还原操作)。

C28114

警告:C28114:复制整个 IRP 堆栈条目会使某些应清除或更新的字段初始化。

C28120

警告 C28120:不允许在当前 IRQ 级别调用该函数。 当前级别太低。

C28121

警告 C28121:不允许在当前 IRQ 级别调用该函数。 当前级别太高。

C28122

警告 C28122:不允许在低 IRQ 级别调用该函数。 以前的函数调用与此约束不一致。

C28123

警告 C28123:不允许在高 IRQ 级别调用该函数。 以前的函数调用与此约束不一致。

C28124

警告 C28124:调用导致 IRQ 级别设置为要分析的函数可接受的最小值。

C28126

警告 C28126:ObReferenceObject* 的 AccessMode 参数应为 IRP-RequestorMode>

C28127

警告 C28127:用作例程的函数与预期的类型不完全匹配。

C28128

警告 C28128:已直接访问字段。 它应由例程进行。

C28129

警告 C28129:已对操作数进行赋值,仅应使用位集和清除来修改此操作数

C28131

警告 C28131:DriverEntry 例程应保存参数的副本,而不是指针,因为 I/O 管理器释放缓冲区

C28132

警告 C28132:获取指针的大小

C28133

警告 C28133:最好从 AddDevice 调用 IoInitializeTimer

C28134

警告 C28134:池标记的类型应为整型,而不是字符串或字符串指针

C28135

警告 C28135:如果 KeWaitForSingleObject 的第一个参数是局部变量,则 Mode 参数必须是 KernelMode

C28139

警告 C28139:参数应与类型完全匹配

C28141

警告 C28141:该参数导致 IRQ 级别设置为低于当前 IRQL,并且此函数不能用于该目的

C28143

警告 C28143:调用 IoMarkIrpPending 的调度例程还必须返回STATUS_PENDING

C28144

警告 C28144:在取消例程中,在退出点,Irp-CancelIrql> 中的 IRQL 应为当前的 IRQL。

C28145

警告 C28145:驱动程序不应修改不透明的 MDL 结构

C28146

警告 C28146:内核模式驱动程序应使用 ntstrsafe.h,而不是 strsafe.h。 在源文件中找到

C28147

警告 C28147:使用默认池标记('kdD'或'mdW')调用此函数会失败池标记的目的

C28150

警告 C28150:该函数导致 IRQ 级别设置为高于要分析的函数可接受的最大值

C28151

警告 C28151:该值不是 IRQL 的法律值

C28152

警告 C28152:来自类似 AddDevice 的函数的返回意外DO_DEVICE_INITIALIZING

C28153

警告 C28153:无法在此上下文中评估来自批注的 IRQL 的值。

C28156

警告 C28156:实际 IRQL 与所需的 IRQL 不一致

C28157

警告 C28157:IRQL 从未还原

C28158

警告 C28158:未保存 IRQL

C28161

警告 C28161:退出而不获取使用浮动硬件的权利

C28162

警告 C28162:退出,同时保留使用浮点硬件的权利

C28165

警告 C28165:类的函数指针与函数类不匹配

C28166

警告 C28166:该函数不会将 IRQL 还原到函数条目的当前值,因此需要这样做。

C28167

警告 C28167:该函数更改 IRQL,并且不会在 IRQL 退出之前还原 IRQL。 应添加注释以反映更改或应还原 IRQL。

C28168

警告 C28168:调度函数没有 与此调度表项匹配的Dispatch_type 批注

C28169

警告 C28169:调度函数没有任何 Dispatch_type 批注

C28170

警告 C28170:函数已声明为分页段,但未找到PAGED_CODE或PAGED_CODE_LOCKED

C28171

警告 C28171:函数具有多个PAGED_CODE或PAGED_CODE_LOCKED实例

C28172

警告 C28172:函数具有PAGED_CODE或PAGED_CODE_LOCKED,但未声明为分页段

C28173

警告 C28173:当前函数似乎错误地适应超过 4 GB 的物理内存

C28175

警告 C28175:驱动程序不应访问结构的成员

C28176

警告 C28176:驱动程序不应修改结构的成员

C28177

警告 C28177:函数使用多个函数类进行批注。 将忽略除了一个。

C28260

警告 C28260:在分析函数中的属性时发现了批注中的语法错误

C28266

为函数中的属性找到了批注中的语法错误。

C28268

警告 C28268:函数上的函数类与此处使用的 typedef 上的函数类不匹配

C28601

警告 C28601:避免阻止HWND_BROADCAST

C28602

警告 C28602:避免使用 HWND_BROADCAST 调用 SendMessageTimeout

C28604

警告 C28604:避免使用超时为 0 的 SMTO_ABORTIFHUNG 调用 SendMessageTimeout

C28615

警告 C28615:在__try块中调用_alloca时,必须在 __except() 块中调用_resetstkoflw。 不要从 catch() 块内部调用_resetstkoflw

C28616

警告 C28616:多线程 AV 条件

C28617

警告 C28617:避免使用 _beginthread() 的返回值。 请改用 _beginthreadex()

C28623

警告 C28623:GetMessagePos() 坐标的无符号转换。 使用 GET_X_LPARAM/GET_Y_LPARAM,而不是 LOWORD/HIWORD

C28624

警告 C28624:不调用 Release() 以匹配 LResultFromObject 中的递增 refcount

C28625

警告 C28625:用于清除敏感数据的函数调用将被优化

C28636

警告 C28636:在从对 GetSecurityDescriptorOwner/Group/Dacl/Sacl 的调用中获取的非分配指针上调用 LocalFree

C28637

警告 C28637:在全局初始值设定项中调用函数不安全

C28638

警告 C28638:函数延迟加载存根缺少匹配声明

C28639

警告 C28639:使用字符串调用 close handle

C28640

警告 C28640:函数延迟加载存根应为静态函数

C28644

警告 C28644:未选中DPA_InsertPtr返回值

C28645

警告 C28645:使用不再推荐的问号消息符号调用 MessageBox

C28648

警告 C28648:PulseEvent 是一个不可靠的函数

C28649

警告 C28649:自动或全局堆栈数组从不为 NULL

C28650

警告 C28650:正在使用 !0 的类型不将其视为失败情况。

返回状态值,例如 !TRUE 与返回指示失败的状态值不同。

C28651

警告 C28651:静态初始值设定项因成员函数指针导致写入页上复制

C28652

警告 C28652:静态初始值设定项由于重载位运算符导致写入页上复制

C28714

警告 C28714:在语义上不同的整数类型之间强制转换

C28715

警告 C28715:在语义上不同的整数类型之间强制转换

C28716

警告 C28716:在语义上不同的整型类型之间插入编译器的强制转换

C28717

警告 C28717:VARIANT 类型无效

C28718

警告 C28718:未批注缓冲区

C28719

警告 C28719:禁止的 API 使用

C28720

警告 C28720:禁止的 API 使用

C28721

警告 C28721:弃用的性能计数器体系结构

C28722

警告 C28722:函数声明中的未批注缓冲区

C28723

警告 C28723:函数定义中没有相应声明的未批注缓冲区

C28725

警告 C28725:使用 Watson 而不是此 SetUnhandledExceptionFilter

C28726

警告 C28726:禁止的 API 使用

C28727

警告 C28727:禁止的 API 使用

C28728

警告 C28728:禁止的 API 使用

C28730

警告 C28730:可能直接将“\0”分配给指针。

C28735

警告 C28735:禁止使用深红 API

C28736

警告 C28736:禁止的 API 参数用法

C28740

警告 C28740:未批注的未签名缓冲区

C28741

警告 C28741:函数中的未批注缓冲区

C28742

警告 C28742:函数中的未批注缓冲区

C28750

警告 C28750:禁止使用 lstrlen 及其变体

C28751

警告 C28751:禁止使用 ExAllocatePool 及其变体

C28752

警告 C28752:禁止使用 kernel32 或 advapi32 API

C28753

警告 C28753:依赖参数的未定义计算顺序

C30029

警告 C30029:调用请求可执行内存的内存分配函数

C30030

警告 C30030:调用内存分配函数并传递指示可执行内存的参数

C30031

警告 C30031:调用内存分配函数并传递指示可执行内存的参数

C30032

警告 C30032:调用内存分配函数,并使用 POOL_NX_OPTOUT 指令强制请求可执行内存

C30033

警告 C30033:在使用POOL_NX_OPTIN编译的驱动程序中检测到可执行分配。 此驱动程序已确定在运行时由另一个驱动程序加载。 请验证加载驱动程序在其 DriverEntry 中是否调用 ExInitializeDriverRuntime(DrvRtPoolNxOptIn)。

C30034

警告 C30034:将标志值传递给分配函数,该函数可能导致分配可执行内存。 请验证分配函数是否未请求一种可执行的非分页池形式。

C30035

警告 C30035:对必须从初始化函数内部(例如 DriverEntry()DllInitialize()内部进行的函数的调用。 PREfast 无法确定是否从初始化函数进行调用。