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

📄 wdc_general.c

📁 WinDriver目录下的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
static DWORD PciSlotToId(const WD_PCI_SLOT *pSlot, WD_PCI_ID *pId)
{
    DWORD dwStatus, i;
    WD_PCI_SCAN_CARDS scanDevices;
    
    BZERO(scanDevices); /* scanCards.searchId.dwVendorId/dwDeviceId = 0 - all cards */
    
    dwStatus = WD_PciScanCards(ghWD, &scanDevices);
    if (WD_STATUS_SUCCESS != dwStatus)
    {
        WdcSetLastErrStr("Failed scanning PCI bus.\n",
            "Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus));
        
        return dwStatus;
    }

    for (i = 0; i < scanDevices.dwCards; i++)
    {
        if ((scanDevices.cardSlot[i].dwBus == pSlot->dwBus) &&
            (scanDevices.cardSlot[i].dwSlot == pSlot->dwSlot) &&
            (scanDevices.cardSlot[i].dwFunction == pSlot->dwFunction))
        {
            pId->dwVendorId = scanDevices.cardId[i].dwVendorId;
            pId->dwDeviceId = scanDevices.cardId[i].dwDeviceId;
            return WD_STATUS_SUCCESS;
        }
    }

    WdcSetLastErrStr("Failed to locate the device "
        "(bus: 0x%lx, slot: 0x%lx, function: 0x%lx)\n",
        pSlot->dwBus, pSlot->dwSlot, pSlot->dwFunction);
    
    return WD_DEVICE_NOT_FOUND;
}

static DWORD PcmciaSlotToId(const WD_PCMCIA_SLOT *pSlot, WD_PCMCIA_ID *pId)
{
    DWORD dwStatus, i;
    WD_PCMCIA_SCAN_CARDS scanDevices;
    
    BZERO(scanDevices); /* scanCards.searchId.wManufacturerId/wCardId = 0 - all cards */
    
    dwStatus = WD_PcmciaScanCards(ghWD, &scanDevices);
    if (WD_STATUS_SUCCESS != dwStatus)
    {
        WdcSetLastErrStr("Failed scanning PCMCIA bus.\n",
            "Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus));
        
        return dwStatus;
    }

    for (i = 0; i < scanDevices.dwCards; i++)
    {
        if ((scanDevices.cardSlot[i].uBus == pSlot->uBus) &&
            (scanDevices.cardSlot[i].uSocket == pSlot->uSocket) &&
            (scanDevices.cardSlot[i].uFunction == pSlot->uFunction))
        {
            pId->wManufacturerId = scanDevices.cardId[i].wManufacturerId;
            pId->wCardId = scanDevices.cardId[i].wCardId;
            return WD_STATUS_SUCCESS;
        }
    }

    WdcSetLastErrStr("Failed to locate the device "
        "(socket: 0x%x, function: 0x%x)\n", pSlot->uSocket, pSlot->uFunction);
    
    return WD_DEVICE_NOT_FOUND;
}

static PWDC_DEVICE DeviceCreate(const PVOID pDeviceInfo, const PVOID pDevCtx,
    WD_BUS_TYPE bus)
{
    PWDC_DEVICE pDev;

    pDev = (PWDC_DEVICE)malloc(sizeof(WDC_DEVICE));
    if (!pDev)
    {
        WdcSetLastErrStr("Failed to allocate memory for the device\n");
        return NULL;
    }
    
    BZERO(*pDev);

    switch (bus)
    {
    case WD_BUS_PCI:
    {
        WD_PCI_CARD_INFO *pInfo = (WD_PCI_CARD_INFO*)pDeviceInfo;
        pDev->slot.pciSlot = pInfo->pciSlot;
        pDev->cardReg.Card = pInfo->Card;

        if (WD_STATUS_SUCCESS != PciSlotToId(&pDev->slot.pciSlot, &pDev->id.pciId))
            goto Error;

        break;
    }
    case WD_BUS_PCMCIA:
    {
        WD_PCMCIA_CARD_INFO *pInfo = (WD_PCMCIA_CARD_INFO*)pDeviceInfo;
        pDev->slot.pcmciaSlot = pInfo->pcmciaSlot;
        pDev->cardReg.Card = pInfo->Card;

        if (WD_STATUS_SUCCESS != PcmciaSlotToId(&pDev->slot.pcmciaSlot, &pDev->id.pcmciaId))
            goto Error;

        break;
    }
    case WD_BUS_ISA:
    {
        pDev->cardReg.Card = *(WD_CARD*)pDeviceInfo;
        break;
    }
    default:
        WdcSetLastErrStr("Error - Invalid bus type (0x%lx)\n", bus);
        goto Error;
        break;
    }

    pDev->pCtx = pDevCtx;

    return pDev;

Error:
    DeviceDestroy(pDev);

    return NULL;
}

static DWORD DeviceOpen(WDC_DEVICE_HANDLE *phDev, const PVOID pDeviceInfo,
    const PVOID pDevCtx, const CHAR *pcKPDriverName, PVOID pKPOpenData,
    WD_BUS_TYPE bus)
{
    DWORD dwStatus;
    PWDC_DEVICE pDev;

    if (!WdcIsValidPtr(phDev, "NULL device handle pointer") ||
        !WdcIsValidPtr(pDeviceInfo, "NULL pointer to device's resources information struct"))
    {
        return WD_INVALID_PARAMETER;
    }

    *phDev = NULL;
    
    pDev = DeviceCreate(pDeviceInfo, pDevCtx, bus);
    if (!pDev)
        return WD_INSUFFICIENT_RESOURCES;

    dwStatus = WD_CardRegister(ghWD, &pDev->cardReg);
    if (WD_STATUS_SUCCESS != dwStatus)
    {
        WdcSetLastErrStr("Failed registering the device. Error 0x%lx - %s\n",
            dwStatus, Stat2Str(dwStatus));
        goto Error;
    }
    
    dwStatus = SetDeviceInfo(pDev);
    if (WD_STATUS_SUCCESS != dwStatus)
        goto Error;
    
    /* Set device handle before KP open to enable passing &hDev as pOpenData */
    *phDev = (WDC_DEVICE_HANDLE)pDev;
    
    if (pcKPDriverName && strcmp(pcKPDriverName, ""))
    {
        dwStatus = KernelPlugInOpen(*phDev, pcKPDriverName, pKPOpenData);
        if(dwStatus != WD_STATUS_SUCCESS)
            goto Error; 
    }
    
    return WD_STATUS_SUCCESS;
    
Error:
    DeviceClose((WDC_DEVICE_HANDLE)pDev);

    *phDev = NULL;
    
    return dwStatus;
}

static void DeviceDestroy(PWDC_DEVICE pDev)
{ 
    if (!pDev)
        return;
    
    if (pDev->pAddrDesc)
        free(pDev->pAddrDesc);

    free(pDev);
}

static DWORD DeviceClose(WDC_DEVICE_HANDLE hDev)
{
    DWORD dwStatus = WD_STATUS_SUCCESS;
    PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
    
    if (!WdcIsValidDevHandle(hDev))
        return WD_INVALID_PARAMETER;

    if (pDev->hIntThread)
    {
        dwStatus = WDC_IntDisable(hDev);
        if (WD_STATUS_SUCCESS != dwStatus)
        {
            WdcSetLastErrStr("Failed disabling interrupt. Error 0x%lx - %s\n",
                dwStatus, Stat2Str(dwStatus));
        }
    }

    if (pDev->hEvent)
    {
        dwStatus = WDC_EventUnregister(hDev);
        if (WD_STATUS_SUCCESS != dwStatus)
        {
            WdcSetLastErrStr("Failed unregistering events. Error 0x%lx - %s\n",
                dwStatus, Stat2Str(dwStatus));
        }
    }
    
    if (WDC_IS_KP(pDev))
    {
        dwStatus = WD_KernelPlugInClose(ghWD, &pDev->kerPlug);
        if (WD_STATUS_SUCCESS != dwStatus)
        {
            WdcSetLastErrStr("Failed closing Kernel PlugIn handle 0x%lx.\n"
                "Error 0x%lx - %s\n", WDC_GET_KP_HANDLE(pDev), dwStatus,
                Stat2Str(dwStatus));
        }
    }

    if (pDev->kerPlug.pcDriverName)
        free(pDev->kerPlug.pcDriverName);

    if (WDC_GET_CARD_HANDLE(pDev))
    {
        dwStatus = WD_CardUnregister(ghWD, &pDev->cardReg);
        if (WD_STATUS_SUCCESS != dwStatus)
        {
            WdcSetLastErrStr("Failed unregistering the device (handle 0x%lx).\n"
                "Error 0x%lx - %s\n",
                WDC_GET_CARD_HANDLE(pDev), dwStatus, Stat2Str(dwStatus));
        }
    }

    DeviceDestroy(pDev);
    
    return dwStatus;
}

static DWORD KernelPlugInOpen(WDC_DEVICE_HANDLE hDev, 
    const CHAR *pcKPDriverName, PVOID pKPOpenData)
{
    DWORD dwStatus;
    PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;

    pDev->kerPlug.pcDriverName = strdup(pcKPDriverName);
    pDev->kerPlug.pOpenData = pKPOpenData;
        
    dwStatus = WD_KernelPlugInOpen(ghWD, &pDev->kerPlug);

    if (WD_STATUS_SUCCESS != dwStatus)
    {
        WdcSetLastErrStr("Failed opening a handle to the Kernel PlugIn.\n"
            "Error 0x%lx - %s\n", dwStatus, Stat2Str(dwStatus));
    }

    return dwStatus;    
}

#define MAX_ADDR_SPACE_NUM WD_CARD_ITEMS
static DWORD SetDeviceInfo(PWDC_DEVICE pDev)
{
    DWORD i;
    DWORD dwNumAddrs = 0;
    DWORD dwNumItems = pDev->cardReg.Card.dwItems;
    WD_ITEMS *pItem = pDev->cardReg.Card.Item;
    WDC_ADDR_DESC addrDescs[MAX_ADDR_SPACE_NUM];
    WDC_ADDR_DESC *pAddrDesc;

    BZERO(addrDescs);
    for (i=0; i<dwNumItems; i++, pItem++)
    {
        switch (pItem->item)
        {
        case ITEM_INTERRUPT:
            pDev->Int.hInterrupt = pItem->I.Int.hInterrupt;
            pDev->Int.dwOptions = pItem->I.Int.dwOptions;
            break;
        case ITEM_MEMORY:
        case ITEM_IO:
            if (pItem->item == ITEM_MEMORY)
            {
                pAddrDesc = &addrDescs[pItem->I.Mem.dwBar];
                pAddrDesc->fIsMemory = TRUE;
                pAddrDesc->dwAddrSpace = pItem->I.Mem.dwBar;
                pAddrDesc->kptAddr = pItem->I.Mem.dwTransAddr;
                pAddrDesc->dwUserDirectMemAddr = pItem->I.Mem.dwUserDirectAddr;
                pAddrDesc->dwBytes = pItem->I.Mem.dwBytes;
            }
            else
            {
                pAddrDesc = &addrDescs[pItem->I.IO.dwBar];
                pAddrDesc->fIsMemory = FALSE;
                pAddrDesc->dwAddrSpace = pItem->I.IO.dwBar;
                pAddrDesc->kptAddr = pItem->I.IO.dwAddr;
                pAddrDesc->dwBytes = pItem->I.IO.dwBytes;
            }

            pAddrDesc->dwItemIndex = i;
            dwNumAddrs = MAX(pAddrDesc->dwAddrSpace + 1, dwNumAddrs);
            break;
        default:
            break;
        }
    }

    if (dwNumAddrs)
    {
        pDev->pAddrDesc = (WDC_ADDR_DESC*)malloc(dwNumAddrs * sizeof(WDC_ADDR_DESC));
        if (!pDev->pAddrDesc)
        {
            WdcSetLastErrStr("Failed allocating memory for address spaces "
                "description (insufficient resources)\n");
            return WD_INSUFFICIENT_RESOURCES;
        }
        memcpy(pDev->pAddrDesc, addrDescs, dwNumAddrs * sizeof(addrDescs[0]));
        pDev->dwNumAddrSpaces = dwNumAddrs;
    }

    return WD_STATUS_SUCCESS;
}

#endif

/* -----------------------------------------------
    Set card cleanup commands
   ----------------------------------------------- */
DWORD WDC_CardCleanupSetup(WDC_DEVICE_HANDLE hDev, WD_TRANSFER *Cmd,
    DWORD dwCmds, BOOL bForceCleanup)
{
    PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
    WD_CARD_CLEANUP cardCleanup;

    if (!Cmd || !dwCmds)
        return WD_INVALID_PARAMETER;
    
    cardCleanup.hCard = WDC_GET_CARD_HANDLE(pDev);
    cardCleanup.Cmd = Cmd;
    cardCleanup.dwCmds = dwCmds;
    cardCleanup.dwOptions = bForceCleanup ? WD_FORCE_CLEANUP : 0;
    
    return WD_CardCleanupSetup(ghWD, &cardCleanup);
}

/* -----------------------------------------------
    Send Kernel PlugIn messages
   ----------------------------------------------- */
DWORD DLLCALLCONV WDC_CallKerPlug(WDC_DEVICE_HANDLE hDev, DWORD dwMsg,
    PVOID pData, PDWORD pdwResult)
{
    DWORD dwStatus;
    PWDC_DEVICE pDev = (PWDC_DEVICE)hDev;
    WD_KERNEL_PLUGIN_CALL kpCall;

    BZERO(kpCall);
    kpCall.hKernelPlugIn = WDC_GET_KP_HANDLE(pDev);
    kpCall.dwMessage = dwMsg;
    kpCall.pData = pData;
    dwStatus = WD_KernelPlugInCall(ghWD, &kpCall);
    if (WD_STATUS_SUCCESS != dwStatus)
    {
        WDC_Err("WDC_CallKerPlug: Failed sending 0x%lx message to the Kernel PlugIn (%s).\n"
            "Error 0x%lx - %s\n",
            dwMsg, pDev->kerPlug.pcDriverName, dwStatus, Stat2Str(dwStatus));
    }
    else if (pdwResult)
        *pdwResult = kpCall.dwResult;

    return dwStatus;
}

⌨️ 快捷键说明

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