⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enumdev.cpp

📁 枚举机器上所有Pci设备的驱动源码
💻 CPP
字号:
// enumdev.cpp -  PCI enumerator device class 
//=============================================================================
//
// Compuware Corporation
// NuMega Lab
// 9 Townsend West
// Nashua, NH 03060  USA
//
// Copyright (c) 1998 Compuware Corporation. All Rights Reserved.
// Unpublished - rights reserved under the Copyright laws of the
// United States.
//
//=============================================================================

#include <vdw.h>
#include "enumdev.h"

////////////////////////////////////////////////////////////////////
VOID Verify(KPciConfiguration& cfg, PVOID cfghead); // forward

////////////////////////////////////////////////////////////////////
// Begin INIT section code
//
#pragma code_seg("INIT")

////////////////////////////////////////////////////////////////////
// Constructor
//
PciEnumDevice::PciEnumDevice() :
	KDevice(L"PCIENUM", FILE_DEVICE_UNKNOWN, L"PCIENUM"),
	m_slot(0,0,0),
	m_busy(FALSE)
{
	if ( ! NT_SUCCESS(m_ConstructorStatus) )
	{
#if DBG
		DbgPrint("PCIENUM: Failed to create device: %x\n", m_ConstructorStatus);
		return;
#endif
	}
}
#pragma code_seg()
//
// End INIT section code
////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////
// Create 
//
NTSTATUS PciEnumDevice::Create(KIrp I)
{
	I.Information() = 0;

// Allow only one file object

	if ( InterlockedExchange(&m_busy, TRUE) )
		return I.Complete(STATUS_DEVICE_BUSY);

	else
	{
		m_slot.Initialize();
		return I.Complete(STATUS_SUCCESS);
	}
}

////////////////////////////////////////////////////////////////////
// Close
//
NTSTATUS PciEnumDevice::Close(KIrp I)
{
	m_busy = FALSE;
	return DefaultDispatch(I);
}

////////////////////////////////////////////////////////////////////
// Read
//
// This is called when the enumeration app invokes ReadFile. It
// just enumerates the next device and returns the header.
//
NTSTATUS PciEnumDevice::Read(KIrp I)
{
	USHORT VendorId;
	USHORT DeviceId;

	if ( ! KPciConfiguration::Enumerate(m_slot, &VendorId, &DeviceId) )
	{
		I.Information() = 0;
		return I.Complete(STATUS_END_OF_FILE);
	}
	else
	{
		KPciConfiguration cfg(m_slot.Bus(), m_slot.Device(), m_slot.Function());
		cfg.ReadHeader(I.IoctlBuffer());

		Verify(cfg, I.IoctlBuffer());

		I.Information() = sizeof(PCI_CONFIG_HEADER_0);
		return I.Complete(STATUS_SUCCESS);
	}
}

////////////////////////////////////////////////////////////////////
// Verify
// 
// This is a diagnostic for class KPciConfiguration.
// 
VOID Verify(KPciConfiguration& cfg, PVOID cfghead)
{
	UCHAR tempchar;
	USHORT tempshort;
	ULONG templong;

	PCI_CONFIG_HEADER_0* pCfg = (PCI_CONFIG_HEADER_0*)cfghead;

#define CheckCharField(field) \
	cfg.ReadHeader(&tempchar, HeaderOffset(field), sizeof(UCHAR)); \
	if (tempchar != pCfg->field) DbgPrint("ERROR in field "#field"\n")
#define CheckShortField(field) \
	cfg.ReadHeader(&tempshort, HeaderOffset(field), sizeof(USHORT)); \
	if (tempshort != pCfg->field) DbgPrint("ERROR in field "#field"\n")
#define CheckLongField(field) \
	cfg.ReadHeader(&templong, HeaderOffset(field), sizeof(ULONG)); \
	if (templong != pCfg->field) DbgPrint("ERROR in field " #field "\n")

    CheckShortField( VendorID);
    CheckShortField( DeviceID);
    CheckShortField( Command); 
    CheckShortField( Status);
    CheckCharField(  RevisionID);
    CheckCharField(  ProgIf); 
    CheckCharField(  SubClass); 
    CheckCharField(  BaseClass); 
    CheckCharField(  CacheLineSize);
    CheckCharField(  LatencyTimer); 
    CheckCharField(  HeaderType); 
    CheckCharField(  BIST); 
    CheckLongField(  BaseAddresses[0]);
    CheckLongField(  BaseAddresses[1]);
    CheckLongField(  BaseAddresses[2]);
    CheckLongField(  BaseAddresses[3]);
    CheckLongField(  BaseAddresses[4]);
    CheckLongField(  BaseAddresses[5]);
	CheckLongField(CardBusCISPtr);
    CheckShortField(SubsystemVendorID);
	CheckShortField(SubsystemID);
	CheckLongField(ROMBaseAddress);
    CheckCharField(  InterruptLine); 
    CheckCharField(  InterruptPin); 
    CheckCharField(  MinimumGrant); 
    CheckCharField(  MaximumLatency);

	if (pCfg->Command != cfg.ReadCommandRegister())
		DbgPrint("Error in ReadCommandRegister\n");


	if (pCfg->Status != cfg.ReadStatusRegister(0))
		DbgPrint("Error in ReadStatusRegister\n");

	for (int i=0; i < 6; i++)
	{
		if (cfg.ReadBaseAddress(i) != pCfg->BaseAddresses[i])
			DbgPrint("Error at base address %d\n", i);
	}
	
	if (pCfg->InterruptLine != cfg.ReadInterrupt())
		DbgPrint("Error in ReadInterrupt\n");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -