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

📄 driver.cpp

📁 windows2000驱动编程源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	pDevExt->state = Started;

	return PassDownPnP(pDO, pIrp);

}

NTSTATUS HandleStopDevice(	IN PDEVICE_OBJECT pDO,
							IN PIRP pIrp ) {
#if DBG>=1
	DbgPrint("HIFILTER: StopDevice Handler\n");
#endif
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
		pDO->DeviceExtension;

	pDevExt->state = Stopped;

	return PassDownPnP(pDO, pIrp);
}

NTSTATUS HandleRemoveDevice(IN PDEVICE_OBJECT pDO,
							IN PIRP pIrp ) {
#if DBG>=1
	DbgPrint("HIFILTER: RemoveDevice Handler\n");
#endif
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
		pDO->DeviceExtension;

	// Delete the filter 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	) {
#if DBG>=1
	DbgPrint("HIFILTER: DriverUnload\n");
#endif

}

//++
// 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("HIFILTER: 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:	OverriddenDispatchWrite
//
// Description:
//		Handles call from Win32 WriteFile request
//		Breaks up large requests into multiple chuncks
//		suitable for the LODriver.
//
// Arguments:
//		pDevObj - Passed from I/O Manager
//		pIrp - Passed from I/O Manager
//
// Return value:
//		NTSTATUS - success or failuer code
//--

NTSTATUS OverriddenDispatchWrite (
		IN PDEVICE_OBJECT	pDevObj,
		IN PIRP				pIrp			) {
#if DBG>=1
	DbgPrint("HIFILTER: Write Operation requested (DispatchWrite)\n");
#endif
	
	PDEVICE_EXTENSION pFilterExt = (PDEVICE_EXTENSION)
			pDevObj->DeviceExtension;

	PIO_STACK_LOCATION pIrpStack =
			IoGetCurrentIrpStackLocation( pIrp );

	PIO_STACK_LOCATION pNextIrpStack =
			IoGetNextIrpStackLocation( pIrp );

	ULONG maxTransfer =
			pFilterExt->bufferInfo.MaxWriteLength;

	ULONG bytesRequested =
			pIrpStack->Parameters.Write.Length;

	// We can handle the request for 0 bytes ourselves
	if (bytesRequested == 0) {
		pIrp->IoStatus.Status = STATUS_SUCCESS;
		pIrp->IoStatus.Information = 0;
		IoCompleteRequest( pIrp, IO_NO_INCREMENT );
		return STATUS_SUCCESS;
	}

	// If the request is small enough for the target
	// device, just pass it thru...
	if (bytesRequested <= maxTransfer)
		return DispatchPassThru( pDevObj, pIrp );

	// Set up the next lower stack location to xfer as
	// much data as the lower level allows.
	pNextIrpStack->MajorFunction = IRP_MJ_WRITE;
	pNextIrpStack->Parameters.Write.Length = maxTransfer;

	// It turns out that the lower driver doesn't use the
	// ByteOffset field of the IRP's Parameter.Write block
	// so we use it for context storage.
	// HighPart holds the remaining transfer count.
	// LowPart holds the original buffer address. 
	pIrpStack->Parameters.Write.ByteOffset.HighPart =
			bytesRequested;
	pIrpStack->Parameters.Write.ByteOffset.LowPart =
			(ULONG) pIrp->AssociatedIrp.SystemBuffer;

	// Set up the I/O Completion routine.  Since there is
	// no external context (beyond the IRP's Parameters)
	// no context is passed to the Completion routine.
	IoSetCompletionRoutine(
				pIrp,
				WriteCompletion,
				NULL,		// no context
				TRUE, TRUE, TRUE );

	// Pass the IRP to the target
	return IoCallDriver( 
				pFilterExt->pTargetDevice,
				pIrp );
}

//++
// Function:	WriteCompletion
//
// Description:
//		Each time a partial Write completes,
//		this routine sends down another chunk.
//		suitable for the LODriver.
//		When the entire Write is complete,
//		complete the original IRP.
//
// Arguments:
//		pDevObj - Passed from I/O Manager
//		pIrp - Passed from I/O Manager
//
// Return value:
//		NTSTATUS - success or failuer code
//--
NTSTATUS WriteCompletion(
				IN PDEVICE_OBJECT pDevObj,
				IN PIRP pIrp,
				IN PVOID pContext ) {

	PDEVICE_EXTENSION pFilterExt = (PDEVICE_EXTENSION)
			pDevObj->DeviceExtension;

	PIO_STACK_LOCATION pIrpStack =
			IoGetCurrentIrpStackLocation( pIrp );

	PIO_STACK_LOCATION pNextIrpStack =
			IoGetNextIrpStackLocation( pIrp );

#if DBG>=1
	DbgPrint("HIFILTER: WriteCompletion\n");
#endif
	ULONG transferSize =
				pIrp->IoStatus.Information;

	ULONG bytesRequested =
				pIrpStack->Parameters.Write.Length;

	ULONG bytesRemaining = (ULONG)
			pIrpStack->Parameters.Write.ByteOffset.HighPart;

	ULONG maxTransfer =
			pFilterExt->bufferInfo.MaxWriteLength;

	NTSTATUS status = pIrp->IoStatus.Status;

	// If the last transfer was successful, reduce the
	// "bytesRemaining" context variable.
	if (NT_SUCCESS( status ))
		bytesRemaining -= transferSize;
	pIrpStack->Parameters.Write.ByteOffset.HighPart =
		bytesRemaining;

		// If there is still more data to transfer, do it.
	if ( NT_SUCCESS( status ) && (bytesRemaining > 0) ) {

		// Bump the buffer address to next chunk.
		pIrp->AssociatedIrp.SystemBuffer =
				(PUCHAR)pIrp->AssociatedIrp.SystemBuffer +
							transferSize;

		// Update the new transferSize:
		transferSize = bytesRemaining;
		if ( transferSize > maxTransfer )
			transferSize = maxTransfer;

		// Build the IRP stack beneath us (again)
		pNextIrpStack->MajorFunction = IRP_MJ_WRITE;

		pNextIrpStack->Parameters.Write.Length =
			transferSize;

		// Set up so we get called again:
		IoSetCompletionRoutine(
				pIrp,
				WriteCompletion,
				NULL,
				TRUE, TRUE, TRUE );

		// Now pass it down:
		IoCallDriver(
			pFilterExt->pTargetDevice,
			pIrp );

		return STATUS_MORE_PROCESSING_REQUIRED;

	} else {
		// There was either an error on the last xfer, or
		// we're done.  Either way, complete the IRP.

		// Restore the original system buffer address:
		pIrp->AssociatedIrp.SystemBuffer = (PVOID)
			pIrpStack->Parameters.Write.ByteOffset.LowPart;

		// Show the total number of bytes xfered:
		pIrp->IoStatus.Information =
			bytesRequested - bytesRemaining;

		// See if the pending mark should be bubbled:
		if ( pIrp->PendingReturned )
			IoMarkIrpPending( pIrp );

		return STATUS_SUCCESS;
	}
}


//++
// Function:	OverriddenDispatchDeviceIoControl
//
// Description:
//		Handles call from Win32 DeviceIoControl request
//
// Arguments:
//		pDevObj - Passed from I/O Manager
//		pIrp - Passed from I/O Manager
//
// Return value:
//		NTSTATUS - success or failuer code
//--

NTSTATUS OverriddenDispatchIoControl(
			IN PDEVICE_OBJECT pDevObj,
			IN PIRP pIrp ) {

	PIO_STACK_LOCATION pIrpStack =
			IoGetCurrentIrpStackLocation( pIrp );

	PBUFFER_SIZE_INFO pBufferInfo;

	// Here is the interception
	if (pIrpStack->Parameters.DeviceIoControl.IoControlCode
					== IOCTL_GET_MAX_BUFFER_SIZE ) {
		// The buffer passed by the user (by mutual
		// agreement) is treated as BUFFER_SIZE_INFO type.
		pBufferInfo = (PBUFFER_SIZE_INFO)
			pIrp->AssociatedIrp.SystemBuffer;
		pBufferInfo->MaxWriteLength = NO_BUFFER_LIMIT;
		pBufferInfo->MaxReadLength = NO_BUFFER_LIMIT;

		// Complete the IRP by announcing the size of
		// the returned BUFFER_SIZE_INFO information.
		pIrp->IoStatus.Information = 
				sizeof(BUFFER_SIZE_INFO);
		pIrp->IoStatus.Status = STATUS_SUCCESS;
		IoCompleteRequest( pIrp, IO_NO_INCREMENT );
		return STATUS_SUCCESS;

	} else
		// not the IOCTL we're supposed to intercept,
		// just pass it thru to the "real" device.
		return DispatchPassThru( pDevObj, pIrp );
}


⌨️ 快捷键说明

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