📄 driver.cpp
字号:
if (!NT_SUCCESS(status)) {
#if DBG>=2
DbgPrint("THREADDMA: Interrupt connection failure: %X\n", status);
#endif
return status;
}
#if DBG>=2
DbgPrint("THREADDMA: Interrupt successfully connected\n");
#endif
pDevExt->state = Started;
return PassDownPnP(pDO, pIrp);
}
NTSTATUS HandleStopDevice( IN PDEVICE_OBJECT pDO,
IN PIRP pIrp ) {
#if DBG>=1
DbgPrint("THREADDMA: StopDevice Handler\n");
#endif
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pDO->DeviceExtension;
// Delete our Interrupt object
if (pDevExt->pIntObj)
IoDisconnectInterrupt( pDevExt->pIntObj );
pDevExt->pIntObj = NULL;
// Delete the DMA Adapter object
pDevExt->pDmaAdapter->DmaOperations->
FreeAdapterChannel( pDevExt->pDmaAdapter );
pDevExt->pDmaAdapter = NULL;
pDevExt->state = Stopped;
return PassDownPnP(pDO, pIrp);
}
NTSTATUS HandleRemoveDevice(IN PDEVICE_OBJECT pDO,
IN PIRP pIrp ) {
#if DBG>=1
DbgPrint("THREADDMA: RemoveDevice Handler\n");
#endif
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pDO->DeviceExtension;
if (pDevExt->state == Started) {
// Woah! we still have an interrupt object out there!
// Delete our Interrupt object
if (pDevExt->pIntObj)
IoDisconnectInterrupt( pDevExt->pIntObj );
pDevExt->pIntObj = NULL;
}
// Since AddDevice created a system thread,
// RemoveDevice must kill it.
KillThread( pDevExt );
// This will yield the symbolic link name
UNICODE_STRING pLinkName =
pDevExt->ustrSymLinkName;
// ... which can now be deleted
IoDeleteSymbolicLink(&pLinkName);
#if DBG>=1
DbgPrint("THREADDMA: Symbolic Link MPMP%d Deleted\n",
pDevExt->DeviceNumber+1);
#endif
// Delete the device
IoDeleteDevice( pDO );
pDevExt->state = Removed;
return PassDownPnP( pDO, pIrp );
}
//++
// Function: DriverUnload
//
// Description:
// For this driver, does nothing
//
// Arguments:
// pDriverObject - Passed from I/O Manager
//
// Return value:
// None
//--
VOID DriverUnload (
IN PDRIVER_OBJECT pDriverObject ) {
#if DBG>=1
DbgPrint("THREADDMA: DriverUnload\n");
#endif
}
//++
// Function: DispatchCreate
//
// Description:
// Handles call from Win32 CreateFile request
// For this driver, does nothing
//
// Arguments:
// pDevObj - Passed from I/O Manager
// pIrp - Passed from I/O Manager
//
// Return value:
// NTSTATUS - success or failure code
//--
NTSTATUS DispatchCreate (
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp ) {
#if DBG>=1
DbgPrint("THREADDMA: DispatchCreate\n");
#endif
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pDevObj->DeviceExtension;
NTSTATUS status = STATUS_SUCCESS;
if (pDevExt->state != Started)
status = STATUS_DEVICE_REMOVED;
// TODO: Reserve any resources needed on a per Open basis
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0; // no bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return status;
}
//++
// Function: DispatchClose
//
// Description:
// Handles call from Win32 CreateHandle request
// For this driver, does nothing
//
// Arguments:
// pDevObj - Passed from I/O Manager
// pIrp - Passed from I/O Manager
//
// Return value:
// NTSTATUS - success or failure code
//--
NTSTATUS DispatchClose (
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp ) {
#if DBG>=1
DbgPrint("THREADDMA: DispatchClose\n");
#endif
// For this driver, does nothing
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0; // no bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
//++
// Function: DispatchCancel
//
// Description:
// Handles canceled IRP
//
// Arguments:
// pDevObj - Passed from I/O Manager
// pIrp - Passed from I/O Manager
//
// Return value:
// NTSTATUS - success or failuer code
//--
VOID DispatchCancel (
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp ) {
#if DBG>=1
DbgPrint("THREADDMA: IRP Canceled\n");
#endif
// TODO: Perform IRP cleanup work
// Just complete the IRP
pIrp->IoStatus.Status = STATUS_CANCELLED;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
IoStartNextPacket( pDevObj, TRUE );
}
//++
// Function: DispatchReadWrite
//
// Description:
// Handles call from Win32 WriteFile request
// For this driver, IRP is "pended" and placed
// into the work queue for this Device object.
// The work queue's Semaphore object is incremented.
// Notice the lack of a call to IoStartPacket.
// Instead the worker thread will pick up the
//
// Arguments:
// pDevObj - Passed from I/O Manager
// pIrp - Passed from I/O Manager
//
// Return value:
// NTSTATUS - success or failuer code
//--
NTSTATUS DispatchReadWrite (
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp ) {
#if DBG>=1
DbgPrint("THREADDMA: Read/Write Operation requested (DispatchWrite)\n");
#endif
PIO_STACK_LOCATION pIrpStack =
IoGetCurrentIrpStackLocation( pIrp );
PDEVICE_EXTENSION pDE = (PDEVICE_EXTENSION)
pDevObj->DeviceExtension;
// Check for zero-length transfers
if ( pIrpStack->Parameters.Read.Length == 0 ) {
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
// Start device operation
IoMarkIrpPending( pIrp );
// Add the IRP to the thread's work queue
ExInterlockedInsertTailList (
&pDE->IrpQueueListHead,
&pIrp->Tail.Overlay.ListEntry,
&pDE->lkIrpQueue );
KeReleaseSemaphore(
&pDE->semIrpQueue,
0, // No priority boost
1, // Increment semaphore by 1
FALSE ); // No WaitForXxx after this call
return STATUS_PENDING;
}
BOOLEAN Isr (
IN PKINTERRUPT pIntObj,
IN PVOID pServiceContext ) {
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pServiceContext;
PDEVICE_OBJECT pDevObj = pDevExt->pDevice;
PIRP pIrp = pDevObj->CurrentIrp;
// TODO: If interrupt was not generated by our device,
// get out quickly by returning FALSE.
// return FALSE;
// If its our interrupt, deal with it
// TODO: Dismiss HW interrupt by writing appropriate
// Control info to device
// Were we expecting an interrupt?
if (!pDevExt->bInterruptExpected)
return TRUE; // nope
pDevExt->bInterruptExpected = FALSE;
// TODO: If more data must be transferred as part
// of this IRP request, restart the device.
// Otherwise, schedule the DPC to complete the IRP.
IoRequestDpc( pDevObj, pIrp, (PVOID)pDevExt );
return TRUE;
}
//++
// Function:
// DpcForIsr
//
// Description:
// This function performs the low-IRQL
// post-processing of I/O requests
//
// Arguments:
// Pointer to a DPC object
// Pointer to the Device object
// Pointer to the IRP for this request
// Pointer to the Device Extension
//
// Return Value:
// (None)
//--
VOID
DpcForIsr(
IN PKDPC pDpc,
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp,
IN PVOID pContext
)
{
PDEVICE_EXTENSION pDE = (PDEVICE_EXTENSION)
pContext;
#if DBG>=1
DbgPrint("THREADDMA: DpcForIsr\n");
#endif
// When the device generates an
// interrupt, the Interrupt Service routine
// saves the status of the hardware
// and requests a DPC. Eventually, DpcForIsr
// executes and just sets an Event object into the
// Signaled state. PerformSynchronousTransfer
// (which has been waiting for this Event object) wakes up and
// continues processing the current IRP.
KeSetEvent(
&pDE->evDeviceOperationComplete,
0,
FALSE );
}
//++
// Function: GetDmaInfo
//
// Description:
// Initializes the driver's DMA Adapter
//
// Arguments:
// busType - Isa, Internal, etc.
// busNumber - raw bus number
//
// Return value:
// NTSTATUS signaling success or failure
//--
NTSTATUS GetDmaInfo( IN INTERFACE_TYPE busType,
IN PDEVICE_OBJECT pDevObj ) {
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pDevObj->DeviceExtension;
DEVICE_DESCRIPTION dd;
// Zero out the entire structure
RtlZeroMemory( &dd, sizeof(dd) );
dd.Version = DEVICE_DESCRIPTION_VERSION1;
dd.Master = FALSE; // this is a slave device
dd.ScatterGather = FALSE;
dd.DemandMode = FALSE;
dd.AutoInitialize = FALSE;
dd.Dma32BitAddresses = FALSE;
dd.InterfaceType = busType; // as passed in
dd.DmaChannel = pDevExt->dmaChannel;
dd.MaximumLength = MAX_DMA_LENGTH;
dd.DmaWidth = Width16Bits;
dd.DmaSpeed = Compatible;
// Compute the maximum number of mapping regs
// this device could possibly need. Since the
// transfer may not be paged aligned, add one
// to allow the max xfer size to span a page.
pDevExt->mapRegisterCount =
(MAX_DMA_LENGTH / PAGE_SIZE) + 1;
pDevExt->pDmaAdapter =
IoGetDmaAdapter( pDevObj,
&dd,
&pDevExt->mapRegisterCount);
// If the Adapter object can't be assigned, fail
if (pDevExt->pDmaAdapter == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
else
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -