📄 driver.cpp
字号:
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 + -