📄 pciscan.c
字号:
// pclUtil.c driver utilities for PCI bus adapters
/*****************************************************************************
* Change Log
* Date | Change
*-----------+-----------------------------------------------------------------
09-13-96 create log
*****************************************************************************/
/*****************************************************************************
* To DO
*-----------------------------------------------------------------------------
*****************************************************************************/
#define NT_DEVICE_NAME L"\\Device\\PCISCAN"
#define DOS_DEVICE_NAME L"\\DosDevices\\PCISCAN"
#define BYTE UCHAR
/*++
Module Name:
pclUtil.c
Abstract:
Windows NT device driver utilities for PCI bus adapters.
Author:
Edward Dekker
Environment:
kernel mode only
Notes:
--*/
#include "ntddk.h"
//#include "pciScan.h" // include device extension for target driver here
#include "pciScanIoctl.h" // include device extension for target driver here
typedef struct _PCISCAN_DEVICE_EXTENSION
{
PDEVICE_OBJECT DeviceObject;
PCI_SLOT_NUMBER returnSlotData;
PCI_COMMON_CONFIG returnPciData;
unsigned int returnBusNumber;
} PCISCAN_DEVICE_EXTENSION;
typedef PCISCAN_DEVICE_EXTENSION *PPCISCAN_DEVICE_EXTENSION;
NTSTATUS pciScanOpen(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp );
NTSTATUS pciScanClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp );
VOID pciScanUnload( IN PDRIVER_OBJECT DriverObject);
NTSTATUS pciScanDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp );
void dumpPciConfig( PCI_COMMON_CONFIG pciData)
{
// dump our PCI_COMMON_CONFIG record here
KdPrint( ("pciScan: pciData.VendorID = %x\n", pciData.VendorID ) );
KdPrint( ("pciScan: pciData.DeviceID = %x\n", pciData.DeviceID ) );
KdPrint( ("pciScan: pciData.Command = %x\n", pciData.Command ) );
KdPrint( ("pciScan: pciData.Status = %x\n", pciData.Status ) );
KdPrint( ("pciScan: pciData.RevisionID = %x\n", pciData.RevisionID ) );
KdPrint( ("pciScan: pciData.ProgIf = %x\n", pciData.ProgIf ) );
KdPrint( ("pciScan: pciData.SubClass = %x\n", pciData.SubClass ) );
KdPrint( ("pciScan: pciData.BaseClass = %x\n", pciData.BaseClass ) );
KdPrint( ("pciScan: pciData.CacheLineSize= %x\n", pciData.CacheLineSize ) );
KdPrint( ("pciScan: pciData.LatencyTimer = %x\n", pciData.LatencyTimer ) );
KdPrint( ("pciScan: pciData.HeaderType = %x\n", pciData.HeaderType ) );
KdPrint( ("pciScan: pciData.BIST = %x\n", pciData.BIST ) );
KdPrint( ("pciScan: pciData.u.type0.BaseAddresses[0] = %x\n", pciData.u.type0.BaseAddresses[0] ) );
KdPrint( ("pciScan: pciData.u.type0.BaseAddresses[1] = %x\n", pciData.u.type0.BaseAddresses[1] ) );
KdPrint( ("pciScan: pciData.u.type0.BaseAddresses[2] = %x\n", pciData.u.type0.BaseAddresses[2] ) );
KdPrint( ("pciScan: pciData.u.type0.ROMBaseAddress = %x\n", pciData.u.type0.ROMBaseAddress ) );
KdPrint( ("pciScan: pciData.u.type0.InterruptLine = %x\n", pciData.u.type0.InterruptLine ) );
KdPrint( ("pciScan: pciData.u.type0.InterruptPin = %x\n", pciData.u.type0.InterruptPin ) );
KdPrint( ("pciScan: pciData.u.type0.MinimumGrant = %x\n", pciData.u.type0.MinimumGrant ) );
KdPrint( ("pciScan: pciData.u.type0.MaximumLatency = %x\n", pciData.u.type0.MaximumLatency ) );
}
/****************************************************************************
Function:
DriverEntry
Arguments:
Description:
Returns:
*****************************************************************************/
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath )
{
PDEVICE_OBJECT deviceObject = NULL;
NTSTATUS status;
UNICODE_STRING uniNtNameString;
UNICODE_STRING uniWin32NameString;
PPCISCAN_DEVICE_EXTENSION extension;
BOOLEAN GotResources;
ULONG ret = 0;
KdPrint( ("pciScan: Entered the pciScan driver!\n") );
//
// Create counted string version of our device name.
//
RtlInitUnicodeString( &uniNtNameString, NT_DEVICE_NAME );
//
// Create the device object
//
status = IoCreateDevice(
DriverObject,
sizeof(PCISCAN_DEVICE_EXTENSION),
&uniNtNameString,
FILE_DEVICE_UNKNOWN,
0, // No standard device characteristics
FALSE, // This isn't an exclusive device
&deviceObject
);
if ( NT_SUCCESS(status) )
{
//
// Create dispatch points for create/open, close, unload.
//
KdPrint( ("pciScan: IoCreateDevice success\n") );
DriverObject->MajorFunction[IRP_MJ_CREATE] = pciScanOpen;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = pciScanClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = pciScanDeviceControl;
DriverObject->DriverUnload = pciScanUnload;
KdPrint( ("pciScan: just about ready!\n") );
//
// Do direct I/O. I.e., the I/O system will provide pointers to/from user data
// from/to the user buffer.
//
deviceObject->Flags |= DO_DIRECT_IO;
//
// Create counted string version of our Win32 device name.
//
RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME );
status = IoCreateSymbolicLink( &uniWin32NameString, &uniNtNameString );
if (!NT_SUCCESS(status))
{
KdPrint( ("pciScan: Couldn't create the symbolic link\n") );
IoDeleteDevice( DriverObject->DeviceObject );
}
else
{
KdPrint( ("pciScan: All initialized!\n") );
}
}
else
{
KdPrint( ("pciScan: IoCreateDevice failed\n") );
}
return status;
}
BOOLEAN pciScanIteratePCI( IN BOOLEAN First, IN unsigned int pciVendorId,
IN unsigned int pciDeviceId,
IN OUT PCI_SLOT_NUMBER *returnSlotData,
IN OUT PCI_COMMON_CONFIG *returnPciData,
IN OUT unsigned int *returnBusNumber )
/*++
Routine Description:
This function is called by the driver to find the next PCI card and
initialize the adapter's configuration.
Arguments:
IN BOOLEAN First - TRUE if scan is to start with
first device
FALSE to increment to the next
device
IN unsigned int pciVendorId - Specified vender ID,
or 0xFFFF for all venders
IN unsigned int pciDeviceId - Specified device ID,
or 0xFFFF for all devices
IN OUT PCI_SLOT_NUMBER *returnSlotData - Slotdata for found device
(starting point for
first == FALSE)
IN OUT unsigned int *returnBusNumber - Bus number for found card
Return Value:
ULONG
--*/
{
PCI_SLOT_NUMBER slotData;
PCI_COMMON_CONFIG pciData;
BOOLEAN nextBus = FALSE;
ULONG busNumber = 1;
ULONG bytesReturned;
BOOLEAN firstFunction;
BOOLEAN firstDevice;
KdPrint( ("pciScan: FindPCI \n") );
//
// iterate over all PCI slots
//
firstFunction = First;
firstDevice = First;
slotData.u.AsULONG = 0;
if (!First)
{ /* continuation */
//
// if not the first we want to point after the last device we found
//
returnSlotData->u.bits.FunctionNumber++;
if (PCI_MAX_FUNCTION <= returnSlotData->u.bits.FunctionNumber)
{ /* next device */
returnSlotData->u.bits.FunctionNumber = 0;
returnSlotData->u.bits.DeviceNumber++;
if (PCI_MAX_DEVICES <= returnSlotData->u.bits.DeviceNumber)
{ /* next bus */
returnSlotData->u.bits.DeviceNumber = 0;
*returnBusNumber++;
} /* next bus */
} /* next device */
} /* continuation */
//
// iterate over all PCI busses looking for devices
//
for ( busNumber = First?0:*returnBusNumber;
busNumber < 256;
busNumber++, firstDevice = TRUE)
{ /* busses loop */
unsigned int DeviceNumber;
nextBus = FALSE;
//
// Iterate over all devices
//
for ( DeviceNumber = firstDevice?0:returnSlotData->u.bits.DeviceNumber;
DeviceNumber < PCI_MAX_DEVICES ;
DeviceNumber++, firstFunction = TRUE )
{ /* devices loop */
unsigned int FunctionNumber;
slotData.u.bits.DeviceNumber = DeviceNumber;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -