📄 candriver.c
字号:
//***************************************************************************************
//* 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 + -