📄 sfilter.c
字号:
typedef
NTSTATUS
(*PSF_ATTACH_DEVICE_TO_DEVICE_STACK_SAFE) (
IN PDEVICE_OBJECT SourceDevice,
IN PDEVICE_OBJECT TargetDevice,
OUT PDEVICE_OBJECT *AttachedToDeviceObject
);
typedef
PDEVICE_OBJECT
(*PSF_GET_LOWER_DEVICE_OBJECT) (
IN PDEVICE_OBJECT DeviceObject
);
typedef
PDEVICE_OBJECT
(*PSF_GET_DEVICE_ATTACHMENT_BASE_REF) (
IN PDEVICE_OBJECT DeviceObject
);
typedef
NTSTATUS
(*PSF_GET_DISK_DEVICE_OBJECT) (
IN PDEVICE_OBJECT FileSystemDeviceObject,
OUT PDEVICE_OBJECT *DiskDeviceObject
);
typedef
PDEVICE_OBJECT
(*PSF_GET_ATTACHED_DEVICE_REFERENCE) (
IN PDEVICE_OBJECT DeviceObject
);
typedef
NTSTATUS
(*PSF_GET_VERSION) (
IN OUT PRTL_OSVERSIONINFOW VersionInformation
);
typedef struct _SF_DYNAMIC_FUNCTION_POINTERS {
// 下面这些例程应该在Windows XP (5.1)及以后的操作系统可用
// The following routines should all be available on Windows XP (5.1) and
// later.
//
PSF_REGISTER_FILE_SYSTEM_FILTER_CALLBACKS RegisterFileSystemFilterCallbacks;
PSF_ATTACH_DEVICE_TO_DEVICE_STACK_SAFE AttachDeviceToDeviceStackSafe;
PSF_ENUMERATE_DEVICE_OBJECT_LIST EnumerateDeviceObjectList;
PSF_GET_LOWER_DEVICE_OBJECT GetLowerDeviceObject;
PSF_GET_DEVICE_ATTACHMENT_BASE_REF GetDeviceAttachmentBaseRef;
PSF_GET_DISK_DEVICE_OBJECT GetDiskDeviceObject;
PSF_GET_ATTACHED_DEVICE_REFERENCE GetAttachedDeviceReference;
PSF_GET_VERSION GetVersion;
} SF_DYNAMIC_FUNCTION_POINTERS, *PSF_DYNAMIC_FUNCTION_POINTERS;
SF_DYNAMIC_FUNCTION_POINTERS gSfDynamicFunctions = {0};
// 在DriverEntry中查找OS版本且存储值在这些全局变量中
// MULTIVERSION NOTE: For this version of the driver, we need to know the
// current OS version while we are running to make decisions regarding what
// logic to use when the logic cannot be the same for all platforms. We
// will look up the OS version in DriverEntry and store the values
// in these global variables.
//
ULONG gSfOsMajorVersion = 0;
ULONG gSfOsMinorVersion = 0;
// 这里是各种OS对应的主次版本号
// Here is what the major and minor versions should be for the various
// OS versions:
//
// OS Name MajorVersion MinorVersion
// ---------------------------------------------------------------------
// Windows 2000 5 0
// Windows XP 5 1
// Windows Server 2003 5 2
//
#define IS_WINDOWS2000() \
((gSfOsMajorVersion == 5) && (gSfOsMinorVersion == 0))
#define IS_WINDOWSXP() \
((gSfOsMajorVersion == 5) && (gSfOsMinorVersion == 1))
#define IS_WINDOWSXP_OR_LATER() \
(((gSfOsMajorVersion == 5) && (gSfOsMinorVersion >= 1)) || \
(gSfOsMajorVersion > 5))
#define IS_WINDOWSSRV2003_OR_LATER() \
(((gSfOsMajorVersion == 5) && (gSfOsMinorVersion >= 2)) || \
(gSfOsMajorVersion > 5))
#endif
// 标识SFilter分配内存的标记
// Tags identifying memory SFilter allocates
//
#define SFLT_POOL_TAG_FASTIO 'ifFS'
#define SFLT_POOL_TAG_MOUNTVOL 'vmFS'
#define SFLT_POOL_TAG_LOADFS 'flFS'
#define SFLT_POOL_TAG_ENUMFSVOL 'neFS'
#define SFLT_POOL_TAG_DOSNAME 'ndFS'
#define SFLT_POOL_TAG_NAME_BUFFER 'bnFS'
#define SFLT_POOL_TAG_BIGNAMEBUFFER 'nbFS'
#define SFLT_POOL_TAG_DEVNAME 'nvFS'
#define SFLT_POOL_TAG_MYSELF 'ydFS'
// 用于SFilter DbgPrint级的宏
// Macros for SFilter DbgPrint levels.
//
#define SF_LOG_PRINT( _dbgLevel, _string ) \
(FlagOn(SfDebug,(_dbgLevel)) ? \
DbgPrint _string : \
((void)0))
// 用于KeDelayExecutionThread()的延迟值,(负值代表相对时间)
// Delay values for KeDelayExecutionThread()
// (Values are negative to represent relative time)
//
#define DELAY_ONE_MICROSECOND (-10)
#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)
/////////////////////////////////////////////////////////////////////////////
//
// Global variables
//
/////////////////////////////////////////////////////////////////////////////
// 用于各种名字缓冲的后视列表
// Lookaside list for various name buffers.
//
PAGED_LOOKASIDE_LIST gSfNameBufferLookasideList;
// 因为我们总是使用这个列表分配NAME_CONTROLs,我们将使用这个作为后视列表的尺寸
// Since we always use this list to allocate NAME_CONTROLs, we will use that
// for the size of the lookaside list.
//
#define SFILTER_LOOKASIDE_SIZE sizeof( NAME_CONTROL )
// 保持用于这个驱动的驱动对象的指针
// Holds pointer to the driver object for this driver
//
PDRIVER_OBJECT gSFilterDriverObject = NULL;
// 保持代表这个驱动的且由外部程序使用存取这个驱动的设备对象的指针。这也就是所谓的"control device object"
// Holds pointer to the device object that represents this driver and is used
// by external programs to access this driver. This is also known as the
// "control device object".
//
PDEVICE_OBJECT gSFilterControlDeviceObject = NULL;
// 用于同步我们的附着到给定设备对象的锁
// 这个锁修正我们可能偶然附着到相同设备对象多次的竞争条件。这个竞争条件仅发生在
// 卷被安装的同时这个过滤器被载入。
// 这个问题当这个过滤器在任何文件系统被载入前就在启动时被载入的情况下不会发生
// 这个锁被用于自动测试是否我们已经附着到给定的设备对象且如果没有,执行附着。
// This lock is used to synchronize our attaching to a given device object.
// This lock fixes a race condition where we could accidently attach to the
// same device object more then once. This race condition only occurs if
// a volume is being mounted at the same time as this filter is being loaded.
// This problem will never occur if this filter is loaded at boot time before
// any file systems are loaded.
//
// This lock is used to atomically test if we are already attached to a given
// device object and if not, do the attach.
//
FAST_MUTEX gSfilterAttachLock;
PAGED_LOOKASIDE_LIST gFileNameLookAsideList;
PAGED_LOOKASIDE_LIST gFsCtxLookAsideList;
PAGED_LOOKASIDE_LIST gFileContextLookAsideList;
NPAGED_LOOKASIDE_LIST gReadWriteCompletionCtxLookAsideList;
UNICODE_STRING gInsufficientResourcesUnicode = CONSTANT_UNICODE_STRING(L"[-= Insufficient Resources =-]");
PRULE gRules = NULL;
ERESOURCE gRulesResource;
HANDLE gRuleFileHandle = NULL;
#define FSCTX_GENERIC_TABLE_POOL_SIZE sizeof(FILE_CONTEXT) + 32
/////////////////////////////////////////////////////////////////////////////
//
// Debug Definitions
//
/////////////////////////////////////////////////////////////////////////////
// 显示我们附着到的设备对象的名字
// Display names of device objects we attach to.
//
#define SFDEBUG_DISPLAY_ATTACHMENT_NAMES 0x00000001
// 得到文件名(在创建期间)且显示他们(创建完成)
// Get file names (during create) and display them (create completion).
//
#define SFDEBUG_DISPLAY_CREATE_NAMES 0x00000002
// 得到文件名但不显示他们(在创建期间)
// Get file names but don't display them (during create).
//
#define SFDEBUG_GET_CREATE_NAMES 0x00000004
// 执行创建完成例程,忽略名字显示
// Do create completion routine, regardless of name display.
//
#define SFDEBUG_DO_CREATE_COMPLETION 0x00000008
// 执行附着到FSRecognizer设备对象
// Do attach to FSRecognizer device objects.
//
#define SFDEBUG_ATTACH_TO_FSRECOGNIZER 0x00000010
// 执行附着到ShadowCopy卷设备对象--他们仅在Windows XP及以后OS发生
// Do attach to ShadowCopy Volume device objects -- they are only around on
// Windows XP and later.
//
#define SFDEBUG_ATTACH_TO_SHADOW_COPIES 0x00000020
// 执行得到和使用DOS设备名字用于文件名的显示
// Do get and use DOS device names for file name display.
//
#define SFDEBUG_GET_DOS_NAMES 0x00000040
// 在清除/关闭时间显示信息
// Display information at cleanup/close time
//
#define SFDEBUG_DISPLAY_CLEANUPCLOSE_NAMES 0x00000080
// 保持调试状态的全局变量
// Global which holds debug state
//
ULONG SfDebug = 0;
// 给出一个设备类型,返回一个有效名字
// Given a device type, return a valid name.
//
#define GET_DEVICE_TYPE_NAME( _type ) \
((((_type) > 0) && \
((_type) < (sizeof(DeviceTypeNames) / sizeof(PCHAR)))) ? \
DeviceTypeNames[ (_type) ] : \
"[Unknown]")
// 已知设备类姓名
// Known device type names.
//
static const PCHAR DeviceTypeNames[] = {
"",
"BEEP",
"CD_ROM",
"CD_ROM_FILE_SYSTEM",
"CONTROLLER",
"DATALINK",
"DFS",
"DISK",
"DISK_FILE_SYSTEM",
"FILE_SYSTEM",
"INPORT_PORT",
"KEYBOARD",
"MAILSLOT",
"MIDI_IN",
"MIDI_OUT",
"MOUSE",
"MULTI_UNC_PROVIDER",
"NAMED_PIPE",
"NETWORK",
"NETWORK_BROWSER",
"NETWORK_FILE_SYSTEM",
"NULL",
"PARALLEL_PORT",
"PHYSICAL_NETCARD",
"PRINTER",
"SCANNER",
"SERIAL_MOUSE_PORT",
"SERIAL_PORT",
"SCREEN",
"SOUND",
"STREAMS",
"TAPE",
"TAPE_FILE_SYSTEM",
"TRANSPORT",
"UNKNOWN",
"VIDEO",
"VIRTUAL_DISK",
"WAVE_IN",
"WAVE_OUT",
"8042_PORT",
"NETWORK_REDIRECTOR",
"BATTERY",
"BUS_EXTENDER",
"MODEM",
"VDM",
"MASS_STORAGE",
"SMB",
"KS",
"CHANGER",
"SMARTCARD",
"ACPI",
"DVD",
"FULLSCREEN_VIDEO",
"DFS_FILE_SYSTEM",
"DFS_VOLUME",
"SERENUM",
"TERMSRV",
"KSEC"
};
/////////////////////////////////////////////////////////////////////////////
//
// Function Prototypes
//
/////////////////////////////////////////////////////////////////////////////
//
// Define driver entry routine.
//
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
#if DBG && WINVER >= 0x0501
VOID
DriverUnload(
IN PDRIVER_OBJECT DriverObject
);
#endif
// 定义由这个驱动模块使用的局部例程。这包括一个如何过滤一个创建文件操作的例子,
// 且然后当文件已经成功被创建/打开时调用一个I/O完成例程
// Define the local routines used by this driver module. This includes a
// a sample of how to filter a create file operation, and then invoke an I/O
// completion routine when the file has successfully been created/opened.
//
#if WINVER >= 0x0501
VOID
SfLoadDynamicFunctions (
VOID
);
VOID
SfGetCurrentVersion (
VOID
);
#endif
NTSTATUS
SfPassThrough (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
SfCreate (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
SfPostCreateWorker(
IN PVOID Context
);
NTSTATUS
SfCreateCompletion (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
NTSTATUS
SfCleanupClose (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
SfRead(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
SfReadCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
NTSTATUS
SfWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
SfWriteCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -