#include <initguid.h>
#include "K1460Driver.h"
#include "comm.h"
#include "PCI.H"
#include "IOCTL.H"
#include "Interface.h"
#include "reg.h"
#pragma INITCODE
extern "C"
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
KdPrint(("Enter DriverEntry\n"));
pDriverObj->DriverExtension->AddDevice = DispatchAddDevice;
pDriverObj->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoControl;
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObj->MajorFunction[IRP_MJ_READ] = DispatchRead;
pDriverObj->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObj->DriverUnload = DispatchDriverUnload;
KdPrint(("Leave DriverEntry\n"));
return STATUS_SUCCESS;
}
#pragma PAGEDCODE
NTSTATUS DispatchAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject)
{
PAGED_CODE();
KdPrint(("Enter DispatchAddDEvice\n"));
NTSTATUS status;
PDEVICE_OBJECT fdo;
// UNICODE_STRING devName;
// RtlInitUnicodeString(&devName,L"\\Device\\K1460");
status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&fdo);
if(!NT_SUCCESS(status))
{
KdPrint(("Create fdo error\n"));
return status;
}
PDEVICE_EXTENSION pdx =(PDEVICE_EXTENSION)fdo->DeviceExtension;
RtlZeroMemory(pdx,sizeof(DEVICE_EXTENSION));
pdx->nTimeOut = 3000;//Time out default 3s
pdx->pdo = PhysicalDeviceObject;
pdx->fdo = fdo;
pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo,PhysicalDeviceObject);
//创建设备接口
status = IoRegisterDeviceInterface(PhysicalDeviceObject, &K1460_PCI_DEVICE, NULL, &pdx->interfaceName);
if( !NT_SUCCESS(status))
{
KdPrint(("IoRegisterDeviceInterface erro\n"));
IoDeleteDevice(fdo);
return status;
}
KdPrint(("%wZ\n",&pdx->interfaceName));
IoSetDeviceInterfaceState(&pdx->interfaceName, TRUE);
/* UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName,L"\\DosDevices\\K1460");
pdx->SymLinkName = symLinkName;
pdx->DeviceName = devName;
status = IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName,&(UNICODE_STRING)devName);
if(!NT_SUCCESS(status))
{
KdPrint(("Create SymLinkName error\n"));
IoDeleteSymbolicLink(&pdx->SymLinkName);
return status;
}*/
//init interrupt dpc
KeInitializeDpc(&pdx->dpc, DpcForIsr, (PVOID)pdx);
//init event;
pdx->pCmdEvent = NULL;
pdx->pCmdEvent = (KEVENT*)ExAllocatePool(NonPagedPool,sizeof(KEVENT));
if(pdx->pCmdEvent == NULL)
{
KdPrint(("分配pCmeEvent空间失败"));
IoDeleteDevice( fdo );
return STATUS_UNSUCCESSFUL;
}
KeInitializeEvent(pdx->pCmdEvent,SynchronizationEvent ,FALSE);
pdx->pDmaEvent = NULL;
pdx->pDmaEvent = (KEVENT*)ExAllocatePool(NonPagedPool,sizeof(KEVENT));
if(pdx->pDmaEvent == NULL)
{
KdPrint(("分配pDmaEvent空间失败"));
IoDeleteDevice( fdo );
return STATUS_UNSUCCESSFUL;
}
KeInitializeEvent(pdx->pDmaEvent,SynchronizationEvent ,FALSE);
pdx->InterruptStatus = 0;
//init
fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
KdPrint(("Leave DispatchAddDEvice\n"));
return STATUS_SUCCESS;
}
#pragma PAGEDCODE
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
PAGED_CODE();
KdPrint(("Enter DispatchPnp"));
NTSTATUS status = STATUS_SUCCESS;
static char* fcnname[] =
{
"IRP_MN_START_DEVICE",
"IRP_MN_QUERY_REMOVE_DEVICE",
"IRP_MN_REMOVE_DEVICE",
"IRP_MN_CANCEL_REMOVE_DEVICE",
"IRP_MN_STOP_DEVICE",
"IRP_MN_QUERY_STOP_DEVICE",
"IRP_MN_CANCEL_STOP_DEVICE",
"IRP_MN_QUERY_DEVICE_RELATIONS",
"IRP_MN_QUERY_INTERFACE",
"IRP_MN_QUERY_CAPABILITIES",
"IRP_MN_QUERY_RESOURCES",
"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
"IRP_MN_QUERY_DEVICE_TEXT",
"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
"",
"IRP_MN_READ_CONFIG",
"IRP_MN_WRITE_CONFIG",
"IRP_MN_EJECT",
"IRP_MN_SET_LOCK",
"IRP_MN_QUERY_ID",
"IRP_MN_QUERY_PNP_DEVICE_STATE",
"IRP_MN_QUERY_BUS_INFORMATION",
"IRP_MN_DEVICE_USAGE_NOTIFICATION",
"IRP_MN_SURPRISE_REMOVAL",
};
static NTSTATUS (*funtab[])(PDEVICE_EXTENSION pdx,PIRP Irp) =
{
HandleStartDevice, // IRP_MN_START_DEVICE 驱动加载启动
DefaultPnpHandler, // IRP_MN_QUERY_REMOVE_DEVICE
HandleRemoveDevice, // IRP_MN_REMOVE_DEVICE
DefaultPnpHandler, // IRP_MN_CANCEL_REMOVE_DEVICE
DefaultPnpHandler, // IRP_MN_STOP_DEVICE // stopDevice
DefaultPnpHandler, // IRP_MN_QUERY_STOP_DEVICE
DefaultPnpHandler, // IRP_MN_CANCEL_STOP_DEVICE
DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_RELATIONS
DefaultPnpHandler, // IRP_MN_QUERY_INTERFACE
DefaultPnpHandler, // IRP_MN_QUERY_CAPABILITIES
DefaultPnpHandler, // IRP_MN_QUERY_RESOURCES
DefaultPnpHandler, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS
DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_TEXT
DefaultPnpHandler, // IRP_MN_FILTER_RESOURCE_REQUIREMENTS
DefaultPnpHandler, //
DefaultPnpHandler, // IRP_MN_READ_CONFIG
DefaultPnpHandler, // IRP_MN_WRITE_CONFIG
DefaultPnpHandler, // IRP_MN_EJECT
DefaultPnpHandler, // IRP_MN_SET_LOCK
DefaultPnpHandler, // IRP_MN_QUERY_ID
DefaultPnpHandler, // IRP_MN_QUERY_PNP_DEVICE_STATE
DefaultPnpHandler, // IRP_MN_QUERY_BUS_INFORMATION
DefaultPnpHandler, // IRP_MN_DEVICE_USAGE_NOTIFICATION
DefaultPnpHandler, // IRP_MN_SURPRISE_REMOVAL
};
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
PIO_STACK_LOCATION stackLocation = IoGetCurrentIrpStackLocation(Irp);
ULONG funirpid = stackLocation->MinorFunction;
if(funirpid >= arraysize(funtab))
{
status = DefaultPnpHandler(pdx,Irp);
return status;
}
else
{
KdPrint(("Enter Pnp Request:%s\n",fcnname[funirpid]));
status = (*funtab[funirpid])(pdx,Irp);
return status;
}
KdPrint(("Leave DispatchPnp"));
}
#pragma PAGEDCODE
NTSTATUS DispatchIoControl(IN PDEVICE_OBJECT fdo,IN PIRP pIrp)
{
PAGED_CODE();
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
PIO_STACK_LOCATION pStackLocation = IoGetCurrentIrpStackLocation(pIrp);
ULONG ulInputLength = pStackLocation->Parameters.DeviceIoControl.InputBufferLength;
ULONG IoControlCode = pStackLocation->Parameters.DeviceIoControl.IoControlCode;
NTSTATUS status = STATUS_SUCCESS;
//防止未定义的控制码
BOOLEAN IsCtrl = FALSE;
static STRUCT_FUN_POINTER fn[] =
{
{IOCTL_WRITE_REGISTER,PciWriteRegister},
{IOCTL_READ_REGISTER,PciReadRegister},
{IOCTL_SEND_CMD,PciSendCmd},
{IOCTL_SET_TIMEOUT,PciSetTimeOut},
{IOCTL_SET_PARAM,PciSetParam},
};
for(ULONG i=0;i<sizeof(fn)/sizeof(fn[0]);i++)
{
if(IoControlCode == fn[i].IoCtlCode )
{
status = (*fn[i].fn)(fdo,pIrp);
IsCtrl = TRUE;
break;
}
}
if(!IsCtrl)
{
KdPrint(("未定义的控制码!\n"));
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
return status;
}
#pragma PAGEDCODE
NTSTATUS DispatchCreate(IN PDEVICE_OBJECT fdo,IN PIRP pIrp)
{
PAGED_CODE();
KdPrint(("open device K1460 -- driver\n"));
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
#pragma PAGEDCODE
NTSTATUS DispatchClose(IN PDEVICE_OBJECT fdo,IN PIRP pIrp)
{
NTSTATUS status = STATUS_SUCCESS;
KdPrint(("Close Device \n"));
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return status;
}
#pragma PAGEDCODE
VOID Dispatc