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

📄 usblptpd11.c

📁 usb driver, sample for usb driver develop. rised for reference
💻 C
📖 第 1 页 / 共 2 页
字号:

/*  Win NT/2000/XP Driver for DeVaSys USBLPT-PD11(D) USB Development Board	*/
/*  Copyright 2001 Craig Peacock, Craig.Peacock@beyondlogic.org				*/
/*  27th October 2001			                     						*/

#include <ntddk.h>
#include <ddk/parallel.h>
#include "USBLPT_IOCTL.h"

#define NT_DEVICE_NAME		L"\\Device\\USBLPTPD11_"
#define	WIN32_DEVICE_NAME	L"\\DosDevices\\USBLPTPD11_"
#define PAR_PORT_NAME		L"\\Device\\ParallelPort"

#define I2C_CTL_READ		0x01
#define I2C_CTL_WRITE		0xFE
#define I2C_TRUE			1
#define I2C_FALSE			0

#define XD0			0x01
#define XD1			0x02
#define XD6			0x40
#define XD7			0x80

#define XERROR		0x08
#define XBUSY		0x80
#define XACK		0x40
#define XPAPEREND	0x20
#define XSELECT		0x10

#define outportb(ADDR,BYTE) outp(ADDR,BYTE)
#define inportb(ADDR)		inp(ADDR)

#define SetSCL(PortAddress)			outportb(PortAddress, inportb(PortAddress) & ~XD0)
#define ClearSCL(PortAddress)		outportb(PortAddress, inportb(PortAddress) |  XD0)

#define ClearStatus(PortAddress)	outportb(PortAddress, inportb(PortAddress) & ~XD6)
#define SetStatus(PortAddress)		outportb(PortAddress, inportb(PortAddress) |  XD6)

#define SetSDA(PortAddress)			outportb(PortAddress, inportb(PortAddress) & ~XD7)
#define ClearSDA(PortAddres)		outportb(PortAddress, inportb(PortAddress) |  XD7)

#define GetSCL(PortAddress)			((~inportb(PortAddress+1)) & XBUSY) >> 7
#define GetSDA(PortAddress)			((inportb(PortAddress+1) & XPAPEREND) >> 5)

#define GetSuspend(PortAddress)		((inportb(PortAddress+1) & XSELECT) >> 4)
#define GetInt(PortAddress)			((inportb(PortAddress+1) & XACK) >> 6)

#define Stop(PortAddress) 			{ClearSCL(PortAddress);ClearSDA(PortAddress);SetSCL(PortAddress);SetSDA(PortAddress);}

#define SetAck(PortAddress) 	    {ClearSCL(PortAddress);ClearSDA(PortAddress);SetSCL(PortAddress);ClearSCL(PortAddress);SetSDA(PortAddress);}
#define SetNak(PortAddress) 	    {ClearSCL(PortAddress);SetSDA(PortAddress);SetSCL(PortAddress);ClearSCL(PortAddress);}

#define Idle(PortAddress) 			{SetSCL(PortAddress);SetSDA(PortAddress);Stop(PortAddress);}

NTSTATUS USBLPTPD11DeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS USBLPTPD11CreateDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
NTSTATUS USBLPTPD11CloseDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);
NTSTATUS USBLPTPD11CreateDevice(IN PDRIVER_OBJECT pDriverObject, IN ULONG DeviceNumber);

BOOLEAN USBLPTPD11Isr(IN PKINTERRUPT Interrupt, IN OUT PVOID Context);
VOID USBLPTPD11Unload(IN PDRIVER_OBJECT DriverObject);
VOID USBLPTPD11StartIo(PDEVICE_OBJECT DeviceObject, PIRP pIrp);
VOID USBLPTPD11DpcRoutine(IN PKDPC Dpc, PDEVICE_OBJECT deviceObject, IN PIRP Irp, IN PVOID Context);
VOID USBLPTPD11TimeOutDPC(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);

NTSTATUS DetectDevice(LONG wLptBaseAddr);
NTSTATUS I2C_Read(unsigned char * pbyData, unsigned char byDevId, unsigned char byCount, unsigned long PortAddress);
NTSTATUS I2C_Write(unsigned char byDevId, unsigned char * pbyData, unsigned char byCount, unsigned long PortAddress);
NTSTATUS I2C_Init(unsigned long PortAddress);

unsigned char Start(unsigned long PortAddress);
unsigned char ByteOut(unsigned char byData, unsigned long PortAddress);
void ByteIn(unsigned char * pbyData, unsigned long PortAddress);

typedef struct _LOCAL_DEVICE_INFO {
    PDEVICE_OBJECT		deviceObject;
    PDRIVER_OBJECT		DriverObject;
	ULONG				DeviceNumber;
    PKINTERRUPT 		InterruptObject;
	ULONG				PortAddress;
    INTERFACE_TYPE		InterfaceType;
	ULONG				BusNumber;
	KIRQL				Irql;
	ULONG				Level;      
    ULONG				Vector;     
	KINTERRUPT_MODE		InterruptMode;
    KAFFINITY			Affinity;   
    KTIMER  			IntTimer;
    KDPC 				IntTimerDPC;
	LARGE_INTEGER		IntTimer_uS;
	PFILE_OBJECT		ParPortFileObject;
	PDEVICE_OBJECT		ParPortDeviceObject;
} LOCAL_DEVICE_INFO, *PLOCAL_DEVICE_INFO;


NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
	ULONG		DeviceNumber;
	ULONG		NumOfParallelPorts;
	NTSTATUS	status;

    DriverObject->MajorFunction[IRP_MJ_CREATE] = USBLPTPD11CreateDispatch;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBLPTPD11CloseDispatch;
  	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USBLPTPD11DeviceControl;

	DriverObject->DriverUnload  = USBLPTPD11Unload;
  	DriverObject->DriverStartIo = USBLPTPD11StartIo;

	NumOfParallelPorts = IoGetConfigurationInformation()->ParallelCount;
	KdPrint( ("USBLPTPD11: USBLPT-PD11 DriverEntry Loading. System has %d Parallel Ports",NumOfParallelPorts) );

	for( DeviceNumber=0; DeviceNumber<NumOfParallelPorts; DeviceNumber++)
	{
   		status = USBLPTPD11CreateDevice( DriverObject, DeviceNumber);
   		if( !NT_SUCCESS(status))
			return status;
	}



	return STATUS_SUCCESS; 
}

NTSTATUS USBLPTPD11CreateDevice (
	IN PDRIVER_OBJECT DriverObject,
	IN ULONG DeviceNumber
	)
{
	PDEVICE_OBJECT				deviceObject;
	NTSTATUS					status;
   	PLOCAL_DEVICE_INFO			deviceExtension;

	WCHAR						NTDeviceBuffer[44];
	WCHAR						Win32DeviceBuffer[52];
	WCHAR						ParPortDeviceBuffer[46];
	WCHAR						NumberBuffer[6];

	UNICODE_STRING			    uniWin32Device = {0, sizeof(Win32DeviceBuffer)/sizeof(WCHAR), Win32DeviceBuffer};
	UNICODE_STRING				uniParPortDevice = {0, sizeof(ParPortDeviceBuffer)/sizeof(WCHAR), ParPortDeviceBuffer};
	UNICODE_STRING				uniNumber = {0, sizeof(NumberBuffer)/sizeof(WCHAR), NumberBuffer};
	UNICODE_STRING				uniNTDevice = {0, sizeof(NTDeviceBuffer)/sizeof(WCHAR), NTDeviceBuffer};

	KEVENT                      event;
	PIRP                        irp;
	IO_STATUS_BLOCK             ioStatus;
	PARALLEL_PORT_INFORMATION   ParPortInfo;
	MORE_PARALLEL_PORT_INFORMATION MoreParPortInfo;

	RtlIntegerToUnicodeString(DeviceNumber, 10, &uniNumber);
	
	RtlAppendUnicodeToString(&uniNTDevice, NT_DEVICE_NAME);
	RtlAppendUnicodeStringToString(&uniNTDevice, &uniNumber);
		
	RtlAppendUnicodeToString(&uniParPortDevice, PAR_PORT_NAME); 
	RtlAppendUnicodeStringToString(&uniParPortDevice, &uniNumber);
	
	RtlAppendUnicodeToString(&uniWin32Device, WIN32_DEVICE_NAME); 
	RtlAppendUnicodeStringToString(&uniWin32Device, &uniNumber);

	status = IoCreateDevice(DriverObject,				// DriverObject
							sizeof(LOCAL_DEVICE_INFO),	// DeviceExtensionSize
							&uniNTDevice,				// DeviceName
							FILE_DEVICE_PARALLEL_PORT,	// DeviceType
							0,							// DeviceCharacteristics
							TRUE,						// Exclusive
							&deviceObject);				// *DeviceObject

	KdPrint( ("USBLPTPD11: USBLPT-PD11 Create Device %d, DriverObject %X, DeviceObject %X",DeviceNumber,DriverObject,deviceObject) );

	if(!NT_SUCCESS(status)) {
		KdPrint( ("USBLPTPD11: Cannot Create Device - IoCreateDevice Failed NTSTATUS %x\n",status) );
		return status;
	}
	
	deviceExtension = deviceObject->DeviceExtension;
	RtlZeroMemory(deviceExtension, sizeof(PLOCAL_DEVICE_INFO));

	deviceExtension->deviceObject = deviceObject;
	deviceExtension->DeviceNumber = DeviceNumber;

 	status = IoGetDeviceObjectPointer(&uniParPortDevice, 
									  FILE_READ_ATTRIBUTES,
									  &deviceExtension->ParPortFileObject,
									  &deviceExtension->ParPortDeviceObject);

	if (!NT_SUCCESS(status)) {
			KdPrint( ("USBLPTPD11: DriverEntry Cannot Open ParPort, ParallelPort%d\n",DeviceNumber) );
			IoDeleteDevice(DriverObject->DeviceObject);
			return STATUS_SUCCESS;
	}

	ObReferenceObjectByPointer(	deviceExtension->ParPortDeviceObject,FILE_READ_ATTRIBUTES,
								NULL,KernelMode);
	ObDereferenceObject(deviceExtension->ParPortFileObject);
    
    KeInitializeEvent(&event, NotificationEvent, FALSE);

	irp = IoBuildDeviceIoControlRequest(
										IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO,
										deviceExtension->ParPortDeviceObject,
										NULL, 
										0, 
										&ParPortInfo,
										sizeof(PARALLEL_PORT_INFORMATION),
										TRUE, 
										&event, 
										&ioStatus);

	if (!irp) {
		KdPrint( ("USBLPTPD11: GET_PARALLEL_PORT_INFO Insufficent Resources for IoBuildDeviceIoControlRequest\n") );
		IoDeleteDevice(DriverObject->DeviceObject);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	status = IoCallDriver(deviceExtension->ParPortDeviceObject, irp);

	if (!NT_SUCCESS(status)) {
		KdPrint( ("USBLPTPD11: GET_PARALLEL_PORT_INFO Unexpected Failure in IoCallDriver\n") );
		IoDeleteDevice(DriverObject->DeviceObject);
		return status;
	}

	status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

	if (!NT_SUCCESS(status))
	{
		KdPrint( ("USBLPTPD11: GET_PARALLEL_PORT_INFO Unexpected Failure in KeWaitForSingleObject\n") );
		IoDeleteDevice(DriverObject->DeviceObject);
		return status;
	}

	KdPrint( ("USBLPTPD11: Parallel Port at Address 0x%x and spans %d bytes",(ULONG)ParPortInfo.Controller,ParPortInfo.SpanOfController) );

	deviceExtension->PortAddress = (ULONG)ParPortInfo.Controller;
	
	/* Get Interrupt Information */
	KeInitializeEvent(&event, NotificationEvent, FALSE);

	irp = IoBuildDeviceIoControlRequest(
										IOCTL_INTERNAL_GET_MORE_PARALLEL_PORT_INFO,
										deviceExtension->ParPortDeviceObject,
										NULL, 
										0, 
										&MoreParPortInfo,
										sizeof(MORE_PARALLEL_PORT_INFORMATION),
										TRUE, 
										&event, 
										&ioStatus);

	if (!irp) {
		KdPrint( ("USBLPTPD11: GET_MORE_PARALLEL_PORT_INFO Insufficent Resources for IoBuildDeviceIoControlRequest\n") );
		IoDeleteDevice(DriverObject->DeviceObject);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	status = IoCallDriver(deviceExtension->ParPortDeviceObject, irp);

	if (!NT_SUCCESS(status)) {
		KdPrint( ("USBLPTPD11: GET_MORE_PARALLEL_PORT_INFO Unexpected Failure in IoCallDriver\n") );
		IoDeleteDevice(DriverObject->DeviceObject);
		return status;
	}

	status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

	if (!NT_SUCCESS(status)) {
		KdPrint( ("USBLPTPD11: GET_MORE_PARALLEL_PORT_INFO Unexpected Failure in KeWaitForSingleObject\n") );
		IoDeleteDevice(DriverObject->DeviceObject);
		return status;
	}

	KdPrint( ("USBLPTPD11: InterfaceType 0x%08x",MoreParPortInfo.InterfaceType) );
	KdPrint( ("USBLPTPD11: BusNumber 0x%08x",MoreParPortInfo.BusNumber) );
	KdPrint( ("USBLPTPD11: Interrupt Vector 0x%08x",MoreParPortInfo.InterruptVector) );
	KdPrint( ("USBLPTPD11: Interrupt Affinity 0x%08x",MoreParPortInfo.InterruptAffinity ) );
	KdPrint( ("USBLPTPD11: Interrupt Mode 0x%08x",MoreParPortInfo.InterruptMode) );

	deviceExtension->InterfaceType = MoreParPortInfo.InterfaceType;
    deviceExtension->BusNumber = MoreParPortInfo.BusNumber;
	deviceExtension->Irql = 0x14;
	deviceExtension->Vector = MoreParPortInfo.InterruptVector;
	deviceExtension->InterruptMode = MoreParPortInfo.InterruptMode;
	deviceExtension->Affinity = MoreParPortInfo.InterruptAffinity;

	status = IoCreateSymbolicLink (&uniWin32Device, &uniNTDevice);

	if (!NT_SUCCESS(status)) {
		KdPrint( ("USBLPTPD11: Unexpected error while Creating Symbolic Link\n") );
		IoDeleteDevice(DriverObject->DeviceObject);
		return status;
	}
   	return STATUS_SUCCESS;
}


NTSTATUS USBLPTPD11CreateDispatch(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
	PLOCAL_DEVICE_INFO			DeviceExtension = DeviceObject->DeviceExtension;
	ULONG						MappedVector;
	KEVENT                      event;
	PIRP                        irp;
	IO_STATUS_BLOCK             ioStatus;
	NTSTATUS					status;

	KdPrint( ("USBLPTPD11: CreateFile() Call - Acquiring Port%d from ParPort",DeviceExtension->DeviceNumber) );
	
	/* Now that someone has opened a handle to us, Acquire the LPT Port from ParPort.SYS */

	KeInitializeEvent(&event, NotificationEvent, FALSE);

	irp = IoBuildDeviceIoControlRequest(
										IOCTL_INTERNAL_PARALLEL_PORT_ALLOCATE,
										DeviceExtension->ParPortDeviceObject,
										NULL, 
										0, 
										NULL,
										0, 
										TRUE,
										&event, 
										&ioStatus);

	if (!irp) {
		KdPrint( ("USBLPTPD11: PARALLEL_PORT_ALLOCATE Insufficent Resources for IoBuildDeviceIoControlRequest\n") );
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	status = IoCallDriver(DeviceExtension->ParPortDeviceObject, irp);

	if (!NT_SUCCESS(status)) {
		KdPrint( ("USBLPTPD11: PARALLEL_PORT_ALLOCATE Unexpected Failure in IoCallDriver\n") );
		return status;
	}

	status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

	if (!NT_SUCCESS(status)) {
		KdPrint( ("USBLPTPD11: PARALLEL_PORT_ALLOCATE Unexpected Failure in KeWaitForSingleObject\n") );
		return status;
	}

	/* and Setup Interrupts */

	if (DeviceExtension->Vector) {

		IoInitializeDpcRequest(DeviceObject,USBLPTPD11DpcRoutine);
	
  		status = IoConnectInterrupt(&DeviceExtension->InterruptObject,	// InterruptObject
  									USBLPTPD11Isr,						// ServiceRoutine
  									DeviceObject,						// ServiceContext
 									NULL,								// SpinLock
									DeviceExtension->Vector,			// Vector
  									DeviceExtension->Irql,				// Irql
									DeviceExtension->Irql,				// SynchronizeIrql
									DeviceExtension->InterruptMode,		// InterruptMode
  									FALSE,								// ShareVector
									DeviceExtension->Affinity,			// ProcessorEnableMask
									FALSE);								// FloatingSave

		if (!NT_SUCCESS (status)) {
			DbgPrint("USBLPTPD11: IoConnectInterrupt  Failed\n");
			return STATUS_INSUFFICIENT_RESOURCES; /* Can't obtain IRQ */
		}

		/* and Setup Timeout Timer */

		KeInitializeTimer(&DeviceExtension->IntTimer);
	}
	else KdPrint( ("USBLPTPD11: No Interrupts enabled on LPT%d. You may want to enable the use of interrupts in control panel",DeviceExtension->DeviceNumber) );

	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}


NTSTATUS USBLPTPD11CloseDispatch(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
	PLOCAL_DEVICE_INFO			DeviceExtension = DeviceObject->DeviceExtension;
	KEVENT                      event;
	PIRP                        irp;
	IO_STATUS_BLOCK             ioStatus;
	NTSTATUS					status;
	
	KdPrint( ("USBLPTPD11: CloseHandle() Call - Releasing Port from ParPort") );
	
	/* Now that someone has closed the handle free the LPT Port from ParPort.SYS */

	KeInitializeEvent(&event, NotificationEvent, FALSE);

	irp = IoBuildDeviceIoControlRequest(
										IOCTL_INTERNAL_PARALLEL_PORT_FREE,
										DeviceExtension->ParPortDeviceObject,
										NULL, 
										0, 
										NULL,
										0, 
										TRUE,
										&event, 
										&ioStatus);

	if (!irp) {
		KdPrint( ("USBLPTPD11: PARALLEL_PORT_FREE Insufficent Resources for IoBuildDeviceIoControlRequest\n") );
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	status = IoCallDriver(DeviceExtension->ParPortDeviceObject, irp);

	if (!NT_SUCCESS(status)) {
		KdPrint( ("USBLPTPD11: PARALLEL_PORT_FREE Unexpected Failure in IoCallDriver\n") );
		return status;
	}

	status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

	if (!NT_SUCCESS(status)) {
		KdPrint( ("USBLPTPD11: PARALLEL_PORT_FREE Unexpected Failure in KeWaitForSingleObject\n") );
		return status;

⌨️ 快捷键说明

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