📄 filespy.c
字号:
ASSERT(IS_FILESPY_DEVICE_OBJECT( DeviceObject ));
UNREFERENCED_PARAMETER( DeviceObject );
//
// If the specified debug level is set, output what operation
// we are seeing to the debugger.
//
if (FlagOn( gFileSpyDebugLevel, SPYDEBUG_TRACE_IRP_OPS )) {
SpyDumpIrpOperation( FALSE, Irp );
}
//
// If we are to SYNC back to the dispatch routine, signal the event
// and return
//
if (FlagOn(recordList->Flags,RLFL_SYNC_TO_DISPATCH)) {
KeSetEvent( recordList->WaitEvent, IO_NO_INCREMENT, FALSE );
//
// When syncing back to the dispatch routine do not propagate the
// IRP_PENDING flag.
//
return STATUS_MORE_PROCESSING_REQUIRED;
}
//
// Do completion log processing
//
SpyLogIrpCompletion( Irp, recordList );
//
// Propagate the IRP pending flag.
//
if (Irp->PendingReturned) {
IoMarkIrpPending( Irp );
}
return STATUS_SUCCESS;
}
NTSTATUS
SpyDispatch (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This function completes all requests on the gControlDeviceObject
(FileSpy's device object) and passes all other requests on to the
SpyPassThrough function.
Arguments:
DeviceObject - Pointer to device object Filespy attached to the file system
filter stack for the volume receiving this I/O request.
Irp - Pointer to the request packet representing the I/O request.
Return Value:
If this is a request on the gControlDeviceObject, STATUS_SUCCESS
will be returned unless the device is already attached. In that case,
STATUS_DEVICE_ALREADY_ATTACHED is returned.
If this is a request on a device other than the gControlDeviceObject,
the function will return the value of SpyPassThrough().
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
//
// File systems should NEVER receive power IRPs
//
ASSERT(irpStack->MajorFunction != IRP_MJ_POWER);
if (DeviceObject == gControlDeviceObject) {
//
// If the specified debug level is set, output what operation
// we are seeing to the debugger.
//
if (FlagOn( gFileSpyDebugLevel, SPYDEBUG_TRACE_IRP_OPS )) {
SpyDumpIrpOperation( TRUE, Irp );
}
//
// A request is being made on our control device object
//
Irp->IoStatus.Information = 0;
switch (irpStack->MajorFunction) {
case IRP_MJ_DEVICE_CONTROL:
//
// This is a private device control IRP for our control device.
// Pass the parameter information along to the common routine
// use to service these requests.
//
// All of FileSpy's IOCTLs are buffered, therefore both the
// input and output buffer are represented by the
// Irp->AssociatedIrp.SystemBuffer.
//
status = SpyCommonDeviceIoControl( Irp->AssociatedIrp.SystemBuffer,
irpStack->Parameters.DeviceIoControl.InputBufferLength,
Irp->AssociatedIrp.SystemBuffer,
irpStack->Parameters.DeviceIoControl.OutputBufferLength,
irpStack->Parameters.DeviceIoControl.IoControlCode,
&Irp->IoStatus );
break;
case IRP_MJ_CLEANUP:
//
// This is the cleanup that we will see when all references
// to a handle opened to FileSpy's control device object are
// cleaned up. We don't have to do anything here since we
// wait until the actual IRP_MJ_CLOSE to clean up the name
// cache. Just complete the IRP successfully.
//
status = STATUS_SUCCESS;
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
}
Irp->IoStatus.Status = status;
//
// We have completed all processing for this IRP, so tell the
// I/O Manager. This IRP will not be passed any further down
// the stack since no drivers below FileSpy care about this
// I/O operation that was directed to FileSpy.
//
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;
}
return SpyPassThrough( DeviceObject, Irp );
}
NTSTATUS
SpyCreate (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the routine that is associated with IRP_MJ_CREATE IRP. If the
DeviceObject is the ControlDevice, we do the creation work for the
ControlDevice and complete the IRP. Otherwise, we pass through
this IRP for another device to complete.
Note: Some of the code in this function duplicates the functions
SpyDispatch and SpyPassThrough, but a design decision was made that
it was worth the code duplication to break out the IRP handlers
that can be pageable code.
Arguments:
DeviceObject - Pointer to device object Filespy attached to the file system
filter stack for the volume receiving this I/O request.
Irp - Pointer to the request packet representing the I/O request.
Return Value:
If DeviceObject == gControlDeviceObject, then this function will
complete the Irp and return the status of that completion. Otherwise,
this function returns the result of calling SpyPassThrough.
--*/
{
NTSTATUS status;
// KIRQL oldIrql;
PFILESPY_DEVICE_EXTENSION DevExt = (PFILESPY_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = IrpSp->FileObject;
PFILE_OBJECT RelatedFileObject = FileObject->RelatedFileObject;
PNAME_CONTROL newName = NULL;
BOOLEAN cacheName;
NAME_LOOKUP_FLAGS LookupFlags = 0x00000000;
PUNICODE_STRING nameToUse;
USHORT Length = 0;
BOOLEAN NeedEncrypt = FALSE;
//PFILE_CONTEXT FileCtxPtr = NULL;
BOOLEAN DeleteOnClose = (BOOLEAN) (IrpSp->Parameters.Create.Options & FILE_DELETE_ON_CLOSE);
BOOLEAN IsEncryptFlagExist = FALSE;
BOOLEAN IsNeedEncrypt = FALSE;
PWSTR FileName = NULL;
//
// See if they want to open the control device object for the filter.
// This will only allow one thread to have this object open at a time.
// All other requests will be failed.
//
if (DeviceObject == gControlDeviceObject) {
//
// If the specified debug level is set, output what operation
// we are seeing to the debugger.
//
/*
if (FlagOn( gFileSpyDebugLevel, SPYDEBUG_TRACE_IRP_OPS )) {
SpyDumpIrpOperation( TRUE, Irp );
}
*/
//
// A CREATE request is being made on our gControlDeviceObject.
// See if someone else has it open. If so, disallow this open.
//
/*
KeAcquireSpinLock( &gControlDeviceStateLock, &oldIrql );
if (gControlDeviceState != CLOSED) {
Irp->IoStatus.Status = STATUS_DEVICE_ALREADY_ATTACHED;
Irp->IoStatus.Information = 0;
} else {
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
gControlDeviceState = OPENED;
}
KeReleaseSpinLock( &gControlDeviceStateLock, oldIrql );
//
// Since this is our gControlDeviceObject, we complete the
// IRP here.
//
status = Irp->IoStatus.Status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;
*/
Irp->IoStatus.Status = STATUS_SUCCESS; //修改
Irp->IoStatus.Information = FILE_OPENED; //修改
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
ASSERT( IS_FILESPY_DEVICE_OBJECT( DeviceObject ) );
if (FsRtlIsPagingFile( FileObject ))
{
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->NLExtHeader.AttachedToDeviceObject, Irp);
}
//
// We only care about volume filter device object
//
if (!DevExt->NLExtHeader.StorageStackDeviceObject)
{
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->NLExtHeader.AttachedToDeviceObject, Irp);
}
if (IrpSp->Parameters.Create.Options & FILE_OPEN_BY_FILE_ID)
{
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->NLExtHeader.AttachedToDeviceObject, Irp);
}
if (FlagOn(Irp->Flags, IRP_PAGING_IO))
{
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->NLExtHeader.AttachedToDeviceObject, Irp);
}
if ((FileObject->FileName.Length == 0) && !RelatedFileObject)
{
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->NLExtHeader.AttachedToDeviceObject, Irp);
}
if (FlagOn( IrpSp->Flags, SL_OPEN_TARGET_DIRECTORY ))
{
//
// The file's parent directory should be opened
//
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->NLExtHeader.AttachedToDeviceObject, Irp);
//SetFlag( LookupFlags, NLFL_OPEN_TARGET_DIR );
}
if (FlagOn( IrpSp->Flags, FILE_DIRECTORY_FILE ))
{
//
// The file's parent directory should be opened
//
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->NLExtHeader.AttachedToDeviceObject, Irp);
//SetFlag( LookupFlags, NLFL_OPEN_TARGET_DIR );
}
if (KernelMode == Irp->RequestorMode)
{
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DevExt->NLExtHeader.AttachedToDeviceObject, Irp);
}
// If DosName has been set, indicate via flags that we
// want to use it when getting the full file name.
//
if (DevExt->NLExtHeader.DosName.Length != 0) {
SetFlag( LookupFlags, NLFL_USE_DOS_DEVICE_NAME );
}
//
// Indicate we are in pre-create
//
SetFlag( LookupFlags, NLFL_IN_CREATE );
status = NLAllocateNameControl( &newName, &gFileSpyNameBufferLookasideList );
if (NT_SUCCESS( status ))
{
status = NLGetFullPathName( FileObject,
newName,
&DevExt->NLExtHeader,
LookupFlags | NLFL_USE_DOS_DEVICE_NAME,
&gFileSpyNameBufferLookasideList,
&cacheName );
nameToUse = &newName->Name;
FileName = nameToUse->Buffer;
//RtlCopyMemory(FileName, nameToUse->Buffer, nameToUse->Length);
SfIsFileNeedEncrypt( DeviceObject,nameToUse->Buffer,&NeedEncrypt);
if(NeedEncrypt)
{
Length =nameToUse->Length;
KdPrint(("SFilter!SfCreate: %ws\n",nameToUse->Buffer));
}
}
/*
FileCtxPtr = ExAllocatePoolWithTag(PagedPool, sizeof(FILE_CONTEXT), FILESPY_POOL_TAG);
if (FileCtxPtr == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
}
if (NT_SUCCESS(status) && (STATUS_REPARSE != status) && SfIsObjectFile(FileObject))
{
PFILE_CONTEXT FileCtxPtr2 = NULL;
BOOLEAN NewElement = FALSE;
FileCtxPtr->FsContext = FileObject->FsContext;
ExAcquireFastMutex(&DevExt->FsCtxTableMutex);
FileCtxPtr2 = RtlLookupElementGenericTable(&DevExt->FsCtxTable, FileCtxPtr);
if (FileCtxPtr2)
++FileCtxPtr2->RefCount;
else
{
FileCtxPtr2 = RtlInsertElementGenericTable(
&DevExt->FsCtxTable,
FileCtxPtr,
sizeof(FILE_CONTEXT),
&NewElement
);
FileCtxPtr2->RefCount = 1;
ASSERT(FileName);
wcscpy(FileCtxPtr2->Name, FileName);
FileCtxPtr2->DecryptOnRead = FALSE;
FileCtxPtr2->EncryptOnWrite = FALSE;
FileCtxPtr2->EncryptFlagExist = FALSE;
FileCtxPtr2->NeedEncrypt = FALSE;
FileCtxPtr2->IsCanCompress = FALSE;
KeInitializeEvent(&FileCtxPtr2->Event, SynchronizationEvent, TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -