📄 watchdog.c
字号:
return hWDThrd;
}
//--------------------------------------------------------------------------------------------
// create/open a watchdog timer
//--------------------------------------------------------------------------------------------
static HANDLE WDOpenOrCreate (int apiCode, PCWDAPIStruct pwdas)
{
HANDLE hWDog;
LPCWSTR pszWatchDogName = (LPCWSTR) pwdas->watchdog;
DEBUGMSG (ZONE_ENTRY, (L"WDOpenOrCreate: '%s', %d, %d, %8.8lx, %8.8lx\r\n",
pszWatchDogName, pwdas->dwPeriod, pwdas->dwWait, pwdas->dwDfltAction, pwdas->dwParam));
// create/open the watchdog event
hWDog = (WDAPI_CREATE == apiCode)
? SC_CreateEvent (NULL, FALSE, FALSE, pszWatchDogName)
: SC_OpenEvent (EVENT_ALL_ACCESS, FALSE, pszWatchDogName);
if (hWDog) {
PWatchDog pWD;
DWORD dwErr = ERROR_OUTOFMEMORY;
if ((WDAPI_OPEN == apiCode)
|| (pszWatchDogName && (ERROR_ALREADY_EXISTS == KGetLastError (pCurThread)))) {
// event exists, verify if it's a watchdog timer
dwErr = GetWatchDog (hWDog)? 0 : ERROR_INVALID_NAME;
} else if (pWD = AllocMem (HEAP_WATCHDOG)) {
// new watchdog, initialized the watchdog structre
pWD->dwDfltAction = pwdas->dwDfltAction;
pWD->dwParam = pwdas->dwParam;
pWD->dwPeriod = pwdas->dwPeriod;
pWD->dwState = WD_STATE_STOPPED;
pWD->dwWait = pwdas->dwWait;
pWD->hProc = NULL;
pWD->hWDog = hWDog;
pWD->pNext = NULL;
pWD->pPrev = NULL;
SetWatchDog (hWDog, pWD);
dwErr = 0;
}
if (dwErr) {
KSetLastError (pCurThread, dwErr);
SC_EventCloseHandle (hWDog);
hWDog = NULL;
}
}
DEBUGMSG (ZONE_ENTRY, (L"WDOpenOrCreate: returns %8.8lx\r\n", hWDog));
return hWDog;
}
//--------------------------------------------------------------------------------------------
// start a watchdog timer
//--------------------------------------------------------------------------------------------
static BOOL WDStart (HANDLE hWDog)
{
PWatchDog pWD;
BOOL dwErr = ERROR_INVALID_PARAMETER;
DEBUGMSG (ZONE_ENTRY, (L"WDStart: %8.8lx\r\n", hWDog));
if (pWD = GetWatchDog (hWDog)) {
if (WD_STATE_STOPPED == pWD->dwState) {
pWD->dwExpire = SC_GetTickCount () + pWD->dwPeriod;
pWD->dwState = WD_STATE_STARTED;
pWD->hProc = hCurProc;
WDenqueue (pWD);
// signal watchdog timer thread to start running and re-calculate timeout
SetEvent (hWDEvt);
dwErr = 0;
} else {
// already started
dwErr = ERROR_ALREADY_INITIALIZED;
}
}
if (dwErr) {
KSetLastError (pCurThread, dwErr);
}
DEBUGMSG (ZONE_ENTRY, (L"WDStart: exits, dwErr = %8.8lx\r\n", dwErr));
return !dwErr;
}
//--------------------------------------------------------------------------------------------
// stop a watchdog timer
//--------------------------------------------------------------------------------------------
static BOOL WDStop (HANDLE hWDog)
{
PWatchDog pWD;
DEBUGMSG (ZONE_ENTRY, (L"WDStop: %8.8lx\r\n", hWDog));
if (!(pWD = GetWatchDog (hWDog))) {
KSetLastError (pCurThread, ERROR_INVALID_PARAMETER);
} else if (WD_STATE_STOPPED != pWD->dwState) {
pWD->dwState = WD_STATE_STOPPED;
WDdequeue (pWD);
}
DEBUGMSG (ZONE_ENTRY, (L"WDStop: returns %8.8lx\r\n", NULL != pWD));
return NULL != pWD;
}
//--------------------------------------------------------------------------------------------
// refresh a watchdog timer
//--------------------------------------------------------------------------------------------
static BOOL WDRefresh (
HANDLE hWDog)
{
PWatchDog pWD;
DEBUGMSG (ZONE_ENTRY, (L"WDRefresh: %8.8lx\r\n", hWDog));
if (!(pWD = GetWatchDog (hWDog))) {
KSetLastError (pCurThread, ERROR_INVALID_PARAMETER);
} else if (WD_STATE_STOPPED != pWD->dwState) {
WDdequeue (pWD);
pWD->dwExpire = SC_GetTickCount () + pWD->dwPeriod;
pWD->dwState = WD_STATE_STARTED;
WDenqueue (pWD);
}
DEBUGMSG (ZONE_ENTRY, (L"WDRefresh: returns %8.8lx\r\n", NULL != pWD));
return NULL != pWD;
}
//--------------------------------------------------------------------------------------------
// Initialize Watchdog support
//--------------------------------------------------------------------------------------------
BOOL InitWatchDog (void)
{
// create the watchdog thread signal event
hWDEvt = SC_CreateEvent (NULL, FALSE, FALSE, NULL);
DEBUGCHK (hWDEvt);
// create watchdog thread if hardware watchdog exist
if (FakedRefreshWatchDog != pfnOEMRefreshWatchDog) {
DEBUGMSG (1, (L"Hardware watchdog supported, watchdog period = %dms, watchdog thread priority = %d\r\n",
dwOEMWatchDogPeriod, dwNKWatchDogThreadPriority));
CreateWatchDogThread ();
DEBUGCHK (hWDThrd);
}
return NULL != hWDEvt;
}
//--------------------------------------------------------------------------------------------
// watchdog timer API handler
//--------------------------------------------------------------------------------------------
DWORD WatchDogAPI (DWORD apiCode, PCWDAPIStruct pwdas)
{
DWORD dwErr = 0;
DWORD dwRet = 0;
if (!pwdas || pwdas->dwFlags) {
dwErr = ERROR_INVALID_PARAMETER;
} else {
EnterCriticalSection (&WDcs);
switch (apiCode) {
case WDAPI_CREATE:
// validate parameters
if (((int) pwdas->dwPeriod <= 0)
|| ((int) pwdas->dwWait < 0)
|| (pwdas->dwDfltAction >= WD_TOTAL_DFLT_ACTION)) {
dwErr = ERROR_INVALID_PARAMETER;
break;
}
// create the watchdog thread if not already created
if (!CreateWatchDogThread ()) {
dwErr = ERROR_OUTOFMEMORY;
break;
}
// fall through to open/create watchdog
case WDAPI_OPEN:
dwRet = (DWORD) WDOpenOrCreate (apiCode, pwdas);
break;
case WDAPI_START:
dwRet = WDStart ((HANDLE) pwdas->watchdog);
break;
case WDAPI_STOP:
dwRet = WDStop ((HANDLE) pwdas->watchdog);
break;
case WDAPI_REFRESH:
dwRet = WDRefresh ((HANDLE) pwdas->watchdog);
break;
default:
dwErr = ERROR_INVALID_PARAMETER;
break;
}
LeaveCriticalSection (&WDcs);
}
return dwRet;
}
//--------------------------------------------------------------------------------------------
// delete a watchdog timer (called by EventCloseHandle)
//--------------------------------------------------------------------------------------------
BOOL WDDelete (HANDLE hWDog)
{
PWatchDog pWD;
DEBUGMSG (ZONE_ENTRY, (L"WDDelete: %8.8lx\r\n", hWDog));
EnterCriticalSection (&WDcs);
if (pWD = GetWatchDog (hWDog)) {
SetWatchDog (hWDog, NULL);
if (WD_STATE_STOPPED != pWD->dwState) {
WDdequeue (pWD);
}
FreeMem (pWD, HEAP_WATCHDOG);
}
LeaveCriticalSection (&WDcs);
DEBUGMSG (ZONE_ENTRY, (L"WDDelete: returns %8.8lx\r\n", NULL != pWD));
return NULL != pWD;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -