驱动程序的代码分析警告
本部分列出并介绍驱动程序代码分析在检测到驱动程序代码中可能存在的错误时报告的警告。 请注意,某些警告适用于内核模式代码,在分析用户模式驱动程序时可以忽略。
驱动程序代码分析报告以下类型的警告:
常规警告 (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:使用字符串调用关闭句柄 |
|
警告 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 无法确定调用是否来自初始化函数。 |
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈