第七篇 硬件內存資源的獲取,解析

 

硬件資源的獲取,解析

  

1. 生成WDF的KMDFhelloWorld程序

2. 改寫INF文件中硬件ID

3. 編譯安裝

以上三點不重複介紹,下面直接關注更新,增加的代碼。

 

在DeviceADD例程中添加

首先是增加即插即用管理....  應該對應於WDM的IRP_MN_START_DEVICE

//初始化即插即用和電源管理例程配置結構

WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);

pnpPowerCallbacks.EvtDevicePrepareHardware= PCISample_EvtDevicePrepareHardware;

//註冊即插即用和電源管理例程

WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);

 

獲取內存資源:

例程實現如下

NTSTATUS

PCISample_EvtDevicePrepareHardware(

IN WDFDEVICE Device,

IN WDFCMRESLIST ResourceList,

IN WDFCMRESLIST ResourceListTranslated

)

{

    PDEVICE_CONTEXT pDeviceContext;

    ULONG           i;

    PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;

 

    PAGED_CODE();

 

    KdPrint(("EvtDevicePrepareHardware -begins\n"));

 

    pDeviceContext =DeviceGetContext(Device);

    pDeviceContext->MemBaseAddress= NULL;

 

    //

    // Parse the resource list and savethe resource information.

    //

    i = WdfCmResourceListGetCount(ResourceListTranslated);

    KdPrint(("WdfCmResourceListGetCount=%d", i));

    for (i = 0; i <WdfCmResourceListGetCount(ResourceListTranslated); i++) {

 

       

        descriptor =WdfCmResourceListGetDescriptor(ResourceListTranslated, i);

 

        KdPrint(("i=%d Type=%d", i, descriptor->Type));

        switch (descriptor->Type) {

        case CmResourceTypeInterrupt

        case CmResourceTypeMemory:

            //MmMapIoSpace將物理地址轉換成系統內核模式地址

            pDeviceContext->MemBaseAddress= MmMapIoSpace(

                descriptor->u.Memory.Start,

                descriptor->u.Memory.Length,

                MmNonCached);

            pDeviceContext->MemLength= descriptor->u.Memory.Length;

            KdPrint(("pDeviceContext->MemLength=%u", pDeviceContext->MemLength));

            break;

 

        default:

            break;

        }

 

    }

 

    KdPrint(("EvtDevicePrepareHardware -ends\n"));

 

    return STATUS_SUCCESS;

}

 

注意釋放資源

 

NTSTATUS

PCISample_EvtDeviceReleaseHardware(

IN WDFDEVICE Device,

IN WDFCMRESLIST ResourceListTranslated

)

{

    PDEVICE_CONTEXT pDeviceContext;

 

    PAGED_CODE();

 

    KdPrint(("EvtDeviceReleaseHardware -begins\n"));

 

    pDeviceContext =DeviceGetContext(Device);

 

    if (pDeviceContext->MemBaseAddress){

        //MmUnmapIoSpace解除物理地址與系統內核模式地址的關聯

        MmUnmapIoSpace(pDeviceContext->MemBaseAddress,pDeviceContext->MemLength);

        pDeviceContext->MemBaseAddress= NULL;

        KdPrint(("pDeviceContext->MemLength=%u",pDeviceContext->MemLength));

    }

    else

    {

        KdPrint(("pDeviceContext->MemBaseAddress=%x",pDeviceContext->MemBaseAddress));

    }

 

    KdPrint(("EvtDeviceReleaseHardware -ends\n"));

 

    return STATUS_SUCCESS;

}

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章