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

📄 pciop.c

📁 windows下hardware访问驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

 Copyright (c) 1990-98  Microsoft Corporation All Rights Reserved

 Module Name:

 sioctl.c

 Abstract:

 Purpose of this driver is to demonstrate how the four different types
 of IOCTLs can be used, and how the I/O manager handles the user I/O
 buffers in each case. This sample also helps to understand the usage of
 some of the memory manager functions.

 Author:

 Eliyas Yakub - July 1997.

 Environment:

 Kernel mode only.

 Notes:

 Revision History:

 --*/

//
// Include files.
//

#include <ntddk.h>          // various NT definitions
#include <string.h>

#include "pciop.h"

#define NT_DEVICE_NAME      L"\\Device\\PCIOP"
#define DOS_DEVICE_NAME     L"\\DosDevices\\PCIOP"

#if DBG
#define SIOCTL_KDPRINT(_x_) \
	DbgPrint("PCIOP.SYS: ");\
	DbgPrint _x_;

#else
#define SIOCTL_KDPRINT(_x_)
#endif

//
// Device driver routine declarations.
//

NTSTATUS
DriverEntry(
		IN OUT PDRIVER_OBJECT DriverObject,
		IN PUNICODE_STRING RegistryPath
);

NTSTATUS
PciopCreateClose(
		IN PDEVICE_OBJECT DeviceObject,
		IN PIRP Irp
);

NTSTATUS
PciopDeviceControl(
		IN PDEVICE_OBJECT DeviceObject,
		IN PIRP Irp
);

VOID
PciopUnloadDriver(
		IN PDRIVER_OBJECT DriverObject
);

VOID
PrintIrpInfo(PIRP Irp);

VOID
PrintHex(
		IN PCHAR BufferAddress,
		IN ULONG CountChars
);

BOOLEAN
PciopScanIteratePCI
( 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 );

BOOLEAN PciopScanAllPCI(ULONG* pcidevices_found);

NTSTATUS
FindPciDevice(
		IN USHORT VendorId,
		IN USHORT DeviceId
);

ULONG
IOReadWrite(
		IN   PCHAR inBuf,
		OUT  PCHAR outBuf
);


#ifdef ALLOC_PRAGMA
#pragma alloc_text( INIT, DriverEntry )
#pragma alloc_text( PAGE, PciopCreateClose)
#pragma alloc_text( PAGE, PciopDeviceControl)
#pragma alloc_text( PAGE, PciopUnloadDriver)
#pragma alloc_text( PAGE, PrintIrpInfo)
#pragma alloc_text( PAGE, PrintHex)
#pragma alloc_text( PAGE, PciopScanIteratePCI)
#pragma alloc_text( PAGE, PciopScanAllPCI)
#pragma alloc_text( PAGE, FindPciDevice)
#pragma alloc_text( PAGE, IOReadWrite)

#endif // ALLOC_PRAGMA

NTSTATUS
DriverEntry(
		IN OUT PDRIVER_OBJECT DriverObject,
		IN PUNICODE_STRING RegistryPath
)
/*++

 Routine Description:
 This routine is called by the Operating System to initialize the driver.

 It creates the device object, fills in the dispatch entry points and
 completes the initialization.

 Arguments:
 DriverObject - a pointer to the object that represents this device
 driver.

 RegistryPath - a pointer to our Services key in the registry.

 Return Value:
 STATUS_SUCCESS if initialized; an error otherwise.

 --*/

{
	NTSTATUS ntStatus;
	UNICODE_STRING ntUnicodeString; // NT Device Name "\Device\SIOCTL"
	UNICODE_STRING ntWin32NameString; // Win32 Name "\DosDevices\IoctlTest"
	PDEVICE_OBJECT deviceObject = NULL; // ptr to device object


	RtlInitUnicodeString( &ntUnicodeString, NT_DEVICE_NAME );

	ntStatus = IoCreateDevice(
			DriverObject, // Our Driver Object
			0, // We don't use a device extension
			&ntUnicodeString, // Device name "\Device\SIOCTL"
			FILE_DEVICE_UNKNOWN, // Device type
			FILE_DEVICE_SECURE_OPEN, // Device characteristics
			FALSE, // Not an exclusive device
			&deviceObject ); // Returned ptr to Device Object

	if ( !NT_SUCCESS( ntStatus ) )
	{
		SIOCTL_KDPRINT(("Couldn't create the device object\n"));
		return ntStatus;
	}

	//
	// Initialize the driver object with this driver's entry points.
	//

	DriverObject->MajorFunction[IRP_MJ_CREATE] = PciopCreateClose;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = PciopCreateClose;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PciopDeviceControl;
	DriverObject->DriverUnload = PciopUnloadDriver;

	//
	// Initialize a Unicode String containing the Win32 name
	// for our device.
	//

	RtlInitUnicodeString( &ntWin32NameString, DOS_DEVICE_NAME );

	//
	// Create a symbolic link between our device name  and the Win32 name
	//

	ntStatus = IoCreateSymbolicLink(
			&ntWin32NameString, &ntUnicodeString );

	if ( !NT_SUCCESS( ntStatus ) )
	{
		//
		// Delete everything that this routine has allocated.
		//
		SIOCTL_KDPRINT(("Couldn't create symbolic link\n"));
		IoDeleteDevice( deviceObject );
	}

	return ntStatus;
}

NTSTATUS
PciopCreateClose(
		IN PDEVICE_OBJECT DeviceObject,
		IN PIRP Irp
)
/*++

 Routine Description:

 This routine is called by the I/O system when the SIOCTL is opened or
 closed.

 No action is performed other than completing the request successfully.

 Arguments:

 DeviceObject - a pointer to the object that represents the device
 that I/O is to be done on.

 Irp - a pointer to the I/O Request Packet for this request.

 Return Value:

 NT status code

 --*/

{
	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;

	IoCompleteRequest( Irp, IO_NO_INCREMENT );

	return STATUS_SUCCESS;
}

VOID
PciopUnloadDriver(
		IN PDRIVER_OBJECT DriverObject
)
/*++

 Routine Description:

 This routine is called by the I/O system to unload the driver.

 Any resources previously allocated must be freed.

 Arguments:

 DriverObject - a pointer to the object that represents our driver.

 Return Value:

 None
 --*/

{
	PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
	UNICODE_STRING uniWin32NameString;

	//
	// Create counted string version of our Win32 device name.
	//

	RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME );

	//
	// Delete the link from our device name to a name in the Win32 namespace.
	//

	IoDeleteSymbolicLink( &uniWin32NameString );

	if ( deviceObject != NULL )
	{
		IoDeleteDevice( deviceObject );
	}

}

NTSTATUS
PciopDeviceControl(
		IN PDEVICE_OBJECT DeviceObject,
		IN PIRP Irp
)

/*++

 Routine Description:

 This routine is called by the I/O system to perform a device I/O
 control function.

 Arguments:

 DeviceObject - a pointer to the object that represents the device
 that I/O is to be done on.

 Irp - a pointer to the I/O Request Packet for this request.

 Return Value:

 NT status code

 --*/

{
	PIO_STACK_LOCATION irpSp;// Pointer to current stack location
	NTSTATUS ntStatus = STATUS_SUCCESS;// Assume success
	ULONG inBufLength; // Input buffer length
	ULONG outBufLength; // Output buffer length
	PCHAR inBuf, outBuf; // pointer to Input and output buffer
	PCHAR data = "This String is from Device Driver !!!";
	ULONG datalen = strlen(data)+1;//Length of data including null
	PMDL mdl = NULL;
	PCHAR buffer = NULL;

	PCI_SLOT_NUMBER pci_slot_number;
	unsigned int dev_number;
	PCI_COMMON_CONFIG pci_cm_conf;
	ULONG pcidev_found = 0;
	BOOLEAN ret_pci_found;

	PPCIDEVQUERY pPciQuery;
	PPCIQUERYRESULT pPciResult;

	PMEMORYRP pMemRead;
	PHYSICAL_ADDRESS physicalAddress;
	PVOID 			 lineAddress;

	ULONG ioRwRet = 0;
	ULONG count = 0;


	irpSp = IoGetCurrentIrpStackLocation( Irp );
	inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
	outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;

	//
	// Determine which I/O control code was specified.
	//

	switch ( irpSp->Parameters.DeviceIoControl.IoControlCode )
	{
	case IOCTL_PORT_READ_WRITE:
		if(inBufLength != sizeof(IOPORTRWP))
		{
			ntStatus = STATUS_INVALID_PARAMETER;
			break;
		}
		inBuf = Irp->AssociatedIrp.SystemBuffer;
		outBuf = Irp->AssociatedIrp.SystemBuffer;
		ioRwRet = IOReadWrite(inBuf, outBuf);
		if(ioRwRet == 0)
		{
			ntStatus = STATUS_INVALID_PARAMETER;
		}
		else
		{
			Irp->IoStatus.Information = ioRwRet;
		}
		break;

	case IOCTL_MEMORY_READ_WRITE:

		KdPrint (("Try read/write memory data here....\n"));
		if(inBufLength != sizeof(MEMORYRP))
		{
			KdPrint (("Error parameter %x....\n", inBufLength));
			ntStatus = STATUS_INVALID_PARAMETER;
			break;
		}
		inBuf = Irp->AssociatedIrp.SystemBuffer;
		//Callers of MmMapIoSpace must be running at IRQL <= DISPATCH_LEVEL
		pMemRead = (PMEMORYRP)inBuf;

		physicalAddress.HighPart = 0;
		physicalAddress.LowPart = pMemRead->memoryAddress;
		lineAddress = MmMapIoSpace(physicalAddress, pMemRead->rSize, MmNonCached);

        KdPrint (("Get line address 0x%x:\n", lineAddress));

		//
        // To access the output buffer, just get the system address
        // for the buffer. For this method,
        //this buffer is intended for transfering data
        // from the driver to the application when read memory.
        //
        //this buffer is intended for transfering data
        // from the appliction to driver when read memory.

        buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);

        if(!buffer) {
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
            break;
        }

        if(pMemRead->isRead)
        {
        	//
        	// Write data to be sent to the user in this buffer
        	//
        	READ_REGISTER_BUFFER_UCHAR(lineAddress, buffer,pMemRead->rSize);

        	for(count=0; count< pMemRead->rSize/32; count++)
        	{
        		PrintHex(buffer+32*count, 32);
        	}
        	if(pMemRead->rSize %32)
        	{
        	    PrintHex(buffer+32*count, pMemRead->rSize);
        	}
        }
        else
        {
        	//
        	//Write data to the memory lineAddress
        	//

        	for(count=0; count< pMemRead->rSize/32; count++)
        	{
        	    PrintHex(buffer+32*count, 32);
        	}
        	if(pMemRead->rSize %32)
        	{
        	    PrintHex(buffer+32*count, pMemRead->rSize);
        	}
        	WRITE_REGISTER_BUFFER_UCHAR(lineAddress, buffer,pMemRead->rSize);
        }

        Irp->IoStatus.Information = pMemRead->rSize;
		break;

	case IOCTL_MEMORY_WRITE:

		break;
	case IOCTL_PCIOP_BUFFERED_TEST:
		inBuf = Irp->AssociatedIrp.SystemBuffer;
		outBuf = Irp->AssociatedIrp.SystemBuffer;

		memcpy(outBuf, data, strlen(data)+1);
		KdPrint (("outBuf is %s\n", outBuf));
		Irp->IoStatus.Information = (outBufLength<datalen?outBufLength:datalen);
		break;
	case IOCTL_PCIOP_GET_PCIDEVICE:
		//
		// Input buffer and output buffer is same in this case, read the
		// content of the buffer before writing to it
		//
		if(inBufLength != sizeof(PCIDEVQUERY) || outBufLength != sizeof(PCIQUERYRESULT))
		{
			ntStatus = STATUS_INVALID_PARAMETER;
			break;
		}
		inBuf = Irp->AssociatedIrp.SystemBuffer;
		outBuf = Irp->AssociatedIrp.SystemBuffer;

		pPciQuery = (PPCIDEVQUERY)inBuf;
		pPciResult = (PPCIQUERYRESULT)outBuf;

⌨️ 快捷键说明

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