?? regisaint.c
字號:
/********************************************************************/
/*Register Isa Interrupt driver composed by 曾國強*******************/
/********************************************************************/
#include <ntddk.h>
#include"DebugPrint.h"
#include"RegIsaIntIOCtl.h"
#define outportb(ADDR,BYTE) WRITE_PORT_UCHAR(ADDR,BYTE)
#define inportb(ADDR) READ_PORT_UCHAR(ADDR)
typedef struct _IntPara{
/*interrupt vector*/
unsigned short m_IrqNum;
/*m_TrigManner==true:Latched; m_TrigManner==false:LevelSensitive*/
int m_TrigManner;
}IntPara,*PIntPara;
typedef struct _LOCAL_DEVICE_INFO {
PKINTERRUPT InterruptObject;
ULONG Level;
ULONG Vector;
KAFFINITY Affinity;
IntPara m_IntPara;
int m_ConnectInt;/*m_ConnectInt==true:Connected; m_ConnectInt==false:disconnected*/
} LOCAL_DEVICE_INFO, *PLOCAL_DEVICE_INFO;
/*斷開中斷*/
VOID UnRegisterInt(IN PLOCAL_DEVICE_INFO deviceExt);
/*連接中斷*/
NTSTATUS RegisterInt(IN PLOCAL_DEVICE_INFO DeviceExtension,IN PDEVICE_OBJECT DeviceObject);
PKEVENT IntComeEvent;/*獲得應用程序生成的事件*/
NTSTATUS RegIsaIntCreateDispatch(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PLOCAL_DEVICE_INFO deviceExt;/*設備擴展*/
PIO_STACK_LOCATION IrpStack;/*Irp棧*/
NTSTATUS status;
NTSTATUS status_reg;
ULONG dwIoControlCode;
PULONG pSystemBuffer;/*系統緩沖區指針*/
IntPara IntParaTemp;
deviceExt=DeviceObject->DeviceExtension;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
pSystemBuffer = Irp->AssociatedIrp.SystemBuffer;
switch (IrpStack->MajorFunction)
{
case IRP_MJ_CREATE: /*與WIN32應用程序中的CreateFile對應,鎖定內存*/
break;
case IRP_MJ_CLOSE: /*與WIN32應用程序中的CloseHandle對應,此處解除對內存的鎖定*/
break;
case IRP_MJ_DEVICE_CONTROL: /*與WIN32應用程序中的DeviceIoControl對應*/
dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
switch (dwIoControlCode)
{
case RegisterIsaInt:
IntParaTemp=*(IntPara*)pSystemBuffer;
/*連接不同的中斷*/
if(IntParaTemp.m_IrqNum!=deviceExt->m_IntPara.m_IrqNum)
{
/*先前掛接的中斷還沒有斷開*/
if(deviceExt->m_ConnectInt==1)
{
UnRegisterInt(deviceExt);
deviceExt->m_ConnectInt=0;
}
deviceExt->m_IntPara=IntParaTemp;
status_reg=RegisterInt(deviceExt,DeviceObject);
if(NT_SUCCESS(status_reg))
deviceExt->m_ConnectInt=1;
else
deviceExt->m_ConnectInt=0;
*(int*)pSystemBuffer=deviceExt->m_ConnectInt;
Irp->IoStatus.Information=sizeof(deviceExt->m_ConnectInt);
}
/*連接相同的中斷*/
else
{
/*尚未掛接中斷,可以直接掛接*/
if(deviceExt->m_ConnectInt==0)
{
deviceExt->m_IntPara=IntParaTemp;
status_reg=RegisterInt(deviceExt,DeviceObject);
if(NT_SUCCESS(status_reg))
deviceExt->m_ConnectInt=1;
else
deviceExt->m_ConnectInt=0;
*(int*)pSystemBuffer=deviceExt->m_ConnectInt;
Irp->IoStatus.Information=sizeof(deviceExt->m_ConnectInt);
}
/*已經掛接了中斷*/
else
{
/*中斷的觸發方式改變了,則重新斷開,并掛接*/
if(IntParaTemp.m_TrigManner!=deviceExt->m_IntPara.m_TrigManner)
{
UnRegisterInt(deviceExt);
deviceExt->m_ConnectInt=0;
deviceExt->m_IntPara=IntParaTemp;
status_reg=RegisterInt(deviceExt,DeviceObject);
if(NT_SUCCESS(status_reg))
deviceExt->m_ConnectInt=1;
else
deviceExt->m_ConnectInt=0;
*(int*)pSystemBuffer=deviceExt->m_ConnectInt;
Irp->IoStatus.Information=sizeof(deviceExt->m_ConnectInt);
}
/*中斷的觸發方式沒有改變,則什么都不做*/
else
{
*(int*)pSystemBuffer=deviceExt->m_ConnectInt;
Irp->IoStatus.Information=sizeof(deviceExt->m_ConnectInt);
}
}
}
break;
case UnRegisterIsaInt:
if(deviceExt->m_ConnectInt==1)
{
UnRegisterInt(deviceExt);
deviceExt->m_ConnectInt=0;
}
break;
case PassDownEvent:
ObReferenceObjectByHandle((HANDLE)(*pSystemBuffer),
0x0002,
NULL,
UserMode,
(PVOID *)(&IntComeEvent),
NULL);
break;
default: // 不支持的IOCTL
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}
}
status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
VOID RegIsaIntDpcRoutine(IN PKDPC Dpc, PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
PLOCAL_DEVICE_INFO DeviceExtension;
PIRP pIrp;
pIrp = DeviceObject->CurrentIrp;
DeviceExtension = DeviceObject->DeviceExtension;
/*設置事件為有效狀態*/
KeSetEvent(IntComeEvent,2,FALSE);
}
//中斷處理例程
BOOLEAN RegIsaIntIsr(IN PKINTERRUPT Interrupt, IN OUT PVOID Context)
{
PDEVICE_OBJECT DeviceObject = Context;
/*請求異步過程調用*/
IoRequestDpc(DeviceObject,
DeviceObject->CurrentIrp,
NULL);
return TRUE;
}
/*斷開中斷*/
VOID UnRegisterInt(IN PLOCAL_DEVICE_INFO deviceExt)
{
/* Disconnect Interrupt */
IoDisconnectInterrupt(deviceExt->InterruptObject);
DebugPrint("RegIsaInt.sys: Disconnect interrupt!\n");
}
/*掛接中斷*/
NTSTATUS RegisterInt(IN PLOCAL_DEVICE_INFO DeviceExtension,IN PDEVICE_OBJECT DeviceObject)
{
NTSTATUS status;
ULONG MappedVector;
KIRQL Irql;
DeviceExtension->Level = DeviceExtension->m_IntPara.m_IrqNum;
DeviceExtension->Vector = DeviceExtension->Level;
MappedVector = HalGetInterruptVector(Isa,
0,
DeviceExtension->Level,
DeviceExtension->Vector,
&Irql,
&DeviceExtension->Affinity);
if (MappedVector == 0)
DebugPrint("RegIsaInt.sys: HalGetInterruptVector failed\n");
if(DeviceExtension->m_IntPara.m_TrigManner==1)/*邊沿觸發*/
{
status = IoConnectInterrupt(&DeviceExtension->InterruptObject, // InterruptObject
RegIsaIntIsr, // ServiceRoutine
DeviceObject, // ServiceContext
NULL, // SpinLock
MappedVector, // Vector
Irql, // Irql
Irql, // SynchronizeIrql
Latched, // InterruptMode
TRUE, // ShareVector
DeviceExtension->Affinity, // ProcessorEnableMask
FALSE); // FloatingSave
}
else/*電平觸發*/
{
status = IoConnectInterrupt(&DeviceExtension->InterruptObject, // InterruptObject
RegIsaIntIsr, // ServiceRoutine
DeviceObject, // ServiceContext
NULL, // SpinLock
MappedVector, // Vector
Irql, // Irql
Irql, // SynchronizeIrql
LevelSensitive, // InterruptMode
TRUE, // ShareVector
DeviceExtension->Affinity, // ProcessorEnableMask
FALSE);
}
if (!NT_SUCCESS (status))
DebugPrint("RegIsaInt.sys: IoConnectInterrupt Failed\n");
else
DebugPrint("RegIsaInt.sys: success to register interrupt\n");
return status;
}
//卸載例程
VOID RegIsaIntUnload(IN PDRIVER_OBJECT DriverObject)
{
WCHAR DOSNameBuffer[] = L"\\DosDevices\\RegIsaInt";
UNICODE_STRING uniDOSString;
PLOCAL_DEVICE_INFO deviceExt= DriverObject->DeviceObject->DeviceExtension;
/*斷開已經連接的中斷*/
if(deviceExt->m_ConnectInt==1)
UnRegisterInt(deviceExt);
/* Delete Symbolic Link */
RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);
IoDeleteSymbolicLink (&uniDOSString);
/* Delete Device */
IoDeleteDevice(DriverObject->DeviceObject);
/*關閉DebugPrint調試軟件的句柄*/
DebugPrintClose();
}
//驅動程序的入口
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS status;
PLOCAL_DEVICE_INFO DeviceExtension;
ULONG i;
LONG EventState;
WCHAR NameBuffer[] = L"\\Device\\RegIsaInt";
WCHAR DOSNameBuffer[] = L"\\DosDevices\\RegIsaInt";
UNICODE_STRING uniNameString, uniDOSString,uniEventName;
//打開DebugPrint軟件的句柄
#if DBG
DebugPrintInit("Wdm1 checked");
#else
DebugPrintInit("Wdm1 free");
#endif
RtlInitUnicodeString(&uniNameString, NameBuffer);
RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);
//由驅動對象生成一個設備對象
status = IoCreateDevice(DriverObject, // DriverObject
sizeof(LOCAL_DEVICE_INFO), // DeviceExtensionSize
&uniNameString, // DeviceName
FILE_DEVICE_UNKNOWN, // DeviceType
0, // DeviceCharacteristics
TRUE, // Exclusive
&DeviceObject); // *DeviceObject
if(!NT_SUCCESS(status)) return status;
DeviceExtension = DeviceObject->DeviceExtension;
/*創建一個符號鏈接*/
status = IoCreateSymbolicLink (&uniDOSString, &uniNameString);
/*初始化異步過程調用*/
IoInitializeDpcRequest(DeviceObject,RegIsaIntDpcRoutine);
if (!NT_SUCCESS(status)) return status;
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =RegIsaIntCreateDispatch;
DriverObject->DriverUnload = RegIsaIntUnload;
DeviceExtension->m_ConnectInt=0;
DeviceExtension->m_IntPara.m_TrigManner=1;
DeviceExtension->m_IntPara.m_IrqNum=2;
DebugPrint("RegIsaInt.sys: Driver Entry!\n");
return STATUS_SUCCESS;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -