#define MAX_SECTION_LENGTH 1391 // 1024 + 184 possible stuffing bytes + 183 possible bytes from previous section
UCHAR m_ucPMTBuffer[MAX_SECTION_LENGTH];
RtlCopyMemory(m_ucPMTBuffer,pbSection,pulProperty->ulcbSectionLength+3);
驱动程序中用到这个数组保存一组数据。
(1)把m_ucPMTBuffer定义成局部变量时debug版会蓝屏,release运行没有问题。
(2)而m_ucPMTBuffer定义成全局变量就全都正常。
查找MSDN得到:
RtlCopyMemory routine
The RtlCopyMemory routine copies the contents of a source memory block to a destination memory block.
Syntax
C++Copy
VOID RtlCopyMemory(
_Out_ VOID UNALIGNED *Destination,
_In_ const VOID UNALIGNED *Source,
_In_ SIZE_T Length
);
Parameters
Destination [out]
A pointer to the destination memory block to copy the bytes to.
Source [in]
A pointer to the source memory block to copy the bytes from.
Length [in]
The number of bytes to copy from the source to the destination.
Return value
None
Remarks
RtlCopyMemory runs faster than RtlMoveMemory. However, RtlCopyMemory requires that the source memory block, which
is defined by Source and Length, cannot overlap the destination memory block, which is defined by Destination and
Length. In contrast, RtlMoveMemory correctly handles the case in which the source and destination memory blocks
overlap.
Callers of RtlCopyMemory can be running at any IRQL if the source and destination memory blocks are in nonpaged system memory. Otherwise, the caller must be running at IRQL <= APC_LEVEL.
#define PASSIVE_LEVEL 0
#define LOW_LEVEL 0
#define APC_LEVEL 1
#define DISPATCH_LEVEL 2
而驱动里我的程序运行在 KeGetCurrentIrql() == DISPATCH_LEVEL,所以只能把数据存储在非分布内存中,而全局数据正是在非分布内存中。
所以使用的数组只能定义成全局变量。debug 会直接导致蓝屏,而release可能是对程序进行了优化。
(默认情况下,内核加载器会加载所有的代码部分和全局数据到非分页内存中。而且,加载器是一次加载整个驱动的可执行文件,包括相关的DLL。加载后,内核加载器关闭驱动程序文件,甚至你可以删除当前正在执行的驱动文件。)
PS:当然也可以使用ExAllocatePool或ExAllocatePoolWithTag指定变量存储在非分页内存中(NonPagedPool),而把它定义成类的成员变量或者局部变量。