Tips of Windows Programming
窗口总在最前
::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
窗口总保持激活状态, 这段代码可以放在定时器内.
void KeepWindowAlwaysActive(HWND hWnd)
{
HWND hCurWnd = NULL;
DWORD lMyID = 0;
DWORD lCurID = 0;
hCurWnd = ::GetForegroundWindow();
if(hCurWnd != hWnd)
{
lMyID = ::GetCurrentThreadId();
lCurID = ::GetWindowThreadProcessId(hCurWnd, NULL);
::AttachThreadInput(lMyID, lCurID, TRUE);
::SetForegroundWindow(hWnd);
::AttachThreadInput(lMyID, lCurID, FALSE);
}
}
怎么跟自旋锁打交道
The code within a critical region guarded by an spin lock must neither be pageable nor make any references to pageable data.
The code within a critical region guarded by a spin lock can neither call any external function that might access pageable data or raise an exception, nor can it generate any exceptions.
The caller should release the spin lock with KeReleaseSpinLock as quickly as possible.
DATE 和 SYSTEMTIME 的相互转换
- DATE 转换成 SYSTEMTIME : VariantTimeToSystemTime, 其原型为:
INT VariantTimeToSystemTime( double vtime, LPSYSTEMTIME lpSystemTime ); - SYSTEMTIME 转换成 DATE : SystemTimeToVariantTime, 其原型为:
INT SystemTimeToVariantTime( LPSYSTEMTIME lpSystemTime, double *pvtime );
读写内核只读内存:
NTSTATUS WriteReadOnlyMemory(PUCHAR Dest, PUCHAR Source, ULONG Length)
{
static KIRQL Irql = 0;
static KSPIN_LOCK SpinLock = 0x999;
PMDL DestMDL, SourceMDL;
PUCHAR DestAddress, SourceAddress;
NTSTATUS status = STATUS_UNSUCCESSFUL;
__try
{
DestMDL = MmCreateMdl(NULL, Dest, Length);
SourceMDL = MmCreateMdl(NULL, Source, Length);
MmBuildMdlForNonPagedPool(DestMDL);
MmBuildMdlForNonPagedPool(SourceMDL);
DestMDL->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
SourceMDL->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
DestAddress = MmMapLockedPages(DestMDL, KernelMode);
SourceAddress = MmMapLockedPages(SourceMDL, KernelMode);
KeAcquireSpinLock(&SpinLock, &Irql);
RtlMoveMemory(DestAddress, SourceAddress, Length);
KeReleaseSpinLock(&SpinLock, Irql);
MmUnmapLockedPages(DestAddress, DestMDL);
MmUnmapLockedPages(SourceAddress, SourceMDL);
IoFreeMdl(DestMDL);
IoFreeMdl(SourceMDL);
status = STATUS_SUCCESS;
}
__except ( EXCEPTION_EXECUTE_HANDLER )
{
kdprintf(NC_DRV_PREFIX "%s Caught exception for reason:\t0x%08X\r\n",
__FUNCTION__, GetExceptionCode());
status = STATUS_UNSUCCESSFUL;
}
return status;
}
最新的 WDK (7600.16385.1) 对于 KeNumberProcessors 变量的定义有误, 不能链接成功, 正确的应是这样:
#if (NTDDI_VERSION >= NTDDI_VISTA) extern NTSYSAPI volatile CCHAR KeNumberProcessors; #elif (NTDDI_VERSION >= NTDDI_WINXP) extern NTSYSAPI CCHAR KeNumberProcessors; #else extern NTSYSAPI PCCHAR KeNumberProcessors; #endif
最后一个的声明少了一个 NTSYSAPI 修饰符

近期评论