📄 windrvr_int_thread.cpp
字号:
////////////////////////////////////////////////////////////////
// File - windrvr_int_thread.c
//
// Implementation of a thread that waits for WinDriver events.
//
// Copyright (c) 2003 - 2006 Jungo Ltd. http://www.jungo.com
////////////////////////////////////////////////////////////////
#include "stdafx.h"
#if defined (__KERNEL_DRIVER__)
#include "kd.h"
#elif defined (__KERNEL__)
#include "kpstdlib.h"
#else
#include "utils.h"
#endif
#include "windrvr_int_thread.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// backward compatibility
BOOL InterruptThreadEnable(HANDLE *phThread, HANDLE hWD,
WD_INTERRUPT *pInt, INT_HANDLER func, PVOID pData)
{
DWORD rc;
rc = InterruptEnable(phThread, hWD, pInt, func, pData);
return rc==WD_STATUS_SUCCESS;
}
void InterruptThreadDisable(HANDLE hThread)
{
InterruptDisable(hThread);
}
#if defined(__KERNEL__)
#if 0 /* only a call from user-mode is supported */
typedef struct
{
HANDLE hWD;
WD_INTERRUPT *pInt;
INT_HANDLER func;
PVOID pData;
} INT_THREAD_DATA;
static void __cdecl InterruptHandler(PVOID pContext)
{
INT_THREAD_DATA *pThread = (INT_THREAD_DATA *)pContext;
WD_IntCount(pThread->hWD, pThread->pInt);
pThread->func(pThread->pData);
}
DWORD InterruptEnable(HANDLE *phThread, HANDLE hWD,
WD_INTERRUPT *pInt, INT_HANDLER func, PVOID pData)
{
INT_THREAD_DATA *pThread;
DWORD dwStatus;
*phThread = NULL;
pThread = (INT_THREAD_DATA *)malloc(sizeof(INT_THREAD_DATA));
if (!pThread)
return WD_INSUFFICIENT_RESOURCES;
pInt->kpCall.hKernelPlugIn = WD_KERNEL_DRIVER_PLUGIN_HANDLE;
pInt->kpCall.dwMessage = (DWORD)InterruptHandler;
pInt->kpCall.pData = pThread;
pThread->pInt = pInt;
pThread->hWD = hWD;
pThread->func = func;
pThread->pData = pData;
dwStatus = WD_IntEnable(hWD, pInt);
// check if WD_IntEnable failed
if (dwStatus)
{
free(pThread);
return dwStatus;
}
*phThread = (HANDLE)pThread;
return WD_STATUS_SUCCESS;
}
DWORD InterruptDisable(HANDLE hThread)
{
DWORD dwStatus;
INT_THREAD_DATA *pThread = (INT_THREAD_DATA *)hThread;
if (!pThread)
return WD_INVALID_HANDLE;
dwStatus = WD_IntDisable(pThread->hWD, pThread->pInt);
free(pThread);
return dwStatus;
}
#endif
#else
typedef struct
{
HANDLE hWD;
INT_HANDLER func;
PVOID pData;
WD_INTERRUPT *pInt;
void *thread;
#if defined(WINCE) && defined(WD_CE_ENHANCED_INTR)
HANDLE hIntEvent;
DWORD dwSysintr;
HANDLE hSysintrEvent;
#endif
} INT_THREAD_DATA;
#if defined(WINCE) && defined(WD_CE_ENHANCED_INTR)
static void DLLCALLCONV interrupt_thread_handler(void *data)
{
INT_THREAD_DATA *pThread = (INT_THREAD_DATA *)data;
// wait for dwSysintr to be filled by CEInterruptEnhance()
if (pThread->hIntEvent && OsEventWait(pThread->hSysintrEvent, INFINITE))
return;
CeSetThreadPriority (pThread->thread, THREAD_PRIORITY_TIME_CRITICAL);
for (;;)
{
if (pThread->hIntEvent)
// wait directly on the WINCE's event
WaitForSingleObject(pThread->hIntEvent, INFINITE);
else
// use old style interrupts - another IST is running in the kernel
WD_IntWait (pThread->hWD, pThread->pInt);
if (pThread->pInt->fStopped==INTERRUPT_STOPPED)
break;
if (pThread->pInt->fStopped==INTERRUPT_INTERRUPTED)
continue;
pThread->func(pThread->pData);
if (pThread->hIntEvent)
{
pThread->pInt->dwCounter++;
// invoke interrupt acknowledge commands
WD_MultiTransfer(pThread->hWD, pThread->pInt->Cmd, pThread->pInt->dwCmds);
InterruptDone(pThread->dwSysintr);
}
// else
// in the old-style interrupts, the interrupt acknowledge commands are called
// from the kernel IST
}
}
// notifies the interrupt thread about dwSysintr
void CEInterruptEnhance(HANDLE hThread, DWORD dwSysintr)
{
INT_THREAD_DATA *pThread = (INT_THREAD_DATA *)hThread;
pThread->dwSysintr = dwSysintr;
OsEventSignal(pThread->hSysintrEvent);
}
#else
static void DLLCALLCONV interrupt_thread_handler(void *data)
{
INT_THREAD_DATA *pThread = (INT_THREAD_DATA *)data;
for (;;)
{
WD_IntWait (pThread->hWD, pThread->pInt);
if (pThread->pInt->fStopped==INTERRUPT_STOPPED)
break;
if (pThread->pInt->fStopped==INTERRUPT_INTERRUPTED)
continue;
pThread->func(pThread->pData);
}
}
#endif
DWORD DLLCALLCONV InterruptEnable(HANDLE *phThread, HANDLE hWD, WD_INTERRUPT *pInt,
INT_HANDLER func, PVOID pData)
{
DWORD dwStatus;
INT_THREAD_DATA *pThread;
#if defined(WINCE) && defined(WD_CE_ENHANCED_INTR)
HANDLE hIntEvent;
WCHAR event_name[64] = L"";
#endif
*phThread = NULL;
pThread = (INT_THREAD_DATA *)malloc(sizeof(INT_THREAD_DATA));
if (!pThread)
return WD_INSUFFICIENT_RESOURCES;
dwStatus = WD_IntEnable(hWD, pInt);
if (dwStatus)
goto Error;
BZERO(*pThread);
pThread->func = func;
pThread->pData = pData;
pThread->hWD = hWD;
pThread->pInt = pInt;
#if defined(WINCE) && defined(WD_CE_ENHANCED_INTR)
dwStatus = OsEventCreate(&pThread->hSysintrEvent);
if (dwStatus)
goto Error;
// this event is shared (by its name) between the user mode and the kernel mode
swprintf(event_name, L"WDINT_EVENT_%d", pThread->pInt->hInterrupt);
hIntEvent = CreateEvent(NULL, FALSE, FALSE, event_name);
if (hIntEvent && GetLastError() == ERROR_ALREADY_EXISTS)
{
// use enhanced interrupts
pThread->hIntEvent = hIntEvent;
}
else if (hIntEvent)
{
// use standard interrupts - no need for the event
CloseHandle(hIntEvent);
}
else
{
dwStatus = WD_INSUFFICIENT_RESOURCES;
goto Error;
}
#endif
dwStatus = ThreadStart(&pThread->thread, interrupt_thread_handler, (void *)pThread);
if (dwStatus)
{
WD_IntDisable(hWD, pInt);
goto Error;
}
*phThread = (HANDLE) pThread;
return WD_STATUS_SUCCESS;
Error:
if (pThread)
free(pThread);
#if defined(WINCE) && defined(WD_CE_ENHANCED_INTR)
if (hIntEvent)
CloseHandle(hIntEvent);
#endif
return dwStatus;
}
DWORD DLLCALLCONV InterruptDisable(HANDLE hThread)
{
INT_THREAD_DATA *pThread = (INT_THREAD_DATA *)hThread;
DWORD dwStatus;
if (!pThread)
return WD_INVALID_HANDLE;
#if defined(WINCE) && defined(WD_CE_ENHANCED_INTR)
if (pThread->hIntEvent)
pThread->pInt->fStopped = INTERRUPT_STOPPED;
#endif
dwStatus = WD_IntDisable(pThread->hWD, pThread->pInt);
ThreadWait(pThread->thread);
#if defined(WINCE) && defined(WD_CE_ENHANCED_INTR)
if (pThread->hIntEvent)
CloseHandle(pThread->hIntEvent);
#endif
free(pThread);
return dwStatus;
}
#endif
#ifdef __cplusplus
}
#endif // __cplusplus
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -