📄 specialiofunction.cpp
字号:
#include "FsTPM.h"
// Used to set Object's flag
#ifndef SetFlag
#define SetFlag(x,f) ((x) |= (f))
#endif
// Used to clear Object's flag
#ifndef ClearFlag
#define ClearFlag(x,f) ((x) &= ~(f))
#endif
BOOL IsSomeSpecialFile( PWCHAR WideSource, PFILE_OBJECT pFileObject, PIO_STACK_LOCATION pCurrentIrpStack)
{
if ( /*(0==pFileObject->FileName.Length) ||*/
(wcsstr(WideSource,L"SYSTEM32\\CONFIG")!=0) ||
(wcsstr(WideSource,L"NTUSER.DAT.LOG")!=0) ||
(wcsstr(WideSource,L"PAGEFILE.SYS")!=0) ||
(wcsstr(WideSource,L"NTUSER.DAT")!=0) ||
(wcsstr(WideSource,L"SECURITY.LOG")!=0) ||
(wcsstr(WideSource,L"SOFTWARE.LOG")!=0) ||
(wcsstr(WideSource,L"SYSTEM.LOG")!=0) ||
(wcsstr(WideSource,L"DEFAULT.LOG")!=0) ||
(Is_Directory_File(pCurrentIrpStack->Parameters.Create.Options))
)
{
return TRUE;
}
return FALSE;
}
VOID
FsTPMGetFileStandardInformation(
PFILE_OBJECT FileObject,
PFILE_STANDARD_INFORMATION StandardInformation,
PIO_STATUS_BLOCK IoStatusBlock,
PDEVICE_OBJECT pDeviceObject
)
//++
// Function: FsTPMGetFileStandardInformation
//
// Description:
// Get a file's standard information
//
// Arguments:
// IN FileObject - Target file object
// OUT StandardInformation - Standard information pointer
// OUT IoStatusBlock - Point out whether this request is success.
// IN pDeviceObject - the Device below me
// Return value:
// None
//
// Notice :
// This function is provided by OSR
//--
{
PIRP irp;
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
PDEVICE_OBJECT fsdDevice=pDeviceObject;
//
// Start off on the right foot - zero the information block.
//
RtlZeroMemory(StandardInformation, sizeof(FILE_STANDARD_INFORMATION));
//
// Allocate an irp for this request. This could also come from a
// private pool, for instance.
//
irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
if (!irp) {
//
// Failure!
//
return;
}
irp->AssociatedIrp.SystemBuffer = StandardInformation;
irp->UserEvent = &event;
irp->UserIosb = IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->RequestorMode = KernelMode;
//
// Initialize the event
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Set up the I/O stack location.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION;
ioStackLocation->DeviceObject = fsdDevice;
ioStackLocation->FileObject = FileObject;
ioStackLocation->Parameters.QueryFile.Length = sizeof(FILE_STANDARD_INFORMATION);
ioStackLocation->Parameters.QueryFile.FileInformationClass = FileStandardInformation;
//
// Set the completion routine.
//
IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
//
// Send it to the FSD
//
(void) IoCallDriver(fsdDevice, irp);
//
// Wait for the I/O
//
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
//
// Done!
//
return;
}
NTSTATUS
KfcIoCompletion(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
//++
// Function: KfcIoCompletion
//
// Description:
// This routine is used to handle I/O (read OR write) completion
//
// Arguments:
// DeviceObject - not used
// Irp - the I/O operation being completed
// Context - not used
//
// Return value:
// STATUS_MORE_PROCESSING_REQUIRED
//
// Notice :
// This function is provided by OSR
//
// Notes:
// The purpose of this routine is to do "cleanup" on I/O operations
// so we don't constantly throw away perfectly good MDLs as part of
// completion processing.
//
{
//
// Copy the status information back into the "user" IOSB.
//
*Irp->UserIosb = Irp->IoStatus;
//
// Set the user event - wakes up the mainline code doing this.
// So that we can jump out of KeWaitForSingleObject() in my routine
//
KeSetEvent(Irp->UserEvent, 0, FALSE);
//
// Free the IRP now that we are done with it.
//
IoFreeIrp(Irp);
//
// We return STATUS_MORE_PROCESSING_REQUIRED because this "magic" return value
// tells the I/O Manager that additional processing will be done by this driver
// to the IRP - in fact, it might (as it is in this case) already BE done - and
// the IRP cannot be completed.
//
return STATUS_MORE_PROCESSING_REQUIRED;
}
VOID
FsTPMRead(
PFILE_OBJECT FileObject,
PLARGE_INTEGER Offset,
ULONG Length,
PMDL Mdl,
PIO_STATUS_BLOCK IoStatusBlock,
PDEVICE_OBJECT pDevice
)
//++
// Function: FsTPMRead
//
// Description:
// This routine is used to read the file object to memory discribed by MDL
//
// Arguments:
// PFILE_OBJECT FileObject,
// PLARGE_INTEGER Offset,
// ULONG Length,
// PMDL Mdl,
// PIO_STATUS_BLOCK IoStatusBlock
//
// Return value:
// None
//
// Notice :
// This function is provided by OSR
//
{
PIRP irp;
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
PDEVICE_OBJECT fsdDevice=pDevice;
//
// Set up the event we'll use.
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Allocate and build the IRP we'll be sending to the FSD.
//
irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
if (!irp) {
//
// Allocation failed, presumably due to memory allocation failure.
//
IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
IoStatusBlock->Information = 0;
}
irp->MdlAddress = Mdl;
irp->UserEvent = &event;
irp->UserIosb = IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject= FileObject;
irp->RequestorMode = KernelMode;
//
// Indicate that this is a READ operation.
//
irp->Flags = IRP_READ_OPERATION;
//
// Set up the next I/O stack location. These are the parameters
// that will be passed to the underlying driver.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_READ;
ioStackLocation->MinorFunction = 0;
ioStackLocation->DeviceObject = fsdDevice;
ioStackLocation->FileObject = FileObject;
//
// We use a completion routine to keep the I/O Manager from doing
// "cleanup" on our IRP - like freeing our MDL.
//
IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
ioStackLocation->Parameters.Read.Length = Length;
ioStackLocation->Parameters.Read.ByteOffset = *Offset;
//
// Send it on. Ignore the return code.
//
(void) IoCallDriver(fsdDevice, irp);
//
// Wait for the I/O to complete.
//
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
//
// Done. Return results are in the io status block.
//
return;
}
VOID
FsTPMSetFileAllocation(
PFILE_OBJECT FileObject,
PLARGE_INTEGER AllocationSize,
PIO_STATUS_BLOCK IoStatusBlock,
PDEVICE_OBJECT pDevice
)
//++
// Function: FsTPMSetFileAllocation
//
// Description:
// This routine sets a file's ALLOCATION size to the specified value.
// Note that this DOES NOT extend the file's EOF.
//
// Arguments:
// FileObject - the file on which to set the allocation size
// AllocationSize - the new allocation size
// IoStatusBlock - the results of this operation
//
// Return value:
// None
//
// Notice :
// This function is provided by OSR
//--
{
PIRP irp;
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
PDEVICE_OBJECT fsdDevice=pDevice;
//
// Allocate an irp for this request. This could also come from a
// private pool, for instance.
//
irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
if (!irp) {
//
// Failure!
//
return;
}
irp->AssociatedIrp.SystemBuffer = AllocationSize;
irp->UserEvent = &event;
irp->UserIosb = IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->RequestorMode = KernelMode;
//
// Initialize the event
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Set up the I/O stack location.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_SET_INFORMATION;
ioStackLocation->DeviceObject = fsdDevice;
ioStackLocation->FileObject = FileObject;
ioStackLocation->Parameters.SetFile.Length = sizeof(LARGE_INTEGER);
ioStackLocation->Parameters.SetFile.FileInformationClass = FileAllocationInformation;
ioStackLocation->Parameters.SetFile.FileObject = 0; // not used for allocation
ioStackLocation->Parameters.SetFile.AdvanceOnly = FALSE;
//
// Set the completion routine.
//
IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
//
// Send it to the FSD
//
(void) IoCallDriver(fsdDevice, irp);
//
// Wait for the I/O
//
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
//
// Done!
//
return;
}
VOID
FsTPMWrite(
PFILE_OBJECT FileObject,
PLARGE_INTEGER Offset,
ULONG Length,
PMDL Mdl,
PIO_STATUS_BLOCK IoStatusBlock,
PDEVICE_OBJECT pDevice
)
//++
// Function: FsTPMWrite
//
// Description:
// This routine is used to write to the file object from memory discribed by MDL
//
// Arguments:
// PFILE_OBJECT FileObject,
// PLARGE_INTEGER Offset,
// ULONG Length,
// PMDL Mdl,
// PIO_STATUS_BLOCK IoStatusBlock
//
// Return value:
// None
//
// Notice :
// This function is provided by OSR
//
{
PIRP irp;
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
PDEVICE_OBJECT fsdDevice =pDevice;
//
// Set up the event we'll use.
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Allocate and build the IRP we'll be sending to the FSD.
//
irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
if (!irp) {
//
// Allocation failed, presumably due to memory allocation failure.
//
IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
IoStatusBlock->Information = 0;
}
irp->MdlAddress = Mdl;
irp->UserEvent = &event;
irp->UserIosb = IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject= FileObject;
irp->RequestorMode = KernelMode;
//
// Indicate that this is a WRITE operation.
//
irp->Flags = IRP_WRITE_OPERATION;
//
// Set up the next I/O stack location. These are the parameters
// that will be passed to the underlying driver.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_WRITE;
ioStackLocation->MinorFunction = 0;
ioStackLocation->DeviceObject = fsdDevice;
ioStackLocation->FileObject = FileObject;
//
// We use a completion routine to keep the I/O Manager from doing
// "cleanup" on our IRP - like freeing our MDL.
//
IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
ioStackLocation->Parameters.Write.Length = Length;
ioStackLocation->Parameters.Write.ByteOffset = *Offset;
//
// Send it on. Ignore the return code.
//
(void) IoCallDriver(fsdDevice, irp);
//
// Wait for the I/O to complete.
//
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
//
// Done. Return results are in the io status block.
//
return;
}
//-----------------------------------------------------------------------------
/*++
The following functions
Abstract:
This module implements routines to support synchronous API calls to
the next lower file system driver.
Revision History:
02-01-2002 : created
Note:
Thank OSR and Mr. Paul for providing some useful information
--*/
VOID FsTPMReferenceDeviceAndVpb(IN PFILE_OBJECT FileObject)
{
// NTSTATUS Status;
PDEVICE_OBJECT RealDevice;
PVPB Vpb;
//
// Copy RealDevice and Vpb into local variables to make things easier.
//
RealDevice = FileObject->DeviceObject;
Vpb = FileObject->Vpb;
//ASSERT(Vpb != NULL ? RealDevice->Vpb != NULL : RealDevice->Vpb == NULL);
//
// Increment RealDevice's reference count.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -