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

📄 driver.cpp

📁 windows2000驱动编程源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			IoDisconnectInterrupt( pDevExt->pIntObj );
	}

		// This will yield the symbolic link name
	UNICODE_STRING pLinkName =
		pDevExt->ustrSymLinkName;
	// ... which can now be deleted
	IoDeleteSymbolicLink(&pLinkName);
	
	// Delete the device
	IoDeleteDevice( pDO );
	
	pDevExt->state = Removed;
	return PassDownPnP( pDO, pIrp );
}

//++
// Function:	DriverUnload
//
// Description:
//		Stops & Deletes devices controlled by this driver.
//		Stops interrupt processing (if any)
//		Releases kernel resources consumed by driver
//
// Arguments:
//		pDriverObject - Passed from I/O Manager
//
// Return value:
//		None
//--

VOID DriverUnload (
		IN PDRIVER_OBJECT	pDriverObject	) {

}

//++
// 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			) {

	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
		pDevObj->DeviceExtension;
	NTSTATUS status = STATUS_SUCCESS;
	if (pDevExt->state != Started)
		status = STATUS_DEVICE_REMOVED;
	
	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			) {
	
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;
	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			) {

	// 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:
//		This function dispatches ReadFile
//		and WriteFile requests from Win32
//
// Arguments:
//		Pointer to Device object
//		Pointer to IRP for this request
//
// Return Value:
//		This function returns STATUS_XXX
//--
static NTSTATUS DispatchReadWrite(
	IN PDEVICE_OBJECT pDO,
	IN PIRP pIrp
	)
{
	PIO_STACK_LOCATION pIrpStack = 
				IoGetCurrentIrpStackLocation( pIrp );
	//
	// 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 );
	IoStartPacket( pDO, pIrp, 0, NULL );
	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;

	// Check HW to see if interrupt for this driver
	// If not, return FALSE immediately
		//return FALSE;

	// its our interrupt, deal with it
	// Dismiss the interrupt in HW now

	// Were we expecting an interrupt?
	if (!pDevExt->bInterruptExpected)
		return TRUE;	// nope
	pDevExt->bInterruptExpected = FALSE;

	// Do the rest of the work down
	// at DISPATCH_LEVEL IRQL
	IoRequestDpc( 
		pDevObj, 
		pIrp,
		(PVOID)pDevExt );

	return TRUE;
}

//++
// Function:
//		StartIo
//
// Description:
//		This function is responsible initiating the
//		actual data transfer. The ultimate result
//		should be an interrupt from the device.
//
// Arguments:
//		Pointer to the Device object
//		Pointer to the IRP for this request
//
// Return Value:
//		(None)
//--
VOID StartIo( IN PDEVICE_OBJECT pDevObj,
			IN PIRP pIrp ) {
	PIO_STACK_LOCATION pStack =
		IoGetCurrentIrpStackLocation( pIrp );

	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
		pDevObj->DeviceExtension;

	// The IRP holds the MDL structure, already set up by
	//   the I/O Manager because DO_DIRECT_IO flag is set
	PMDL pMdl = pIrp->MdlAddress;

	ULONG mapRegsNeeded;
	NTSTATUS status;

	pDevExt->bWriting = FALSE;	// assume read operation

	switch ( pStack->MajorFunction ) {
	case IRP_MJ_WRITE:
		pDevExt->bWriting = TRUE;	// bad assumption
	case IRP_MJ_READ:
		pDevExt->bytesRequested = 
			MmGetMdlByteCount( pMdl );
		pDevExt->transferVA = (PUCHAR)
			MmGetMdlVirtualAddress( pMdl );
		pDevExt->bytesRemaining =
		pDevExt->transferSize = 
			pDevExt->bytesRequested;

		mapRegsNeeded =
			ADDRESS_AND_SIZE_TO_SPAN_PAGES(
				pDevExt->transferVA,
				pDevExt->transferSize );

		if (mapRegsNeeded > pDevExt->mapRegisterCount) {
			mapRegsNeeded = pDevExt->mapRegisterCount;
			pDevExt->transferSize =
				mapRegsNeeded * PAGE_SIZE -
				MmGetMdlByteOffset( pMdl );
		}

		status = pDevExt->pDmaAdapter->DmaOperations->
				AllocateAdapterChannel(
					pDevExt->pDmaAdapter,
					pDevObj,
					mapRegsNeeded,
					AdapterControl,
					pDevExt );

		if (!NT_SUCCESS( status )) {
			// fail the IRP & don't continue with it
			pIrp->IoStatus.Status = status;
			// Show no bytes transferred
			pIrp->IoStatus.Information = 0;
			IoCompleteRequest( pIrp, IO_NO_INCREMENT );
			IoStartNextPacket( pDevObj, FALSE);
		}
		break;	// nice job - AdapterControl takes it
				//			from here on

	default:
		// Shouldn't be here - ditch this strange IRP
		pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
		pIrp->IoStatus.Information = 0;
		IoCompleteRequest( pIrp, IO_NO_INCREMENT );
		IoStartNextPacket( pDevObj, FALSE );
	}
}

//++
// Function:
//		AdapterControl
//
// Description:
//		This function sets up the first
//		part of a split transfer and
//		starts the DMA device.
//
// Arguments:
//		Device object
//		Current Irp
//		Map register base handle
//		Pointer to Device Extension
//
// Return Value:
//		KeepObject
//--
IO_ALLOCATION_ACTION AdapterControl(
					IN PDEVICE_OBJECT pDevObj,
					IN PIRP pIrp,
					IN PVOID MapRegisterBase,
					IN PVOID pContext ) {
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
								pContext;

	// Save the handle to the mapping register set
	pDevExt->mapRegisterBase = MapRegisterBase;

	// Flush the CPU cache(s), 
	//	if necessary on this platform...
	KeFlushIoBuffers( pIrp->MdlAddress,
				   !pDevExt->bWriting, 	// inverted
				   TRUE );			// yes DMA

	pDevExt->pDmaAdapter->DmaOperations->
		MapTransfer( pDevExt->pDmaAdapter,
				   pIrp->MdlAddress,
				   MapRegisterBase,	
				   pDevExt->transferVA,
				   &pDevExt->transferSize,
				   pDevExt->bWriting );

	// Start the device
	StartTransfer( pDevExt );

	return KeepObject;
}
//++
// 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 pDevExt = (PDEVICE_EXTENSION)
		pContext;
	ULONG mapRegsNeeded;
	PMDL pMdl = pIrp->MdlAddress;

	// Flush the Apapter buffer to system RAM or device.
	pDevExt->pDmaAdapter->DmaOperations->
		FlushAdapterBuffers( pDevExt->pDmaAdapter,
						 pMdl,
						 pDevExt->mapRegisterBase,	
						 pDevExt->transferVA,
						 pDevExt->transferSize,
						 pDevExt->bWriting );

	// If the device is reporting errors, fail the IRP
	if (DEVICE_FAIL( pDevExt )) {
		// An error occurred, the DMA channel is now free
		pDevExt->pDmaAdapter->DmaOperations->
			FreeAdapterChannel( pDevExt->pDmaAdapter );
		pIrp->IoStatus.Status = STATUS_DEVICE_DATA_ERROR;
		pIrp->IoStatus.Information =
			pDevExt->bytesRequested - 
			pDevExt->bytesRemaining;
		IoCompleteRequest( pIrp, IO_NO_INCREMENT );
		IoStartNextPacket( pDevObj, FALSE);
	}

	// Device had no errors, see if another partial needed
	pDevExt->bytesRemaining -= pDevExt->transferSize;
	if (pDevExt->bytesRemaining > 0) {
		// Another partial transfer needed
		// Update the transferVA and try to finish it
		pDevExt->transferVA += pDevExt->transferSize;
		pDevExt->transferSize = pDevExt->bytesRemaining;
		mapRegsNeeded =
			ADDRESS_AND_SIZE_TO_SPAN_PAGES(
				pDevExt->transferVA,
				pDevExt->transferSize );
		// If it still doesn't fit in one swipe,
		//	cut back the expectation
		if (mapRegsNeeded > pDevExt->mapRegisterCount) {
			mapRegsNeeded = pDevExt->mapRegisterCount;
			pDevExt->transferSize =
				mapRegsNeeded * PAGE_SIZE -
				BYTE_OFFSET( pDevExt->transferVA );
		}

		// Now set up the mapping registers for another
		pDevExt->pDmaAdapter->DmaOperations->
			MapTransfer( pDevExt->pDmaAdapter,
					   pMdl,
					   pDevExt->mapRegisterBase,
					   pDevExt->transferVA,
					   &pDevExt->transferSize,
					   pDevExt->bWriting );

		// And start the device
		StartTransfer( pDevExt );
	} else {
		// Entire transfer has now completed -
		// Free the DMA channel for another device
		pDevExt->pDmaAdapter->DmaOperations->
			FreeAdapterChannel( pDevExt->pDmaAdapter );
		// And complete the IRP in glory
		pIrp->IoStatus.Status = STATUS_SUCCESS;
		pIrp->IoStatus.Information = 
			pDevExt->bytesRequested;

		// Choose a priority boost appropriate for device
		IoCompleteRequest( pIrp, IO_DISK_INCREMENT );
		IoStartNextPacket( pDevObj, FALSE );
	}
}

VOID StartTransfer( IN PDEVICE_EXTENSION pDevExt ) {
	// This place holder routine would hold the code
	// necessary to manipulate the slave DMA device
	// so that it starts the transfer of data.
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -