WDM下HalGetBusData不能用了。加上感觉pnp方式太麻烦。 自己修改了驱动开发技术详解上的代码直接在驱动下获取信息

#include "Driver.h"
NTSTATUS DriverEntry(
	IN PDRIVER_OBJECT pDriverObject,
	IN PUNICODE_STRING pRegistryPath)
{
	NTSTATUS status;
	//判断CPU类型
	CPUType();
	//枚举
	EnumeratePCI();
	KdPrint(("Enter DriverEntry\n"));
	//DbgBreakPoint();
	//设置卸载函数
	pDriverObject->DriverUnload =DDKUnload;
	//设置派遣函数
	pDriverObject->MajorFunction[IRP_MJ_CREATE] = DDKDispatchRoutin;
	pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DDKDispatchRoutin;
	pDriverObject->MajorFunction[IRP_MJ_WRITE] = DDKDispatchRoutin;
	pDriverObject->MajorFunction[IRP_MJ_READ] = DDKDispatchRoutin;
	pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = DDKDispatchRoutin;
	pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DDKDispatchRoutin;
	pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = DDKDispatchRoutin;
	pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DDKDispatchRoutin;
	pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DDKDispatchRoutin;

	//创建驱动设备对象
	status = CreateDevice(pDriverObject);

	KdPrint(("Leave DriverEntry\n"));
	return status;
}

NTSTATUS CreateDevice(
	IN PDRIVER_OBJECT	pDriverObject)
{
	NTSTATUS status;
	PDEVICE_OBJECT pDevObj;
	PDEVICE_EXTENSION pDevExt;

	//创建设备名称
	UNICODE_STRING devName;
	RtlInitUnicodeString(&devName, L"\\Device\\MyDDKDevice");

	//创建设备
	status = IoCreateDevice(pDriverObject,
		sizeof(DEVICE_EXTENSION),
		&devName,
		FILE_DEVICE_UNKNOWN,
		0, TRUE,
		&pDevObj);
	if (!NT_SUCCESS(status))
		return status;

	pDevObj->Flags |= DO_BUFFERED_IO;
	pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
	pDevExt->pDevice = pDevObj;
	pDevExt->ustrDeviceName = devName;
	//创建符号链接
	UNICODE_STRING symLinkName;
	RtlInitUnicodeString(&symLinkName, L"\\??\\TESTDDK");
	pDevExt->ustrSymLinkName = symLinkName;
	status = IoCreateSymbolicLink(&symLinkName, &devName);
	if (!NT_SUCCESS(status))
	{
		IoDeleteDevice(pDevObj);
		return status;
	}
	return STATUS_SUCCESS;
}

#pragma PAGEDCODE
VOID DDKUnload(IN PDRIVER_OBJECT pDriverObject)
{
	PDEVICE_OBJECT	pNextObj;
	KdPrint(("Enter DriverUnload\n"));
	
	pNextObj = pDriverObject->DeviceObject;
	while (pNextObj != NULL)
	{
		PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
			pNextObj->DeviceExtension;

		//删除符号链接
		UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
		IoDeleteSymbolicLink(&pLinkName);
		pNextObj = pNextObj->NextDevice;
		IoDeleteDevice(pDevExt->pDevice);
	}
}


#pragma PAGEDCODE
NTSTATUS DDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,
	IN PIRP pIrp)
{
	KdPrint(("Enter HelloDDKDispatchRoutin\n"));

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
	//建立一个字符串数组与IRP类型对应起来
	static char* irpname[] =
	{
		"IRP_MJ_CREATE",
		"IRP_MJ_CREATE_NAMED_PIPE",
		"IRP_MJ_CLOSE",
		"IRP_MJ_READ",
		"IRP_MJ_WRITE",
		"IRP_MJ_QUERY_INFORMATION",
		"IRP_MJ_SET_INFORMATION",
		"IRP_MJ_QUERY_EA",
		"IRP_MJ_SET_EA",
		"IRP_MJ_FLUSH_BUFFERS",
		"IRP_MJ_QUERY_VOLUME_INFORMATION",
		"IRP_MJ_SET_VOLUME_INFORMATION",
		"IRP_MJ_DIRECTORY_CONTROL",
		"IRP_MJ_FILE_SYSTEM_CONTROL",
		"IRP_MJ_DEVICE_CONTROL",
		"IRP_MJ_INTERNAL_DEVICE_CONTROL",
		"IRP_MJ_SHUTDOWN",
		"IRP_MJ_LOCK_CONTROL",
		"IRP_MJ_CLEANUP",
		"IRP_MJ_CREATE_MAILSLOT",
		"IRP_MJ_QUERY_SECURITY",
		"IRP_MJ_SET_SECURITY",
		"IRP_MJ_POWER",
		"IRP_MJ_SYSTEM_CONTROL",
		"IRP_MJ_DEVICE_CHANGE",
		"IRP_MJ_QUERY_QUOTA",
		"IRP_MJ_SET_QUOTA",
		"IRP_MJ_PNP",
	};

	UCHAR type = stack->MajorFunction;
	if (type >= arraysize(irpname))
		KdPrint((" - Unknown IRP, major type %X\n", type));
	else
		KdPrint(("\t%s\n", irpname[type]));


	//对一般IRP的简单操作,后面会介绍对IRP更复杂的操作
	NTSTATUS status = STATUS_SUCCESS;
	// 完成IRP
	pIrp->IoStatus.Status = status;
	pIrp->IoStatus.Information = 0;	// bytes xfered
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	KdPrint(("Leave DDKDispatchRoutin\n"));

	return status;
}

stRet CPUType()
{
	stRet st_Ret = {FALSE,FALSE}; 
	ULONG CPUInfo[4] = { -1 };
	CHAR cpu_string[48];
	__cpuid(CPUInfo, 0);
	INT num_ids = CPUInfo[0];
	//GenuineIntel是Intel的CPU 
	//0x47, 0x65, 0x6E, 0x75,   0x69, 0x6E, 0x65, 0x49,   0x6E, 0x74, 0x65, 0x6C,   0x00, 0x00, 0x00, 0x00 GenuineIntel
	if ((CPUInfo[1] == 0x756e6547) && (CPUInfo[2] == 0x6c65746e) && (CPUInfo[3] == 0x49656e69))
	{
		st_Ret.bIntelCPU=TRUE;
		KdPrint(("GenuineIntel\n"));
	}
	//AuthenticAMD 是AMD的CPU
	//0x41, 0x75, 0x74, 0x68,   0x65, 0x6E, 0x74, 0x69,   0x63, 0x41, 0x4D, 0x44,   0x00, 0x00, 0x00, 0x00  AuthenticAMD
	if ((CPUInfo[1] == 0x68747541) && (CPUInfo[2] == 0x444d4163) && (CPUInfo[3] == 0x69746e65))
	{
		st_Ret.bIntelCPU = TRUE;
		KdPrint(("AuthenticAMD\n"));
	}
	INT cpu_info[4] = { -1 };
	__cpuid(cpu_info, 0);
	// Interpret CPU feature information.
	if (num_ids > 0) {
		int cpu_info7[4] = { 0 };
		__cpuid(cpu_info, 1);
		if (num_ids >= 7) {
			__cpuid(cpu_info7, 7);
		}
		signature_ = cpu_info[0];
		stepping_ = cpu_info[0] & 0xf;
		model_ = ((cpu_info[0] >> 4) & 0xf) + ((cpu_info[0] >> 12) & 0xf0);
		family_ = (cpu_info[0] >> 8) & 0xf;
		type_ = (cpu_info[0] >> 12) & 0x3;
		ext_model_ = (cpu_info[0] >> 16) & 0xf;
		ext_family_ = (cpu_info[0] >> 20) & 0xff;
		has_mmx_ = (cpu_info[3] & 0x00800000) != 0;
		has_sse_ = (cpu_info[3] & 0x02000000) != 0;
		has_sse2_ = (cpu_info[3] & 0x04000000) != 0;
		has_sse3_ = (cpu_info[2] & 0x00000001) != 0;
		has_ssse3_ = (cpu_info[2] & 0x00000200) != 0;
		has_sse41_ = (cpu_info[2] & 0x00080000) != 0;
		has_sse42_ = (cpu_info[2] & 0x00100000) != 0;
		has_aesni_ = (cpu_info[2] & 0x02000000) != 0;
		has_avx2_ = has_avx_ && (cpu_info7[1] & 0x00000020) != 0;
	}

	// Get the brand string of the cpu.
	__cpuid(cpu_info, 0x80000000);
	const int parameter_end = 0x80000004;
	int max_parameter = cpu_info[0];

	//CHAR temp[40] = { -1 };
	if (cpu_info[0] >= parameter_end) {
		PCHAR cpu_string_ptr = cpu_string;
		for (int parameter = 0x80000002; parameter <= parameter_end &&
			cpu_string_ptr < &cpu_string[lstrlen(cpu_string)]; parameter++) {
			__cpuid(cpu_info, parameter);
			lstrcpy(cpu_string_ptr, cpu_info, lstrlen(cpu_info));
			cpu_string_ptr += lstrlen(cpu_info);
		}
		//lstrcpy(g_cpu_string, cpu_string_ptr-34, 32);
		KdPrint(("cpu_string:%s cpu_string:%x\n", cpu_string, cpu_string));
		//DbgBreakPoint(); 
	}

	const int parameter_containing_non_stop_time_stamp_counter = 0x80000007;
	if (max_parameter >= parameter_containing_non_stop_time_stamp_counter) {
		__cpuid(cpu_info, parameter_containing_non_stop_time_stamp_counter);
		has_non_stop_time_stamp_counter_ = (cpu_info[3] & (1 << 8)) != 0;
	} 
	return st_Ret;
}
//	字符串长度
DWORD lstrlen(PCHAR pSrc)
{
	DWORD	dwRet = 0;

	while (*pSrc != 0)
	{
		dwRet++;
		pSrc++;
	}
	return dwRet;
}
//	字符拷贝
VOID lstrcpy(PCHAR pDst, PCHAR pSrc, DWORD len)
{
	//while (1)
	//{
	//	//	复制字符,直到零结尾
	//	*pDst = *pSrc;
	//	if (*pSrc == 0)
	//		break;

	//	//	下一个字符
	//	pSrc++;
	//	pDst++;
	//}
	for (DWORD i = 0; i < len; i++) {
			//	复制字符 
			*pDst = *pSrc;
			if (*pSrc == 0)
				break;
			//	下一个字符
			pSrc++;
			pDst++;
	}
}

//VOID EnumeratePCI()
//{
//	ULONG bus;
//	ULONG dev;
//	ULONG func;
//
//	PCI_COMMON_CONFIG PciConfig;
//	PCI_SLOT_NUMBER SlotNumber;
//
//	KdPrint(("Bus\tDevice\tFunc\tVendor\tDevice\tBaseCls\tSubCls\tIRQ\tPIN\n"));
//
//	for (bus = 0; bus <= PDI_BUS_MAX; ++bus)
//	{
//		for (dev = 0; dev <= PDI_DEVICE_MAX; ++dev)
//		{
//			for (func = 0; func <= PDI_FUNCTION_MAX; ++func)
//			{
//				SlotNumber.u.AsULONG = 0;
//				SlotNumber.u.bits.DeviceNumber = dev;
//				SlotNumber.u.bits.FunctionNumber = func;
//
//				RtlZeroMemory(&PciConfig,
//					sizeof(PCI_COMMON_CONFIG));
//				ULONG Size = HalGetBusData(PCIConfiguration,
//					bus,
//					SlotNumber.u.AsULONG,
//					&PciConfig,
//					PCI_COMMON_HDR_LENGTH);
//				if (Size == PCI_COMMON_HDR_LENGTH)
//				{
//					KdPrint(("%02X\t%02X\t%x\t%x\t%x\t%02X\t%02X\t%d\t%d\n",
//						bus,
//						dev,
//						func,
//						PciConfig.VendorID,
//						PciConfig.DeviceID,
//						PciConfig.BaseClass,
//						PciConfig.SubClass,
//						PciConfig.u.type0.InterruptLine,
//						PciConfig.u.type0.InterruptPin));
//				}
//
//			}
//		}
//	}
//
//}
void Out_32(USHORT port, ULONG value)
{ 
	UCHAR method = 4; 
	//KdPrint(("port:%x\n", port));
	//KdPrint(("method:%x\n", method));
	//KdPrint(("value:%x\n", value));
	if (method == 1)//8位操作
	{
		WRITE_PORT_UCHAR((PUCHAR)port, (UCHAR)value);
	}
	else if (method == 2)//16位操作
	{
		WRITE_PORT_USHORT((PUSHORT)port, (USHORT)value);
	}
	else if (method == 4)//32位操作
	{
		WRITE_PORT_ULONG((PULONG)port, (ULONG)value);
	}
}
DWORD In_32(USHORT port)
{ 
	UCHAR method = 4;
	//KdPrint(("port:%x\n", port));
	//KdPrint(("method:%x\n", method));
	if (method == 1)//8位操作
	{
		return READ_PORT_UCHAR((PUCHAR)port);
	}
	else if (method == 2)//16位操作
	{
		return READ_PORT_USHORT((PUSHORT)port);
	}
	else if (method == 4)//32位操作
	{
		return  READ_PORT_ULONG((PULONG)port);
	} 
	return 0;

}
void DisplayPCIConfiguation(int bus, int dev, int func)
{
	DWORD	dwAddr;
	DWORD	dwData;

	MYPCI_COMMON_CONFIG pci_config;
	MYPCI_SLOT_NUMBER SlotNumber;

	SlotNumber.u.AsULONG = 0;
	SlotNumber.u.bits.DeviceNumber = dev;
	SlotNumber.u.bits.FunctionNumber = func;

	dwAddr = 0x80000000 | (bus << 16) | (SlotNumber.u.AsULONG << 8);

	/* 256字节的PCI配置空间 */
	for (int i = 0; i < 0x100; i += 4)
	{
		/* Read */
		Out_32(PCI_CONFIG_ADDRESS, dwAddr | i);
		dwData = In_32(PCI_CONFIG_DATA);
		memcpy(((PUCHAR)&pci_config) + i, &dwData, 4);
	}
//bus:2 dev : 1 func : 0
//	VendorID : 15ad
//	DeviceID : 1977
//	Command : 6
//	Status : 10
//	RevisionID : 9
//	ProgIf : 0
//	SubClass : 3
//	BaseClass : 4
//	CacheLineSize : 40
//	LatencyTimer : 0
//	HeaderType : 0
//	BIST : 0
//	BaseAddresses[0] : 0XFC000004
//	BaseAddresses[1] : 0X00000000
//	BaseAddresses[2] : 0X00000000
//	BaseAddresses[3] : 0X00000000
//	BaseAddresses[4] : 0X00000000
//	BaseAddresses[5] : 0X00000000
//	InterruptLine : 19
//	InterruptPin : 1

	KdPrint(("bus:%d\tdev:%d\tfunc:%d\n", bus, dev, func));

	KdPrint(("VendorID:%x\n", pci_config.VendorID));
	KdPrint(("DeviceID:%x\n", pci_config.DeviceID));
	KdPrint(("Command:%x\n", pci_config.Command));
	KdPrint(("Status:%x\n", pci_config.Status));
	KdPrint(("RevisionID:%x\n", pci_config.RevisionID));
	KdPrint(("ProgIf:%x\n", pci_config.ProgIf));
	KdPrint(("SubClass:%x\n", pci_config.SubClass));
	KdPrint(("BaseClass:%x\n", pci_config.BaseClass));
	KdPrint(("CacheLineSize:%x\n", pci_config.CacheLineSize));
	KdPrint(("LatencyTimer:%x\n", pci_config.LatencyTimer));
	KdPrint(("HeaderType:%x\n", pci_config.HeaderType));
	KdPrint(("BIST:%x\n", pci_config.BIST));
	for (int i = 0; i < 6; i++)
	{
		KdPrint(("BaseAddresses[%d]:0X%08X\n", i, pci_config.u.type0.BaseAddresses[i]));
	}
	KdPrint(("InterruptLine:%d\n", pci_config.u.type0.InterruptLine));
	KdPrint(("InterruptPin:%d\n", pci_config.u.type0.InterruptPin));
}

VOID EnumeratePCI() {
	DisplayPCIConfiguation( 2, 1, 0);
}

Driver.h

#include <ntifs.h>
#include <NTDDK.h>
#include <string.h>
#include <ntstrsafe.h>
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
#define PDI_BUS_MAX     0xFF
#define PDI_DEVICE_MAX     0x1F
#define PDI_FUNCTION_MAX     0x7 
#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")
#define arraysize(p) (sizeof(p)/sizeof((p)[0]))

typedef struct _DEVICE_EXTENSION {
	PDEVICE_OBJECT pDevice;
	UNICODE_STRING ustrDeviceName;	//设备名称
	UNICODE_STRING ustrSymLinkName;	//符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef struct MyStruct
{
	//Intel
	BOOLEAN bIntelCPU;
	//AMD
	BOOLEAN bAMDCPU;
}stRet;
INT signature_;  // raw form of type, family, model, and stepping
INT type_;  // process type
INT family_;  // family of the processor
INT model_;  // model of processor
INT stepping_;  // processor revision number
INT ext_model_;
INT ext_family_;
BOOLEAN has_mmx_;
BOOLEAN has_sse_;
BOOLEAN has_sse2_;
BOOLEAN has_sse3_;
BOOLEAN has_ssse3_;
BOOLEAN has_sse41_;
BOOLEAN has_sse42_;
BOOLEAN has_avx_;
BOOLEAN has_avx2_;
BOOLEAN has_aesni_;
BOOLEAN has_non_stop_time_stamp_counter_;
ULONG CPUInfo[4] = { -1 };
// 函数声明
stRet CPUType();
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject);
VOID DDKUnload(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS DDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,
	IN PIRP pIrp);
//	字符串长度
DWORD lstrlen(PCHAR pSrc);
//	字符拷贝
VOID lstrcpy(PCHAR pDst, PCHAR pSrc, DWORD len);

//////////////////////////////////////////////////////////////
/* PCI配置空间寄存器 */
#define PCI_CONFIG_ADDRESS      0xCF8
#define PCI_CONFIG_DATA         0xCFC


#define PCI_TYPE0_ADDRESSES             6
#define PCI_TYPE1_ADDRESSES             2
#define PCI_TYPE2_ADDRESSES             5

typedef struct _MYPCI_COMMON_CONFIG {
	USHORT  VendorID;                   // (ro)
	USHORT  DeviceID;                   // (ro)
	USHORT  Command;                    // Device control
	USHORT  Status;
	UCHAR   RevisionID;                 // (ro)
	UCHAR   ProgIf;                     // (ro)
	UCHAR   SubClass;                   // (ro)
	UCHAR   BaseClass;                  // (ro)
	UCHAR   CacheLineSize;              // (ro+)
	UCHAR   LatencyTimer;               // (ro+)
	UCHAR   HeaderType;                 // (ro)
	UCHAR   BIST;                       // Built in self test

	union {
		struct _MYPCI_HEADER_TYPE_0 {
			ULONG   BaseAddresses[PCI_TYPE0_ADDRESSES];
			ULONG   CIS;
			USHORT  SubVendorID;
			USHORT  SubSystemID;
			ULONG   ROMBaseAddress;
			UCHAR   CapabilitiesPtr;
			UCHAR   Reserved1[3];
			ULONG   Reserved2;
			UCHAR   InterruptLine;      //
			UCHAR   InterruptPin;       // (ro)
			UCHAR   MinimumGrant;       // (ro)
			UCHAR   MaximumLatency;     // (ro)
		} type0;

		// end_wdm end_ntminiport end_ntndis

		//
		// PCI to PCI Bridge
		//

		struct _MYPCI_HEADER_TYPE_1 {
			ULONG   BaseAddresses[PCI_TYPE1_ADDRESSES];
			UCHAR   PrimaryBus;
			UCHAR   SecondaryBus;
			UCHAR   SubordinateBus;
			UCHAR   SecondaryLatency;
			UCHAR   IOBase;
			UCHAR   IOLimit;
			USHORT  SecondaryStatus;
			USHORT  MemoryBase;
			USHORT  MemoryLimit;
			USHORT  PrefetchBase;
			USHORT  PrefetchLimit;
			ULONG   PrefetchBaseUpper32;
			ULONG   PrefetchLimitUpper32;
			USHORT  IOBaseUpper16;
			USHORT  IOLimitUpper16;
			UCHAR   CapabilitiesPtr;
			UCHAR   Reserved1[3];
			ULONG   ROMBaseAddress;
			UCHAR   InterruptLine;
			UCHAR   InterruptPin;
			USHORT  BridgeControl;
		} type1;

		//
		// PCI to CARDBUS Bridge
		//

		struct _MYPCI_HEADER_TYPE_2 {
			ULONG   SocketRegistersBaseAddress;
			UCHAR   CapabilitiesPtr;
			UCHAR   Reserved;
			USHORT  SecondaryStatus;
			UCHAR   PrimaryBus;
			UCHAR   SecondaryBus;
			UCHAR   SubordinateBus;
			UCHAR   SecondaryLatency;
			struct {
				ULONG   Base;
				ULONG   Limit;
			}       Range[PCI_TYPE2_ADDRESSES - 1];
			UCHAR   InterruptLine;
			UCHAR   InterruptPin;
			USHORT  BridgeControl;
		} type2;

		// begin_wdm begin_ntminiport begin_ntndis

	} u;

	UCHAR   DeviceSpecific[192];

} MYPCI_COMMON_CONFIG, *MYPPCI_COMMON_CONFIG;

typedef struct _MYPCI_SLOT_NUMBER {
	union {
		struct {
			ULONG   FunctionNumber : 3;
			ULONG   DeviceNumber : 5;
			ULONG   Reserved : 24;
		} bits;
		ULONG   AsULONG;
	} u;
} MYPCI_SLOT_NUMBER, *MYPPCI_SLOT_NUMBER;
VOID EnumeratePCI();

对比书中的源码: