📄 functions.c
字号:
return NtStatus;
}
/**********************************************************************
*
* ExampleFilter_Read
*
* This is called when a read is issued on the device handle (ReadFile/ReadFileEx)
*
*
**********************************************************************/
NTSTATUS ExampleFilter_Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS NtStatus = STATUS_BUFFER_TOO_SMALL;
PEXAMPLE_FILTER_EXTENSION pExampleFilterDeviceContext = (PEXAMPLE_FILTER_EXTENSION)DeviceObject->DeviceExtension;
PIO_STACK_LOCATION pIoStackIrp = NULL;
PCHAR pReadDataBuffer;
DbgPrint("ExampleFilter_Read Called \r\n");
/*
* We want to process this IRP. Our filter driver's functionality is to remove all NULL's from the
* returned strings and add one only to the end of the string returned. This ensures that if we
* return strings without NULL's that they are given NULL's and if we provide an array of NULL terminated
* strings that they are all displayed. This is essentially the functionality we will add in this
* simple example.
*
* When we want to process an IRP after we pass it down we need to do two things the first is we need to
* call IoCopyCurrentIrpStackLocationToNext() and set a completetion routine.
*/
pIoStackIrp = IoGetCurrentIrpStackLocation(Irp);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) ExampleFilter_CompletionRoutine, NULL, TRUE, TRUE, TRUE);
/*
* IoCallDriver() simply calls the appropriate entry point in the driver object associated
* with the device object. This is how drivers are basically "chained" together, they must know
* that there are lower driver so they can perform the appropriate action and send down the IRP.
*
* They do not have to send the IRP down they could simply process it completely themselves if they wish.
*/
NtStatus = IoCallDriver(pExampleFilterDeviceContext->pNextDeviceInChain, Irp);
/*
* Please note that our implementation here is a simple one. We do not take into account PENDING IRP's or
* anything complicated. We assume that once we get to this locaiton the IRP has already been completed and
* our completetion routine was called or it wasn't completed and we are still able to complete it here.
*
* Our completetion routine makes sure that the IRP is still valid here.
*
*/
if(NT_SUCCESS(NtStatus))
{
/*
* Data was read?
*/
if(Irp->IoStatus.Information)
{
/*
* Our filter device is dependent upon the compliation settings of how we compiled example.sys
* That means we need to dynamically figure out if we're using Direct, Buffered or Neither.
*/
if(DeviceObject->Flags & DO_BUFFERED_IO)
{
DbgPrint("ExampleFilter_Read - Use Buffered I/O \r\n");
/*
* Implementation for Buffered I/O
*/
pReadDataBuffer = (PCHAR)Irp->AssociatedIrp.SystemBuffer;
if(pReadDataBuffer && pIoStackIrp->Parameters.Read.Length > 0)
{
ExampleFilter_FixNullString(pReadDataBuffer, (UINT)Irp->IoStatus.Information);
}
}
else
{
if(DeviceObject->Flags & DO_DIRECT_IO)
{
DbgPrint("ExampleFilter_Read - Use Direct I/O \r\n");
/*
* Implementation for Direct I/O
*/
if(pIoStackIrp && Irp->MdlAddress)
{
pReadDataBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
if(pReadDataBuffer && pIoStackIrp->Parameters.Read.Length)
{
ExampleFilter_FixNullString(pReadDataBuffer, (UINT)Irp->IoStatus.Information);
}
}
}
else
{
DbgPrint("ExampleFilter_Read - Use Neither I/O \r\n");
/*
* Implementation for Neither I/O
*/
__try {
if(pIoStackIrp->Parameters.Read.Length > 0 && Irp->UserBuffer)
{
ProbeForWrite(Irp->UserBuffer, pIoStackIrp->Parameters.Read.Length, TYPE_ALIGNMENT(char));
pReadDataBuffer = Irp->UserBuffer;
ExampleFilter_FixNullString(pReadDataBuffer, (UINT)Irp->IoStatus.Information);
}
} __except( EXCEPTION_EXECUTE_HANDLER ) {
NtStatus = GetExceptionCode();
}
}
}
}
}
/*
* Complete the IRP
*
*/
Irp->IoStatus.Status = NtStatus;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DbgPrint("ExampleFilter_Read Exit 0x%0x \r\n", NtStatus);
return NtStatus;
}
/**********************************************************************
*
* ExampleFilter_UnSupportedFunction
*
* This is called when a major function is issued that isn't supported.
*
**********************************************************************/
NTSTATUS ExampleFilter_UnSupportedFunction(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS NtStatus = STATUS_NOT_SUPPORTED;
PEXAMPLE_FILTER_EXTENSION pExampleFilterDeviceContext = (PEXAMPLE_FILTER_EXTENSION)DeviceObject->DeviceExtension;
DbgPrint("ExampleFilter_UnSupportedFunction Called \r\n");
/*
* We do not want to process this IRP, we simply want to send it down to the next driver.
* We use IoSkipCurrentIrpStackLocation() since we do not want to set a completion routine.
*
* We should not complete this IRP! Once we pass it down we must forget about it.
*/
IoSkipCurrentIrpStackLocation(Irp);
/*
* IoCallDriver() simply calls the appropriate entry point in the driver object associated
* with the device object. This is how drivers are basically "chained" together, they must know
* that there are lower driver so they can perform the appropriate action and send down the IRP.
*
* They do not have to send the IRP down they could simply process it completely themselves if they wish.
*/
NtStatus = IoCallDriver(pExampleFilterDeviceContext->pNextDeviceInChain, Irp);
DbgPrint("ExampleFilter_UnSupportedFunction Exit 0x%0x \r\n", NtStatus);
return NtStatus;
}
/**********************************************************************
*
* ExampleFilter_CompletionRoutine
*
* This is called when an IRP has been completed (IoCompleteRequest)
*
**********************************************************************/
NTSTATUS ExampleFilter_CompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
DbgPrint("ExampleFilter_CompletionRoutine Called \r\n");
/*
* We need to return "STATUS_MORE_PROCESSING_REQUIRED" so that we can use the IRP in our driver.
* If we complete this here we would not be able to use it and the IRP would be completed. This
* also means that our driver must also complete the IRP since it has not been completed yet.
*/
return STATUS_MORE_PROCESSING_REQUIRED;
}
/**********************************************************************
*
* ExampleFilter_FixNullString
*
* This function will simply fix the NULL in the returned string.
* This is a very simple implementation for demonstration purposes.
*
**********************************************************************/
NTSTATUS ExampleFilter_FixNullString(PCHAR pString, UINT uiSize)
{
NTSTATUS NtStatus = STATUS_SUCCESS;
UINT uiIndex = 0;
while(uiIndex < (uiSize - 1))
{
if(pString[uiIndex] == 0)
{
pString[uiIndex] = ' ';
}
uiIndex++;
}
/*
* Fix the end NULL
*/
pString[uiIndex] = 0;
return NtStatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -