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

📄 wdu_lib.c

📁 一个基于windriver开发的
💻 C
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////////////
// File - wdu_lib.c
//
// WinDriver USB API Declarations & Implementations
//
// Copyright (c) 2003 Jungo Ltd.  http://www.jungo.com 
////////////////////////////////////////////////////////////////

#include "../include/wdu_lib.h"
#include "../include/windrvr_events.h"
#include "../include/status_strings.h"
#include "../include/utils.h"
#include <stdarg.h>
#include <stdio.h>

// Print Functions

#if !defined(TRACE)
int __cdecl TRACE(const char *fmt, ...) 
{ 
    #if defined(DEBUG)
        va_list argp;
        va_start(argp, fmt);
        vfprintf(stderr, fmt, argp);
        va_end(argp);
    #endif
    return 0;
}
#endif

#if !defined(ERR)
int __cdecl ERR(const char *fmt, ...) 
{ 
    #if defined(DEBUG)
        va_list argp;
        va_start(argp, fmt);
        fprintf(stderr, "WDERROR: ");
        vfprintf(stderr, fmt, argp);
        va_end(argp);
    #endif
    return 0;
}
#endif

// Structures

#define WDU_DEVLIST_TIMEOUT 30 // in seconds

typedef struct
{
    HANDLE hWD; // old API WinDriver handle
    WDU_EVENT_TABLE EventTable;
    HANDLE hEvents;
} DRIVER_CTX;
    
typedef struct
{
    DRIVER_CTX *pDriverCtx;
    WDU_DEVICE *pDevice; // not fixed size => ptr 
    DWORD dwUniqueID;
} DEVICE_CTX;

typedef struct _WDU_DEVICE_LIST_ITEM
{
    struct _WDU_DEVICE_LIST_ITEM *next;
    DEVICE_CTX *pDeviceCtx;
} WDU_DEVICE_LIST_ITEM; 

typedef struct
{
    WDU_DEVICE_LIST_ITEM *pHead;
    HANDLE hEvent;    
    int iRefCount;
} WDU_DEVICE_LIST;

WDU_DEVICE_LIST DevList; // global devices list

// Private Functions Prototypes

DWORD AddDeviceToDevList(DEVICE_CTX *pDeviceCtx);
DWORD RemoveDeviceFromDevList(DWORD dwUniqueID, DEVICE_CTX **ppDeviceCtx);
DWORD RemoveAllDevicesFromDevList(DRIVER_CTX *pDriverCtx);
DWORD FindDeviceByUniqueID(DWORD dwUniqueID, DEVICE_CTX **ppDeviceCtx);
DWORD FindDeviceByCtx(DEVICE_CTX *pDeviceCtx);

// Translate WD_functions into IOCTLs

#define PARAMS_SET(param) Params.param = param
#define GET_HWD(h) (((DEVICE_CTX *)(h))->pDriverCtx->hWD)

// unique ID is passed in IOCTLs to identify the device/interface instead of
// hDevice like in the old API
#define PARAMS_INIT(T) \
    T Params; \
    BZERO(Params); \
    if (!hDevice || FindDeviceByCtx((DEVICE_CTX *)hDevice) != WD_STATUS_SUCCESS) \
        return WD_DEVICE_NOT_FOUND; \
    Params.dwUniqueID = ((DEVICE_CTX *)hDevice)->dwUniqueID;


DWORD DLLCALLCONV WDU_SetInterface(WDU_DEVICE_HANDLE hDevice, DWORD dwInterfaceNum,
    DWORD dwAlternateSetting)
{
    PARAMS_INIT(WDU_SET_INTERFACE);
    PARAMS_SET(dwInterfaceNum);
    PARAMS_SET(dwAlternateSetting);
    return WD_USetInterface(GET_HWD(hDevice), &Params);
}

// currently not implemented
DWORD DLLCALLCONV WDU_SetConfig(WDU_DEVICE_HANDLE hDevice, DWORD dwConfigNum);

DWORD DLLCALLCONV WDU_ResetPipe(WDU_DEVICE_HANDLE hDevice, DWORD dwPipeNum)
{
    PARAMS_INIT(WDU_RESET_PIPE);
    PARAMS_SET(dwPipeNum);
    return WD_UResetPipe(GET_HWD(hDevice), &Params);
}

// currently not implemented
DWORD DLLCALLCONV WDU_ResetDevice(WDU_DEVICE_HANDLE hDevice);

DWORD DLLCALLCONV WDU_Transfer(WDU_DEVICE_HANDLE hDevice, DWORD dwPipeNum, DWORD fRead, 
    DWORD dwOptions, PVOID pBuffer, DWORD dwBufferSize, PDWORD pdwBytesTransferred, 
    PBYTE pSetupPacket, DWORD dwTimeout)
{
    DWORD dwStatus;
    PARAMS_INIT(WDU_TRANSFER);
    PARAMS_SET(dwPipeNum);
    PARAMS_SET(fRead);
    PARAMS_SET(dwOptions);
    PARAMS_SET(pBuffer);
    PARAMS_SET(dwBufferSize);
    if (pSetupPacket)
        memcpy(&Params.SetupPacket, pSetupPacket, 8);
    PARAMS_SET(dwTimeout);
    dwStatus = WD_UTransfer(GET_HWD(hDevice), &Params);
    *pdwBytesTransferred = Params.dwBytesTransferred;
    return dwStatus;
}

DWORD DLLCALLCONV WDU_HaltTransfer(WDU_DEVICE_HANDLE hDevice, DWORD dwPipeNum)
{
    PARAMS_INIT(WDU_HALT_TRANSFER);
    PARAMS_SET(dwPipeNum);
    return WD_UHaltTransfer(GET_HWD(hDevice), &Params);
}

// User-mode wrappers for kernel functions

void EventHandler(WD_EVENT *pEvent, void *pDriverContext);

DWORD DLLCALLCONV WDU_Init(WDU_DRIVER_HANDLE *phDriver, 
    WDU_MATCH_TABLE *pMatchTables, DWORD dwNumMatchTables, 
    WDU_EVENT_TABLE *pEventTable, const char *sLicense, DWORD dwOptions)
{
    DWORD dwStatus;
    DRIVER_CTX *pDriverCtx = NULL;
    WD_VERSION ver;
    WD_EVENT *event = NULL;
    WD_LICENSE lic;
   
    *phDriver = INVALID_HANDLE_VALUE;

    pDriverCtx = (DRIVER_CTX *) calloc(1, sizeof(DRIVER_CTX));
    if (!pDriverCtx)
    {
        ERR("WDU_Init: cannot malloc memory\n");
        dwStatus = WD_INSUFFICIENT_RESOURCES;
        goto Error;
    }

    // init the device list event
    if (DevList.iRefCount == 0)
    {
        DevList.iRefCount++;
        
        dwStatus = OsEventCreate(&DevList.hEvent);
        if (dwStatus)
        {
            ERR("WDU_Init: cannot create event: dwStatus (0x%x) - %s\n", 
                dwStatus, Stat2Str(dwStatus));
            goto Error;
        }
        dwStatus = OsEventSignal(DevList.hEvent);
        if (dwStatus)
        {
            ERR("WDU_Init: error signaling device list event: dwStatus (0x%x) - %s\n", 
                dwStatus, Stat2Str(dwStatus));
            goto Error;
        }
    }
    
    pDriverCtx->hWD = INVALID_HANDLE_VALUE;
    pDriverCtx->hWD = WD_Open();

    // Check whether handle is valid and version OK
    if (pDriverCtx->hWD==INVALID_HANDLE_VALUE) 
    {
        ERR("WDU_Init: cannot open " WD_PROD_NAME " device\n");
        dwStatus = WD_SYSTEM_INTERNAL_ERROR;
        goto Error;
    }

    strcpy(lic.cLicense, sLicense);
    WD_License(pDriverCtx->hWD, &lic);

    BZERO(ver);
    dwStatus = WD_Version(pDriverCtx->hWD, &ver);
    if ((dwStatus != WD_STATUS_SUCCESS) || (ver.dwVer<WD_VER)) 
    {
        ERR("WDU_Init: incorrect " WD_PROD_NAME " version\n");
        if (!dwStatus)
            dwStatus = WD_INCORRECT_VERSION;
        goto Error;
    }

    pDriverCtx->EventTable = *pEventTable;

    if (pEventTable->pfDeviceAttach)
    {
        DWORD dwAction;
        dwAction = WD_INSERT |
            (pEventTable->pfDeviceDetach ?  WD_REMOVE : 0) |
            (pEventTable->pfPowerChange ? WD_POWER_CHANGED_D0 | 
                                        WD_POWER_CHANGED_D1 |
                                        WD_POWER_CHANGED_D2 |
                                        WD_POWER_CHANGED_D3 |
                                        WD_POWER_SYSTEM_WORKING |
                                        WD_POWER_SYSTEM_SLEEPING1 |
                                        WD_POWER_SYSTEM_SLEEPING2 |
                                        WD_POWER_SYSTEM_SLEEPING3 |
                                        WD_POWER_SYSTEM_HIBERNATE |
                                        WD_POWER_SYSTEM_SHUTDOWN : 0); 
        event = UsbEventCreate(pMatchTables, dwNumMatchTables, dwOptions,
            dwAction);
        if (!event)
        {
            ERR("WDU_Init: cannot malloc memory\n");
            dwStatus = WD_INSUFFICIENT_RESOURCES;
            goto Error;
        }

        dwStatus = EventRegister(&pDriverCtx->hEvents, pDriverCtx->hWD, event,
            EventHandler, pDriverCtx);
        if (dwStatus)
        {
            ERR("WDU_Init: EventRegister failed with dwStatus (0x%x) - %s\n", 
                dwStatus, Stat2Str(dwStatus));
            goto Error;
        }
    }

    *phDriver = pDriverCtx;
    goto Exit;

Error:
    if (pDriverCtx)
        WDU_Uninit(pDriverCtx);
Exit:
    if (event)
        EventFree(event);
    return dwStatus;
}

void DLLCALLCONV WDU_Uninit(WDU_DRIVER_HANDLE hDriver)
{
    DRIVER_CTX *pDriverCtx = (DRIVER_CTX *)hDriver;

    if (pDriverCtx && hDriver != INVALID_HANDLE_VALUE)
    {
        if (pDriverCtx->hWD) 
        {
            if (pDriverCtx->hEvents)
                EventUnregister(pDriverCtx->hEvents);
            WD_Close(pDriverCtx->hWD);
        }
        RemoveAllDevicesFromDevList(pDriverCtx);
        free (pDriverCtx);
    }

    DevList.iRefCount--;
    if (DevList.iRefCount == 0)
        OsEventClose(DevList.hEvent);
}

void EventHandler(WD_EVENT *pEvent, void *pDriverContext)
{
    DRIVER_CTX *pDriverCtx = (DRIVER_CTX *)pDriverContext;
    DEVICE_CTX *pDeviceCtx, *pDummyDeviceCtx;
    WDU_DEVICE_HANDLE hDevice;
    BOOL bControlDevice = FALSE, bChangePower;
    DWORD dwStatus;

    TRACE("EventHandler: got event %d handle 0x%x\n", pEvent->dwAction, pEvent->handle);
    switch (pEvent->dwAction)
    {
    case WD_INSERT:
        // create device context
        pDeviceCtx = (DEVICE_CTX *)calloc(1, sizeof(DEVICE_CTX));
        if (!pDeviceCtx)
        {
            ERR("EventHandler: cannot alloc memory\n");
            return;
        }
        
        // DEVICE_CTX * is used as WDU_DEVICE_HANDLE 
        hDevice = pDeviceCtx; 

        pDeviceCtx->dwUniqueID = pEvent->u.Usb.dwUniqueID;
        pDeviceCtx->pDriverCtx = pDriverCtx;

        // add the device handle to the device list for future IOCTLs
        dwStatus = AddDeviceToDevList(pDeviceCtx);
        if (dwStatus)
        {
            free(pDeviceCtx);
            return;
        }

        // get device info
        dwStatus = WDU_GetDeviceInfo(hDevice, &pDeviceCtx->pDevice);
        if (dwStatus)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -