⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windrvr_int_thread.cpp

📁 采用windriver提供的API开发的D12应用程序源码
💻 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 + -