📄 candriver.c
字号:
//* NAME: IoCtrlCreateClose
//*
//* DESCRIPTION: This is the dispatch entry point for IRP_MJ_CREATE and IRP_MJ_CLOSE
//* routines. This sample simply completes the requests with success.
//*
//* PARAMETERS: DriverObject IN Address of our DRIVER_OBJECT.
//* Irp IN Address of the IRP.
//*
//* IRQL: IRQL_PASSIVE_LEVEL.
//*
//* RETURNS: STATUS_SUCCESS
//***************************************************************************************
NTSTATUS
IoCtrlCreateClose
(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
DbgPrint( "IoCtrlCreateClose\n" );
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Completete the request
IoCompleteRequest( Irp, IO_NO_INCREMENT );
DbgPrint( "CreateClose completed.\n");
return STATUS_SUCCESS;
}
//***************************************************************************************
//* NAME: DriverUnload
//*
//* DESCRIPTION: This routine is our dynamic unload entry point.
//*
//* PARAMETERS: DriverObject IN Address of our DRIVER_OBJECT.
//*
//* IRQL: IRQL_PASSIVE_LEVEL.
//*
//* RETURNS: None
//***************************************************************************************
VOID
DriverUnload
(
IN PDRIVER_OBJECT DriverObject
)
{
UNICODE_STRING symbolicName;
PDEVICE_EXTENSION extension = DriverObject->DeviceObject->DeviceExtension;
// Unloading - no resources to free so just return.
DbgPrint( "Unloading...\n");
/* Disconnect Interrupt */
//IoDisconnectInterrupt(extension->InterruptObject);
//Delete the symbolic link
DbgPrint( "Delete the symbolic link...\n");
RtlInitUnicodeString( &symbolicName, SYMBOLIC_LINK_NAME );
IoDeleteSymbolicLink( &symbolicName );
// Delete the DeviceObject
DbgPrint( "Delete the DeviceObject...\n");
IoDeleteDevice( DriverObject->DeviceObject );
return;
}
/*
*中断处理例程,
*/
BOOLEAN InterruptIsr(IN PKINTERRUPT Interrupt, IN OUT PVOID Context)
{
PDEVICE_OBJECT DeviceObject = Context;
KdPrint( ("Interrupt.sys: Interrupt Service Routine\n") );
/* We should check if the interrupt comes from us and return */
IoRequestDpc(DeviceObject,
DeviceObject->CurrentIrp,
DeviceObject);
return TRUE;
}
/*
*InterruptDpcRoutine
*/
VOID InterruptDpcRoutine(IN PKDPC Dpc, PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
PDEVICE_EXTENSION DeviceExtension;
PIRP pIrp;
pIrp = DeviceObject->CurrentIrp;
DeviceExtension = DeviceObject->DeviceExtension;
DbgPrint( "Interrupt.sys: DPC Routine - Completing Interrupt Request\n");
/* Do any processing here */
return;
}
/******************************************************************************
*
* Function : LockDevice
*
* Description: Lock a device for operation, return FALSE if device is being
* removed.
*
******************************************************************************/
BOOLEAN LockDevice(IN DEVICE_EXTENSION *pdx)
{
//LockDevice
// Increment use count on our device object
//InterlockedIncrement(&pdx->UsageCount);
/*
If device is about to be removed, restore the use count and return FALSE.
If a race exists with HandleRemoveDevice (maybe running on another CPU),
the sequence we've followed is guaranteed to avoid a mistaken deletion of
the device object. If we test "removing" after HandleRemoveDevice sets
it, we'll restore the use count and return FALSE. In the meantime, if
HandleRemoveDevice decremented count to 0 before we did our increment,
its thread will have set the remove event. Otherwise, we'll decrement to
0 and set the event. Either way, HandleRemoveDevice will wake up to
finish removing the device, and we'll return FALSE to our caller.
If, on the other hand, we test "removing" before HandleRemoveDevice sets
it, we'll have already incremented the use count past 1 and will return
TRUE. Our caller will eventually call UnlockDevice, which will decrement
the use count and might set the event HandleRemoveDevice is waiting on at
that point.
*/
//if (pdx->bStopping)
//{
// Stopping device
// if (InterlockedDecrement(&pdx->UsageCount) == 0)
// KeSetEvent(&pdx->StoppingEvent,0,FALSE);
// return FALSE;
//}
// DebugPrint("PCI9052Demo is locked.");
return TRUE;
} //LockDevice
/******************************************************************************
*
* Function : UnlockDevice
*
* Description: Unlock a device.
*
******************************************************************************/
VOID UnlockDevice(IN DEVICE_EXTENSION *pdx)
{ //UnlockDevice
//LONG UsageCount = InterlockedDecrement(&pdx->UsageCount);
//DebugPrint("PCI9052Demo is unlocking...");
//KdPrint(("PCI9052Demo: UNLOCKING... (usage = %d)\n", UsageCount));
// if (UsageCount == 0)
//{
// Stopping device
// KeSetEvent(&pdx->StoppingEvent,0,FALSE);
//}
}
/*********************************************************************
*
* Function : EnablePciInterrupt
*
* Description: Enables the PLX Chip PCI Interrupt
*
**********************************************************************/
BOOLEAN EnablePciInterrupt(IN PDEVICE_EXTENSION pdx)
{ //EnablePciInterrupt
ULONG RegInterrupt;
ULONG Address;
LockDevice(pdx);
//Address=(ULONG)pdx->MemBase;
Address = 0;
RegInterrupt = READ_REGISTER_ULONG((ULONG *)(Address + 0x4c));
RegInterrupt |= 0x40;
WRITE_REGISTER_ULONG((ULONG *)(Address +0x4c),RegInterrupt);
UnlockDevice(pdx);
return TRUE;
} //EnablePciInterrupt
/*********************************************************************
*
* Function : DisablePciInterrupt
*
* Description: Disables the PLX Chip PCI Interrupt
*
**********************************************************************/
BOOLEAN DisablePciInterrupt(IN PDEVICE_EXTENSION pdx)
{ //DisablePciInterrupt
ULONG RegInterrupt;
ULONG Address;
LockDevice(pdx);
//Address=(ULONG)pdx->MemBase;
Address = 0;
RegInterrupt = READ_REGISTER_ULONG((ULONG *)(Address + 0x4c));
// DebugPrint("The interrupt register is 0x%x.",RegInterrupt);
RegInterrupt &= ~(0x40);
WRITE_REGISTER_ULONG((ULONG *)(Address +0x4c),RegInterrupt);
// DebugPrint("The interrupt register is 0x%x.",RegInterrupt);
UnlockDevice(pdx);
return TRUE;
}
//***************************************************************************************
//* NAME: DriverEntry
//*
//* DESCRIPTION: Registers dispatch routines.
//*
//* PARAMETERS: DriverObject IN
//* Address of the DRIVER_OBJECT created by NT for this driver.
//* RegistryPath IN
//* UNICODE_STRING which represents this drivers KEY in the Registry.
//*
//* IRQL: IRQL_PASSIVE_LEVEL.
//*
//* RETURNS: NTSTATUS
//***************************************************************************************
NTSTATUS
DriverEntry
(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT deviceObject;
PDEVICE_EXTENSION deviceExtension;
UNICODE_STRING deviceName;
UNICODE_STRING symbolicName;
ULONG MappedVector;
KIRQL Irql;
DbgPrint
(
"\n"
"www.DriverEntry.com\n"
"-------------------\n"
"IoCtrl Sample Driver\n"
"Compiled %s %s\n\n",
__DATE__,
__TIME__
);
// Register dispatch routines
DriverObject->MajorFunction[IRP_MJ_CREATE] = IoCtrlCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = IoCtrlCreateClose;
// Dispatch routine for communications
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoCtrlDeviceControl;
// Unload routine
DriverObject->DriverUnload = DriverUnload;
// Initialize the device name.
RtlInitUnicodeString( &deviceName, DEVICE_NAME );
//debug_printf("driver entry success\n");
// Create the device object and device extension
status = IoCreateDevice
(
DriverObject,
sizeof( DEVICE_EXTENSION ),
&deviceName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&deviceObject
);
if ( status != STATUS_SUCCESS )
{
return status;
}
// Get a pointer to our device extension
deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
// Save a pointer to the device object
deviceExtension->DeviceObject = deviceObject;
// Create a symbolic link to allow USER applications to access it.
RtlInitUnicodeString( &symbolicName, SYMBOLIC_LINK_NAME );
status = IoCreateSymbolicLink( &symbolicName, &deviceName );
if ( status != STATUS_SUCCESS )
{
//
// Error
//
IoDeleteDevice( deviceObject );
return status;
}
//连接中断
//deviceExtension->Level = 10;
//deviceExtension->Vector = deviceExtension->Level;
//MappedVector = HalGetInterruptVector(PCIBus,
// 0,
// deviceExtension->Level,
// deviceExtension->Vector,
// &Irql,
// &deviceExtension->Affinity);
// KdPrint( ("MappedVector = 0x%08X\n",MappedVector) );
// KdPrint( ("Level = 0x%08X\n",deviceExtension->Level) );
// KdPrint( ("Vector = 0x%08X\n",deviceExtension->Vector) );
// KdPrint( ("Irql = 0x%08X\n",Irql) );
// KdPrint( ("Affinity = 0x%08X\n",deviceExtension->Affinity) );
// if (MappedVector == 0) DbgPrint("HalGetInterruptVector failed\n");
// IoInitializeDpcRequest(deviceObject,InterruptDpcRoutine);
// Disable the PCI interrupt
//DisablePciInterrupt(deviceExtension);
// status = IoConnectInterrupt(&deviceExtension->InterruptObject, // InterruptObject
// InterruptIsr, // ServiceRoutine
// deviceObject, // ServiceContext
// NULL, // SpinLock
// MappedVector, // Vector
// Irql, // Irql
// Irql, // SynchronizeIrql
// LevelSensitive, // InterruptMode
// TRUE, // ShareVector
// deviceExtension->Affinity, // ProcessorEnableMask
// FALSE);
// DbgPrint("OK, I haved Connect Interruput!");
// if (!NT_SUCCESS (status))
// {
// DbgPrint("IoConnectInterrupt Failed\n");
// }
// else
// { // Re-enable the PCI Interrupt
//DbgPrint("OK, Let's enable interrupt.");
//if (deviceExtension->pInterruptObject == NULL)
//{
// DbgPrint("Interrupt object is NULL.");
//}
//同步Enable interrupt.
//KeSynchronizeExecution(deviceExtension->InterruptObject,(PKSYNCHRONIZE_ROUTINE)EnablePciInterrupt,deviceExtension);
// DbgPrint("Have Enabled Interrupt.");
// }
// Tell the I/O Manger to do BUFFERED IO
deviceObject->Flags |= DO_BUFFERED_IO;
// Save the DeviveObject
deviceExtension->DeviceObject = deviceObject;
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -