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

📄 candriver.c

📁 一个关于PCI CAN开发板的windows下的驱动程序,用DDK做的,希望对做PCI CAN板的朋友有用
💻 C
📖 第 1 页 / 共 2 页
字号:
//***************************************************************************************
//*	IOCTRL Sample Driver
//*		Demonstrates communications between USER and KERNEL.	
//*	Aug	2003 - DriverEntry (www.ecict.com)
//***************************************************************************************
//
//* Software is provided "as is", without warranty or guarantee of any kind. The use of 
//* this software is at your own risk. We take no responsibly for any damage that may be 
//* caused through its use. DriverEntry source code may not be used in any product without 
//* written consent. DriverEntry source code or software may not distributed in any form 
//* without written consent. All enquiries should be made to linbirg@ecict.com. 
//*
//*	THE ENTIRE RISK FROM THE USE OF THIS SOFTWARE REMAINS WITH YOU			
//***************************************************************************************

#include <ntddk.h>
#include "Common.h"
#include "PeliCAN.h"
#include "PeliCanDef.h"

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


//	Device Extension
typedef struct _DEVICE_EXTENSION
{
	//
	//	Device information
	//
        PDEVICE_OBJECT			DeviceObject;
        PKINTERRUPT 			InterruptObject;
    	ULONG				Level;      
    	ULONG				Vector;     
    	KAFFINITY			Affinity;
        //PIRQL                 CurrentIrp;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

#define DATA_TO_GUI			"Hello World from DRIVER"
#define MAX_BUF_LEN			20                          // max len of buf

//	Allow the DriverEntry routine to be discarded once initialization is completed
#pragma alloc_text ( INIT, DriverEntry )

//***************************************************************************************
//* NAME:			IoCtrlDeviceControl
//*
//* DESCRIPTION:	This is the dispatch entry point for IRP_MJ_DEVICE_CONTROL.
//*					
//*	PARAMETERS:		DriverObject					IN		Address of our DRIVER_OBJECT.
//*					Irp								IN		Address of the IRP.
//*
//*	IRQL:			IRQL_PASSIVE_LEVEL.
//*
//*	RETURNS:		NTSTATUS
//*
//*	NOTES:			IRP_MJ_DEVICE_CONTROL
//*					Parameters:
//*					Parameters.DeviceIoControl.OutputBufferLength	Length of OutBuffer 
//*					in bytes (length of buffer from GUI)
//*					Parameters.DeviceIoControl.InputBufferLength	Length of InBuffer 
//*					in bytes (length of buffer from DRIVER)
//*					Parameters.DeviceIoControl.ControlCode			I/O control code
//***************************************************************************************
NTSTATUS 
	IoCtrlDeviceControl
	(
		IN		PDEVICE_OBJECT		DeviceObject, 
		IN		PIRP				Irp
	)
{
    PIO_STACK_LOCATION	ioStackLocation 	= IoGetCurrentIrpStackLocation( Irp );
    ULONG				operation			= 0;
    NTSTATUS			status				= STATUS_UNSUCCESSFUL;
	ULONG				inBufLen	= 0;
	ULONG				outBufLen	= 0;
	PCHAR				buffer				= NULL;
	
	CHAR				outBuf[MAX_BUF_LEN] = {'0'};
	UINT32_T LenUINT8, LenUINT32;
	//unsigned int board = 0;
	UINT8_T channel = 0;                       
	//int IDNum = 0;
	int baudrate = 0;
	UINT8_T sja_reg;
	//ULONG k;
	char data;
	
	// return value
	UINT32_T intRet = 0;
	UINT8_T charRet = 0;
	//char acr;
	//char amr;

 	//
	// Get the IoCtrl Code
    operation = ioStackLocation->Parameters.DeviceIoControl.IoControlCode;

	outBufLen	= ioStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
	inBufLen	= ioStackLocation->Parameters.DeviceIoControl.InputBufferLength;

	buffer				= Irp->AssociatedIrp.SystemBuffer;

    //
    // Set the status field to zero for completion
    //
    Irp->IoStatus.Information = 0;
    LenUINT8 =  sizeof(UINT8_T);
	LenUINT32 = sizeof(UINT32_T);

    // mainly do handle the args and call pelican functions
    switch ( operation ) 
	{	
		case IOCTRL_INIT_CAN: 			// int can_init(UINT8_T channel);
			debug_printf("IOCTL_INIT_CAN routine\n");
			
			if( inBufLen<LenUINT8 ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}

     		channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel%d will be inited!\n", channel);
            baudrate = (int)(*(buffer+LenUINT8));
			debug_printf("baudrate%d will be inited!\n", baudrate);
			intRet = can_init(channel,baudrate);
			debug_printf( "can_init: %s\n" ,(intRet == OK)?" OK":" ERROR");
			RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &intRet, LenUINT32);
			Irp->IoStatus.Information = LenUINT32;
			status = STATUS_SUCCESS;
			break;	
			
		case IOCTRL_CAN_TRANS:			// void can_transmit(UINT8_T channel, char *txdata);
			debug_printf("IOCTRL_CAN_TRANS routine\n");
	
			if( inBufLen < (LenUINT8 + CAN_FRAME_LEN) ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}

			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			can_transmit(channel, buffer+1);

			status = STATUS_SUCCESS;
			break;

		case IOCTRL_CAN_REV:  			// int can_receive(UINT8_T channel, char *rxdata);
			debug_printf("IOCTRL_CAN_REV routine\n");

			if(inBufLen < LenUINT8 || outBufLen < CAN_FRAME_LEN){
					status = STATUS_UNSUCCESSFUL;
					break;
			}
			
			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel=%d\n", channel);
			intRet = can_receive(channel, outBuf);
			debug_printf("the result is %d\n", intRet);
			
			RtlCopyMemory(outBuf+CAN_FRAME_LEN, &intRet, LenUINT32);
			RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, outBuf, CAN_FRAME_LEN+LenUINT32);
		
			Irp->IoStatus.Information = LenUINT32 + CAN_FRAME_LEN;
			status = STATUS_SUCCESS;
			break;	

		case IOCTRL_CAN_RST:			// int can_rst(UINT8_T channel);
			debug_printf("IOCTRL_CAN_RST routine\n");

			if(inBufLen < LenUINT8 ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}
			
			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel=%d\n", channel);
			intRet = can_rst(channel);
			debug_printf("the result is %d\n", intRet);
			
			RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &intRet, LenUINT32);
		
			Irp->IoStatus.Information = LenUINT32;
			status = STATUS_SUCCESS;
			break;	

		case IOCTRL_CAN_STATUS:			// UINT8_T can_st(UINT8_T channel);
			debug_printf("IOCTRL_CAN_STATUS routine\n");

			if( inBufLen < LenUINT8 ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}
			
			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel=%d\n", channel);
			charRet = can_st(channel);
			debug_printf("the result is %d\n", charRet);
			
			RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &charRet, LenUINT8);
		
			Irp->IoStatus.Information = LenUINT8;
			status = STATUS_SUCCESS;
			break;	
			
		case IOCTRL_CAN_RCV_LEN:		// UINT32_T can_RcvLngth(UINT8_T channel);
			debug_printf("IOCTRL_CAN_RCV_LEN routine\n");

			if(inBufLen < LenUINT8 ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}
			
			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel=%d\n", channel);
			intRet = can_RcvLngth(channel);
			debug_printf("the result is %d\n", intRet);
			
			RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &intRet, LenUINT32);
		
			Irp->IoStatus.Information = LenUINT32;
			status = STATUS_SUCCESS;
			break;	

		case IOCTRL_CAN_TRANS_LEN:		// UINT32_T can_TrsmtLngth(UINT8_T channel);
			debug_printf("IOCTRL_CAN_TRANS_LEN routine\n");

			if(inBufLen < LenUINT8 ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}
			
			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel=%d\n", channel);
			intRet = can_TrsmtLngth(channel);
			debug_printf("the result is %d\n", intRet);
			
			RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &intRet, LenUINT32);
		
			Irp->IoStatus.Information = LenUINT32;
			status = STATUS_SUCCESS;
			break;	

		case IOCTRL_CAN_REG_READ:		// UINT8_T rd_reg(UINT8_T channel, UINT8_T sja_reg);
			debug_printf("IOCTRL_CAN_REG_READ routine\n");

			if(inBufLen < 2*LenUINT8 ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}
			
			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel=%d\n", channel);
			sja_reg = (UINT8_T)(*(UINT8_T*)(buffer+LenUINT8));

			charRet = rd_reg(channel, sja_reg);
			debug_printf("the result is %d\n", charRet);
			
			RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &charRet, LenUINT8);
		
			Irp->IoStatus.Information = LenUINT8;
			status = STATUS_SUCCESS;
			break;	

		case IOCTRL_CAN_REG_WRITE:		// void wrt_reg(UINT8_T channel, UINT8_T sja_reg, char data);
			debug_printf("IOCTRL_CAN_REG_WRITE routine\n");

			if(inBufLen < 3*LenUINT8 ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}
			
			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel=%d\n", channel);
			sja_reg = (UINT8_T)(*(UINT8_T*)(buffer+LenUINT8));
			data = buffer[2*LenUINT8];
			wrt_reg(channel, sja_reg, data);
			
			status = STATUS_SUCCESS;
			break;	

		case IOCTRL_CAN_READ_TRNSMEM:	// int can_rd_trn(UINT8_T channel, char *rxdata);
			debug_printf("IOCTRL_CAN_READ_TRNSMEM routine\n");

			if(inBufLen<LenUINT8 || outBufLen<CAN_FRAME_LEN ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}
			
			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel=%d\n", channel);
			intRet = can_rd_trn(channel, outBuf);
			debug_printf("the result is %d\n", intRet);
			
			RtlCopyMemory(outBuf+CAN_FRAME_LEN, &intRet, LenUINT32);
			RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, outBuf, CAN_FRAME_LEN+LenUINT32);
		
			Irp->IoStatus.Information = LenUINT32+CAN_FRAME_LEN;
			status = STATUS_SUCCESS;
			break;	

		case IOCTRL_CAN_WRITE_RECVMEM:	// void can_wrt_recv(UINT8_T channel, char *txdata);
			debug_printf("IOCTRL_CAN_WRITE_RECVMEM routine\n");

			if(inBufLen < LenUINT8+CAN_FRAME_LEN ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}
			
			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel=%d\n", channel);
			
			can_wrt_recv(channel, buffer+LenUINT8);
			
			status = STATUS_SUCCESS;
			break;	

		case IOCTRL_CAN_SET_URG:		//void can_set_urg(UINT8_T channel, char *ACK);
			debug_printf("IOCTRL_CAN_SET_URG routine\n");

			if(inBufLen < LenUINT8+CAN_ACK_LEN ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}
			
			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel=%d\n", channel);
			can_set_urg(channel, buffer+LenUINT8);
			
			status = STATUS_SUCCESS;
			break;	

		case IOCTRL_CAN_TRANS_URG:		//void can_TrnUrg(UINT8_T channel, char *txdata);
			debug_printf("IOCTRL_CAN_TRANS_URG routine\n");

			if(inBufLen < LenUINT8+CAN_FRAME_LEN ){
					status = STATUS_UNSUCCESSFUL;
					break;
			}
			
			channel = (UINT8_T)(*(UINT8_T*)(buffer));
			debug_printf("channel=%d\n", channel);
			can_TrnUrg(channel, buffer+LenUINT8);
			
			status = STATUS_SUCCESS;
			break;	

		case IOCTRL_CAN_REGSTR_FUN:		//void registerFunc(PFUNC func);
			debug_printf("IOCTRL_CAN_REGSTR_FUN routine\n");

			debug_printf("registerFunc routine was reserved.\n");
			
			status = STATUS_SUCCESS;
			break;	

		default:
			debug_printf("invalid IOCTL Code.\n");
			status = STATUS_UNSUCCESSFUL;
    }

    //
    // Complete the I/O Request
    //
    Irp->IoStatus.Status = status;

    IoCompleteRequest( Irp, IO_NO_INCREMENT );

    return status;
}

//***************************************************************************************

⌨️ 快捷键说明

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