www.pudn.com > PCIConf.rar > Control.cpp


// Control.cpp -- IOCTL handlers for PCIConf driver 
// Copyright (C) 1999 by Walter Oney 
// All rights reserved 
 
#include "stddcls.h" 
#include "driver.h" 
#include "ioctls.h" 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
NTSTATUS DispatchControl(PDEVICE_OBJECT fdo, PIRP Irp) 
	{							// DispatchControl 
	PAGED_CODE(); 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
 
	NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); 
	if (!NT_SUCCESS(status)) 
		return CompleteRequest(Irp, status, 0); 
	ULONG info = 0; 
 
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); 
	ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength; 
	ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength; 
	ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; 
 
	switch (code) 
		{						// process request 
 
	case IOCTL_GET_PCI_BUF:				// code == 0x800 
		{						// IOCTL_GET_VERSION_BUFFERED 
			PULONG pData = (PULONG) Irp->AssociatedIrp.SystemBuffer; 
			 
			unsigned long iobase, ioa0, iod; 
			int bus, device, offset; 
			bus=*pData; 
			device=*(pData+1); 
			iobase = 0x80000000 + bus * 0x10000+ (device * 8 ) * 0x100; 
			ioa0 = iobase + 0; 
			WRITE_PORT_ULONG((PULONG)0xcf8, ioa0); 
			iod = READ_PORT_ULONG((PULONG)0xcfc); 
			if(iod != 0xffffffff) 
			{ 
				for(offset=0; offset<16; offset++) 
				{ 
					ioa0 = iobase + offset*4; 
					WRITE_PORT_ULONG((PULONG)0xcf8, ioa0); 
					iod = READ_PORT_ULONG((PULONG)0xcfc); 
					*(pData+offset)=iod; 
				} 
				info=offset*4; 
			} 
			else 
			{ 
				*pData=0xffffffff; 
				info=4; 
			} 
			break; 
		}						// IOCTL_GET_VERSION_BUFFERED 
 
	case IOCTL_GET_PCI_INFO:				// code == 0x801 
		{						// IOCTL_GET_PCI_INFO CTL_CODE 
			unsigned long iobase, ioa0, iod; 
			int bus, device, offset; 
			 
			KdPrint(("--- Now in IOCTL_GET_PORT section! ---")); 
			for(bus=0; bus<5; bus++) 
			{ 
				for(device=0; device<32; device++) 
				{ 
					iobase = 0x80000000 + bus * 0x10000+ (device * 8 ) * 0x100; 
					ioa0 = iobase + 0; 
					WRITE_PORT_ULONG((PULONG)0xcf8, ioa0); 
					iod = READ_PORT_ULONG((PULONG)0xcfc); 
					if(iod != 0xffffffff) 
					{ 
						KdPrint(("        ")); 
						KdPrint(("------------------------")); 
						KdPrint(("Bus = %x\tDevice = %x", bus, device)); 
						KdPrint(("ID# = %lx ", iod)); 
						for(offset=0; offset<16; offset++) 
						{ 
							ioa0 = iobase + offset*4; 
							WRITE_PORT_ULONG((PULONG)0xcf8, ioa0); 
							iod = READ_PORT_ULONG((PULONG)0xcfc); 
							KdPrint(("%x : %8lx", offset, iod)); 
						} 
					} 
				} 
			} 
			break; 
		}						// IOCTL_GET_PCI_INFO CTL_CODE 
 
	case IOCTL_GET_VERSION_BUFFERED:				// code == 0x802 
		{						// IOCTL_GET_PCI_BUF 
			if (cbout < sizeof(ULONG)) 
			{					// not enough output data 
				status = STATUS_INVALID_BUFFER_SIZE; 
				break; 
			}					// not enough output data 
			 
			PULONG pversion = (PULONG) Irp->AssociatedIrp.SystemBuffer; 
			info = sizeof(ULONG); 
			*pversion = 0x04000A; 
			break; 
		}						// IOCTL_GET_PCI_BUF 
 
	default: 
		status = STATUS_INVALID_DEVICE_REQUEST; 
		break; 
 
		}						// process request 
 
	IoReleaseRemoveLock(&pdx->RemoveLock, Irp); 
	return CompleteRequest(Irp, status, info); 
	}							// DispatchControl