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

📄 sfilter.c

📁 文件系统过滤驱动的详细代码,含有中文说明及注释
💻 C
📖 第 1 页 / 共 5 页
字号:
            ObDereferenceObject( devList[i] );
        }
    }

	fastIoDispatch = DriverObject->FastIoDispatch;
	DriverObject->FastIoDispatch = NULL;
	ExFreePool( fastIoDispatch );
}
#endif

//============== SfLoadDynamicFunctions函数(仅WinXP下编译该函数) =============
#if WINVER >= 0x0501
VOID  SfLoadDynamicFunctions()
{
    UNICODE_STRING functionName;
    RtlZeroMemory( &gSfDynamicFunctions, sizeof( gSfDynamicFunctions ) );		//将gSfDynamicFunctions结构变量清0

    RtlInitUnicodeString( &functionName, L"FsRtlRegisterFileSystemFilterCallbacks" );
    gSfDynamicFunctions.RegisterFileSystemFilterCallbacks = MmGetSystemRoutineAddress( &functionName );

    RtlInitUnicodeString( &functionName, L"IoAttachDeviceToDeviceStackSafe" );
    gSfDynamicFunctions.AttachDeviceToDeviceStackSafe = MmGetSystemRoutineAddress( &functionName );
    
    RtlInitUnicodeString( &functionName, L"IoEnumerateDeviceObjectList" );
    gSfDynamicFunctions.EnumerateDeviceObjectList = MmGetSystemRoutineAddress( &functionName );

    RtlInitUnicodeString( &functionName, L"IoGetLowerDeviceObject" );
    gSfDynamicFunctions.GetLowerDeviceObject = MmGetSystemRoutineAddress( &functionName );

    RtlInitUnicodeString( &functionName, L"IoGetDeviceAttachmentBaseRef" );
    gSfDynamicFunctions.GetDeviceAttachmentBaseRef = MmGetSystemRoutineAddress( &functionName );

    RtlInitUnicodeString( &functionName, L"IoGetDiskDeviceObject" );
    gSfDynamicFunctions.GetDiskDeviceObject = MmGetSystemRoutineAddress( &functionName );

    RtlInitUnicodeString( &functionName, L"IoGetAttachedDeviceReference" );
    gSfDynamicFunctions.GetAttachedDeviceReference = MmGetSystemRoutineAddress( &functionName );

    RtlInitUnicodeString( &functionName, L"RtlGetVersion" );
    gSfDynamicFunctions.GetVersion = MmGetSystemRoutineAddress( &functionName );
}
#endif

//=============== SfGetCurrentVersion函数(仅WinXP下编译该函数) ===============
#if WINVER >= 0x0501
VOID  SfGetCurrentVersion()
{
    if (NULL != gSfDynamicFunctions.GetVersion)
	{
		RTL_OSVERSIONINFOW versionInfo;
		NTSTATUS status;
		
		versionInfo.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW );
		status = (gSfDynamicFunctions.GetVersion)( &versionInfo );
		ASSERT( NT_SUCCESS( status ) );
		gSfOsMajorVersion = versionInfo.dwMajorVersion;
		gSfOsMinorVersion = versionInfo.dwMinorVersion;
	}
	else
	{
		PsGetVersion( &gSfOsMajorVersion, &gSfOsMinorVersion, NULL, NULL );
	}
}
#endif

//========================= 回调函数 ==============================
VOID  SfFsNotification( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN FsActive )
{
    UNICODE_STRING name;																			//定义结构变量
    WCHAR nameBuffer[MAX_DEVNAME_LENGTH];												//定义宽字符缓冲区,长度64

    PAGED_CODE();

	RtlInitEmptyUnicodeString( &name, nameBuffer, sizeof(nameBuffer) );			//初始化name(成员Buffer->nameBuffer,Length=0,MaximumLength=64)
	SfGetObjectName( DeviceObject, &name );													//
	SF_LOG_PRINT( SFDEBUG_DISPLAY_ATTACHMENT_NAMES,
                  ("SFilter!SfFsNotification:                    %s   %p \"%wZ\" (%s)\n",
                   (FsActive) ? "Activating file system  " : "Deactivating file system",
                   DeviceObject,
                   &name,
                   GET_DEVICE_TYPE_NAME(DeviceObject->DeviceType)) );

	if (FsActive)
	{
		SfAttachToFileSystemDevice( DeviceObject, &name );								//用于完成对文件系统控制设备的绑定
	}
	else
	{
		SfDetachFromFileSystemDevice( DeviceObject );
	}
}

//======================== IRP 处理函数 ============================
NTSTATUS  SfPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
	ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ));
	ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
	IoSkipCurrentIrpStackLocation( Irp );
	return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
}

VOID  SfDisplayCreateFileName( IN PIRP Irp )
{
	PIO_STACK_LOCATION irpSp;
	PUNICODE_STRING name;
	GET_NAME_CONTROL nameControl;
	
	irpSp = IoGetCurrentIrpStackLocation( Irp );
	name = SfGetFileName( irpSp->FileObject, Irp->IoStatus.Status, &nameControl );
	if (irpSp->Parameters.Create.Options & FILE_OPEN_BY_FILE_ID)
	{
		SF_LOG_PRINT( SFDEBUG_DISPLAY_CREATE_NAMES,
                      ("SFilter!SfDisplayCreateFileName: Opened %08x:%08x %wZ (FID)\n", 
                       Irp->IoStatus.Status,
                       Irp->IoStatus.Information,
                       name) );
	}
	else
	{
		SF_LOG_PRINT( SFDEBUG_DISPLAY_CREATE_NAMES,
                      ("SFilter!SfDisplayCreateFileName: Opened %08x:%08x %wZ\n", 
                       Irp->IoStatus.Status,
                       Irp->IoStatus.Information,
                       name) );
	}
	
	SfGetFileNameCleanup( &nameControl );
}

NTSTATUS  SfCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
    NTSTATUS status;

    PAGED_CODE();
	
	if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
	{
		Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
		Irp->IoStatus.Information = 0;
		IoCompleteRequest( Irp, IO_NO_INCREMENT );
		return STATUS_INVALID_DEVICE_REQUEST;
	}
	
	ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
	
	if (!FlagOn( SfDebug, SFDEBUG_DO_CREATE_COMPLETION | SFDEBUG_GET_CREATE_NAMES| SFDEBUG_DISPLAY_CREATE_NAMES ))
	{
		IoSkipCurrentIrpStackLocation( Irp );
		return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
	}
	else
	{
		KEVENT waitEvent;
		KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );
		IoCopyCurrentIrpStackLocationToNext( Irp );
		IoSetCompletionRoutine( Irp,
								SfCreateCompletion,
								&waitEvent,
								TRUE,
								TRUE,
								TRUE );
		status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
		if (STATUS_PENDING == status)
		{
			NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL);
			ASSERT(STATUS_SUCCESS == localStatus);
		}
		
		ASSERT(KeReadStateEvent(&waitEvent) || !NT_SUCCESS(Irp->IoStatus.Status));
		if (FlagOn(SfDebug, (SFDEBUG_GET_CREATE_NAMES|SFDEBUG_DISPLAY_CREATE_NAMES)))
		{
			SfDisplayCreateFileName( Irp );
		}
		status = Irp->IoStatus.Status;
		IoCompleteRequest( Irp, IO_NO_INCREMENT );
		return status;
	}
}

NTSTATUS  SfCreateCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context )
{
    PKEVENT event = Context;

    UNREFERENCED_PARAMETER( DeviceObject );
    UNREFERENCED_PARAMETER( Irp );

    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));

    KeSetEvent(event, IO_NO_INCREMENT, FALSE);

    return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS  SfCleanupClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
    PAGED_CODE();
    ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ));
    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
    IoSkipCurrentIrpStackLocation( Irp );
    return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
}

NTSTATUS  SfFsControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
    PAGED_CODE();
    ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ));
    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
    switch (irpSp->MinorFunction) {

        case IRP_MN_MOUNT_VOLUME:

            return SfFsControlMountVolume( DeviceObject, Irp );

        case IRP_MN_LOAD_FILE_SYSTEM:

            return SfFsControlLoadFileSystem( DeviceObject, Irp );

        case IRP_MN_USER_FS_REQUEST:
        {
            switch (irpSp->Parameters.FileSystemControl.FsControlCode) {

                case FSCTL_DISMOUNT_VOLUME:
                {
                    PSFILTER_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;

                    SF_LOG_PRINT( SFDEBUG_DISPLAY_ATTACHMENT_NAMES,
                                  ("SFilter!SfFsControl:                         Dismounting volume         %p \"%wZ\"\n",
                                   devExt->AttachedToDeviceObject,
                                   &devExt->DeviceName) );
                    break;
                }
            }
            break;
        }
    }        

    IoSkipCurrentIrpStackLocation( Irp );
    return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
}

NTSTATUS  SfFsControlCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context )
{
    UNREFERENCED_PARAMETER( DeviceObject );
    UNREFERENCED_PARAMETER( Irp );

    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
    ASSERT(Context != NULL);

#if WINVER >= 0x0501
    if (IS_WINDOWSXP_OR_LATER())
	{
		KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
	}
	else
	{
#endif
		if (KeGetCurrentIrql() > PASSIVE_LEVEL)
		{
			ExQueueWorkItem( (PWORK_QUEUE_ITEM) Context, DelayedWorkQueue );
		}
		else
		{
			PWORK_QUEUE_ITEM workItem = Context;
			(workItem->WorkerRoutine)(workItem->Parameter);
		}

#if WINVER >= 0x0501
    }
#endif

    return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS  SfFsControlMountVolume( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
    PSFILTER_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
    PDEVICE_OBJECT newDeviceObject;
    PDEVICE_OBJECT storageStackDeviceObject;
    PSFILTER_DEVICE_EXTENSION newDevExt;
    NTSTATUS status;
    BOOLEAN isShadowCopyVolume;
    PFSCTRL_COMPLETION_CONTEXT completionContext;
    

    PAGED_CODE();

    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));
    ASSERT(IS_DESIRED_DEVICE_TYPE(DeviceObject->DeviceType));
    storageStackDeviceObject = irpSp->Parameters.MountVolume.Vpb->RealDevice;
    status = SfIsShadowCopyVolume ( storageStackDeviceObject, &isShadowCopyVolume );

    if (NT_SUCCESS(status) && 
        isShadowCopyVolume &&
        !FlagOn(SfDebug,SFDEBUG_ATTACH_TO_SHADOW_COPIES)) {

        UNICODE_STRING shadowDeviceName;
        WCHAR shadowNameBuffer[MAX_DEVNAME_LENGTH];

		RtlInitEmptyUnicodeString( &shadowDeviceName, shadowNameBuffer, sizeof(shadowNameBuffer) );
        SfGetObjectName( storageStackDeviceObject, &shadowDeviceName );
        SF_LOG_PRINT( SFDEBUG_DISPLAY_ATTACHMENT_NAMES,
                      ("SFilter!SfFsControlMountVolume               Not attaching to Volume    %p \"%wZ\", shadow copy volume\n", 
                       storageStackDeviceObject,
                       &shadowDeviceName) );

		IoSkipCurrentIrpStackLocation( Irp );
        return IoCallDriver( devExt->AttachedToDeviceObject, Irp );
    }

	status = IoCreateDevice( gSFilterDriverObject,
                             sizeof( SFILTER_DEVICE_EXTENSION ),
                             NULL,
                             DeviceObject->DeviceType,
                             0,
                             FALSE,
                             &newDeviceObject );

    if (!NT_SUCCESS( status ))
	{
		KdPrint(( "SFilter!SfFsControlMountVolume: Error creating volume device object, status=%08x\n", status ));

        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = status;
        IoCompleteRequest( Irp, IO_NO_INCREMENT );

        return status;
    }

	newDevExt = newDeviceObject->DeviceExtension;
    newDevExt->StorageStackDeviceObject = storageStackDeviceObject;
    RtlInitEmptyUnicodeString( &newDevExt->DeviceName, newDevExt->DeviceNameBuffer, sizeof(newDevExt->DeviceNameBuffer) );
    SfGetObjectName( storageStackDeviceObject, &newDevExt->DeviceName );

#if WINVER >= 0x0501

    if (IS_WINDOWSXP_OR_LATER())
	{
		KEVENT waitEvent;
		KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );
        IoCopyCurrentIrpStackLocationToNext ( Irp );
        IoSetCompletionRoutine( Irp,
                                SfFsControlCompletion,
                                &waitEvent,     //context parameter
                                TRUE,
                                TRUE,
                                TRUE );
        status = IoCallDriver( devExt->AttachedToDeviceObject, Irp );
    	if (STATUS_PENDING == status) {

⌨️ 快捷键说明

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