驱动程序代码分析警告
本部分列出并介绍驱动程序代码分析在检测到驱动程序代码中可能出现的错误时报告的警告。 请注意,某些警告适用于内核模式代码,在分析用户模式驱动程序时可以忽略。
重要
驱动程序的代码分析在 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:驱动程序模块推断当前函数不是正确的函数类型 |
|
警告 C28110:驱动程序必须保护浮点硬件状态。 请参阅 float 的使用 |
|
警告 C28111:保存浮点状态的 IRQL 与当前 IRQL 不匹配(对于此还原操作)。 |
|
警告:C28114:复制整个 IRP 堆栈条目会使某些应清除或更新的字段初始化。 |
|
警告 C28120:不允许在当前 IRQ 级别调用该函数。 当前级别太低。 |
|
警告 C28121:不允许在当前 IRQ 级别调用该函数。 当前级别太高。 |
|
警告 C28122:不允许在低 IRQ 级别调用该函数。 以前的函数调用与此约束不一致。 |
|
警告 C28123:不允许在高 IRQ 级别调用该函数。 以前的函数调用与此约束不一致。 |
|
警告 C28124:调用导致 IRQ 级别设置为要分析的函数可接受的最小值。 |
|
警告 C28126:ObReferenceObject* 的 AccessMode 参数应为 IRP-RequestorMode> |
|
警告 C28127:用作例程的函数与预期的类型不完全匹配。 |
|
警告 C28128:已直接访问字段。 它应由例程进行。 |
|
警告 C28129:已对操作数进行赋值,仅应使用位集和清除来修改此操作数 |
|
警告 C28131:DriverEntry 例程应保存参数的副本,而不是指针,因为 I/O 管理器释放缓冲区 |
|
警告 C28132:获取指针的大小 |
|
警告 C28133:最好从 AddDevice 调用 IoInitializeTimer |
|
警告 C28134:池标记的类型应为整型,而不是字符串或字符串指针 |
|
警告 C28135:如果 KeWaitForSingleObject 的第一个参数是局部变量,则 Mode 参数必须是 KernelMode |
|
警告 C28139:参数应与类型完全匹配 |
|
警告 C28141:该参数导致 IRQ 级别设置为低于当前 IRQL,并且此函数不能用于该目的 |
|
警告 C28143:调用 IoMarkIrpPending 的调度例程还必须返回STATUS_PENDING |
|
警告 C28144:在取消例程中,在退出点,Irp-CancelIrql> 中的 IRQL 应为当前的 IRQL。 |
|
警告 C28145:驱动程序不应修改不透明的 MDL 结构 |
|
警告 C28146:内核模式驱动程序应使用 ntstrsafe.h,而不是 strsafe.h。 在源文件中找到 |
|
警告 C28147:使用默认池标记('kdD'或'mdW')调用此函数会失败池标记的目的 |
|
警告 C28150:该函数导致 IRQ 级别设置为高于要分析的函数可接受的最大值 |
|
警告 C28151:该值不是 IRQL 的法律值 |
|
警告 C28152:来自类似 AddDevice 的函数的返回意外DO_DEVICE_INITIALIZING |
|
警告 C28153:无法在此上下文中评估来自批注的 IRQL 的值。 |
|
警告 C28156:实际 IRQL 与所需的 IRQL 不一致 |
|
警告 C28157:IRQL 从未还原 |
|
警告 C28158:未保存 IRQL |
|
警告 C28161:退出而不获取使用浮动硬件的权利 |
|
警告 C28162:退出,同时保留使用浮点硬件的权利 |
|
警告 C28165:类的函数指针与函数类不匹配 |
|
警告 C28166:该函数不会将 IRQL 还原到函数条目的当前值,因此需要这样做。 |
|
警告 C28167:该函数更改 IRQL,并且不会在 IRQL 退出之前还原 IRQL。 应添加注释以反映更改或应还原 IRQL。 |
|
警告 C28168:调度函数没有 与此调度表项匹配的Dispatch_type 批注 |
|
警告 C28169:调度函数没有任何 Dispatch_type 批注 |
|
警告 C28170:函数已声明为分页段,但未找到PAGED_CODE或PAGED_CODE_LOCKED |
|
警告 C28171:函数具有多个PAGED_CODE或PAGED_CODE_LOCKED实例 |
|
警告 C28172:函数具有PAGED_CODE或PAGED_CODE_LOCKED,但未声明为分页段 |
|
警告 C28173:当前函数似乎错误地适应超过 4 GB 的物理内存 |
|
警告 C28175:驱动程序不应访问结构的成员 |
|
警告 C28176:驱动程序不应修改结构的成员 |
|
警告 C28177:函数使用多个函数类进行批注。 将忽略除了一个。 |
|
警告 C28260:在分析函数中的属性时发现了批注中的语法错误 |
|
为函数中的属性找到了批注中的语法错误。 |
|
警告 C28268:函数上的函数类与此处使用的 typedef 上的函数类不匹配 |
|
警告 C28601:避免阻止HWND_BROADCAST |
|
警告 C28602:避免使用 HWND_BROADCAST 调用 SendMessageTimeout |
|
警告 C28604:避免使用超时为 0 的 SMTO_ABORTIFHUNG 调用 SendMessageTimeout |
|
警告 C28615:在__try块中调用_alloca时,必须在 __except() 块中调用_resetstkoflw。 不要从 catch() 块内部调用_resetstkoflw |
|
警告 C28616:多线程 AV 条件 |
|
警告 C28617:避免使用 _beginthread() 的返回值。 请改用 _beginthreadex() |
|
警告 C28623:GetMessagePos() 坐标的无符号转换。 使用 GET_X_LPARAM/GET_Y_LPARAM,而不是 LOWORD/HIWORD |
|
警告 C28624:不调用 Release() 以匹配 LResultFromObject 中的递增 refcount |
|
警告 C28625:用于清除敏感数据的函数调用将被优化 |
|
警告 C28636:在从对 GetSecurityDescriptorOwner/Group/Dacl/Sacl 的调用中获取的非分配指针上调用 LocalFree |
|
警告 C28637:在全局初始值设定项中调用函数不安全 |
|
警告 C28638:函数延迟加载存根缺少匹配声明 |
|
警告 C28639:使用字符串调用 close handle |
|
警告 C28640:函数延迟加载存根应为静态函数 |
|
警告 C28644:未选中DPA_InsertPtr返回值 |
|
警告 C28645:使用不再推荐的问号消息符号调用 MessageBox |
|
警告 C28648:PulseEvent 是一个不可靠的函数 |
|
警告 C28649:自动或全局堆栈数组从不为 NULL |
|
警告 C28650:正在使用 !0 的类型不将其视为失败情况。 返回状态值,例如 !TRUE 与返回指示失败的状态值不同。 |
|
警告 C28651:静态初始值设定项因成员函数指针导致写入页上复制 |
|
警告 C28652:静态初始值设定项由于重载位运算符导致写入页上复制 |
|
警告 C28714:在语义上不同的整数类型之间强制转换 |
|
警告 C28715:在语义上不同的整数类型之间强制转换 |
|
警告 C28716:在语义上不同的整型类型之间插入编译器的强制转换 |
|
警告 C28717:VARIANT 类型无效 |
|
警告 C28718:未批注缓冲区 |
|
警告 C28719:禁止的 API 使用 |
|
警告 C28720:禁止的 API 使用 |
|
警告 C28721:弃用的性能计数器体系结构 |
|
警告 C28722:函数声明中的未批注缓冲区 |
|
警告 C28723:函数定义中没有相应声明的未批注缓冲区 |
|
警告 C28725:使用 Watson 而不是此 SetUnhandledExceptionFilter |
|
警告 C28726:禁止的 API 使用 |
|
警告 C28727:禁止的 API 使用 |
|
警告 C28728:禁止的 API 使用 |
|
警告 C28730:可能直接将“\0”分配给指针。 |
|
警告 C28735:禁止使用深红 API |
|
警告 C28736:禁止的 API 参数用法 |
|
警告 C28740:未批注的未签名缓冲区 |
|
警告 C28741:函数中的未批注缓冲区 |
|
警告 C28742:函数中的未批注缓冲区 |
|
警告 C28750:禁止使用 lstrlen 及其变体 |
|
警告 C28751:禁止使用 ExAllocatePool 及其变体 |
|
警告 C28752:禁止使用 kernel32 或 advapi32 API |
|
警告 C28753:依赖参数的未定义计算顺序 |
|
警告 C30029:调用请求可执行内存的内存分配函数 |
|
警告 C30030:调用内存分配函数并传递指示可执行内存的参数 |
|
警告 C30031:调用内存分配函数并传递指示可执行内存的参数 |
|
警告 C30032:调用内存分配函数,并使用 POOL_NX_OPTOUT 指令强制请求可执行内存 |
|
警告 C30033:在使用POOL_NX_OPTIN编译的驱动程序中检测到可执行分配。 此驱动程序已确定在运行时由另一个驱动程序加载。 请验证加载驱动程序在其 DriverEntry 中是否调用 ExInitializeDriverRuntime(DrvRtPoolNxOptIn)。 |
|
警告 C30034:将标志值传递给分配函数,该函数可能导致分配可执行内存。 请验证分配函数是否未请求一种可执行的非分页池形式。 |
|
警告 C30035:对必须从初始化函数内部(例如 DriverEntry() 或 DllInitialize()内部进行的函数的调用。 PREfast 无法确定是否从初始化函数进行调用。 |