⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.cpp

📁 windows2000驱动编程源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -