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