这段是PCI设备驱动的遍历信息函数,实现了遍历PCI的设备的具体配置信息
#pragma PAGEDCODE
NTSTATUS InitMyPCI(IN PDEVICE_EXTENSION pdx,IN PCM_PARTIAL_RESOURCE_LIST list)
{
PDEVICE_OBJECT fdo = pdx->fdo;
ULONG vector;
KIRQL irql;
KINTERRUPT_MODE mode;
KAFFINITY affinity;
BOOLEAN irqshare;
BOOLEAN gotinterrupt = FALSE;
PHYSICAL_ADDRESS portbase;
BOOLEAN gotport = FALSE;
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = &list->PartialDescriptors[0];
ULONG nres = list->Count;
BOOLEAN IsMem0 = TRUE;
for (ULONG i = 0; i < nres; ++i, ++resource)
{ // for each resource
switch (resource->Type)
{ // switch on resource type
case CmResourceTypePort:
portbase = resource->u.Port.Start;
pdx->nports = resource->u.Port.Length;
pdx->mappedport = (resource->Flags & CM_RESOURCE_PORT_IO) == 0;
gotport = TRUE;
break;
case CmResourceTypeMemory:
if (IsMem0)
{
pdx->MemBar0 = (PUCHAR)MmMapIoSpace(resource->u.Memory.Start,
resource->u.Memory.Length,
MmNonCached);
pdx->nMem0 = resource->u.Memory.Length;
IsMem0 = FALSE;
}else
{
pdx->MemBar1 = (PUCHAR)MmMapIoSpace(resource->u.Memory.Start,
resource->u.Memory.Length,
MmNonCached);
pdx->nMem1 = resource->u.Memory.Length;
}
break;
case CmResourceTypeInterrupt:
irql = (KIRQL) resource->u.Interrupt.Level;
vector = resource->u.Interrupt.Vector;
affinity = resource->u.Interrupt.Affinity;
mode = (resource->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
? Latched : LevelSensitive;
irqshare = resource->ShareDisposition == CmResourceShareShared;
gotinterrupt = TRUE;
break;
default:
KdPrint(("Unexpected I/O resource type %d/n", resource->Type));
break;
} // switch on resource type
} // for each resource
if (!(TRUE&& gotport&& gotinterrupt ))
{
KdPrint((" Didn't get expected I/O resources/n"));
return STATUS_DEVICE_CONFIGURATION_ERROR;
}
if (pdx->mappedport)
{ // map port address for RISC platform
pdx->portbase = (PUCHAR) MmMapIoSpace(portbase, pdx->nports, MmNonCached);
if (!pdx->mappedport)
{
KdPrint(("Unable to map port range %I64X, length %X/n", portbase, pdx->nports));
return STATUS_INSUFFICIENT_RESOURCES;
}
} // map port address for RISC platform
else
pdx->portbase = (PUCHAR) portbase.QuadPart;
NTSTATUS status = IoConnectInterrupt(&pdx->InterruptObject, (PKSERVICE_ROUTINE) OnInterrupt,
(PVOID) pdx, NULL, vector, irql, irql, LevelSensitive, TRUE, affinity, FALSE);
if (!NT_SUCCESS(status))
{
KdPrint(("IoConnectInterrupt failed - %X/n", status));
if (pdx->portbase && pdx->mappedport)
MmUnmapIoSpace(pdx->portbase, pdx->nports);
pdx->portbase = NULL;
return status;
}
#define IMAGE_LENGTH (640*480)
//申请一段连续物理地址来读取图像
PHYSICAL_ADDRESS maxAddress;
maxAddress.u.LowPart = 0xFFFFFFFF;
maxAddress.u.HighPart = 0;
pdx->MemForImage = MmAllocateContiguousMemory(IMAGE_LENGTH,maxAddress);
PHYSICAL_ADDRESS pycialAddressForImage = MmGetPhysicalAddress(pdx->MemForImage);
WRITE_REGISTER_BUFFER_UCHAR((PUCHAR)pdx->MemBar0+0x10000,
(PUCHAR)&pycialAddressForImage.u.LowPart,4);
return STATUS_SUCCESS;
}
----------------------------上面这段程序用SP3+VS2008+wdk6001.1280编译会出现几个问题如下:
1>HelloWDM.obj : error LNK2019: unresolved external symbol __imp__MmGetPhysicalAddress@4 referenced in function "long __stdcall InitMyPCI(struct _DEVICE_EXTENSION *,struct _CM_PARTIAL_RESOURCE_LIST *)" (?InitMyPCI@@YGJPAU_DEVICE_EXTENSION@@PAU_CM_PARTIAL_RESOURCE_LIST@@@Z)
1>HelloWDM.obj : error LNK2019: unresolved external symbol __imp__MmAllocateContiguousMemory@12 referenced in function "long __stdcall InitMyPCI(struct _DEVICE_EXTENSION *,struct _CM_PARTIAL_RESOURCE_LIST *)" (?InitMyPCI@@YGJPAU_DEVICE_EXTENSION@@PAU_CM_PARTIAL_RESOURCE_LIST@@@Z)
1>MyDriver_Check/HelloWDM.sys : fatal error LNK1120: 2 unresolved externals
问题原因:暂时还不是太清楚,分析可能是有几个链接库文件没有加载进来的原因。具体也不是太清楚,正在研究中。