硬件資源的獲取,解析
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;
}