DriverEntry

 

NTSTATUS
DriverEntry (
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
 
/*++
    // 创建设备对象且登记它监视所有的活动文件系统
--*/
{
    PFAST_IO_DISPATCH fastIoDispatch;
    UNICODE_STRING nameString;
    NTSTATUS status;
    ULONG i;
 
#if WINVER >= 0x0501
    //  试图载入动态函数
    SfLoadDynamicFunctions();
    //  得到 OS 版本
    SfGetCurrentVersion();
#endif
 
    //  得到注册表值
    SfReadDriverParameters( RegistryPath );
 
    //  保存我们的驱动对象,设置我们的 UNLOAD 例程
    gSFilterDriverObject = DriverObject;
 
#if DBG && WINVER >= 0x0501
    //  如果我们可以枚举我们驱动拥有的显著的设备对象,仅支持测试环境的卸载
    //  卸载只用于开发环境
if (NULL != gSfDynamicFunctions.EnumerateDeviceObjectList)
{
        gSFilterDriverObject->DriverUnload = DriverUnload;
    }
#endif
    // 初始化一个资源变量,可被用于同步一线程集合,
         // 在释放资源占用内存前调用 ExDeleteResourceLite
 
         status = ExInitializeResourceLite(&gRulesResource);
         if (!NT_SUCCESS(status))
         {
                   KdPrint(("SFilter!DriverEntry: ExInitializeResourceLite failed, Status=%08x/n", status));
                   return status;
         }
 
         // SystemRoot 目录的 xefs.dat 中检索匹配规则
         //
         status = SfLoadRules(&gRuleFileHandle);
         if (!NT_SUCCESS(status))
         {
                   ExDeleteResourceLite(&gRulesResource);
                   KdPrint(("SFilter!DriverEntry: SfLoadRules failed, Status=%08x/n", status));
                   return status;
         }
 
         //  设置其它全局变量
    ExInitializeFastMutex( &gSfilterAttachLock );
 
    // #define FSCTX_GENERIC_TABLE_POOL_SIZE                   sizeof(FILE_CONTEXT) + 32
         ExInitializePagedLookasideList(
                   &gFsCtxLookAsideList,
                   NULL,
                   NULL,
                   0,
                   FSCTX_GENERIC_TABLE_POOL_SIZE,
                   SFLT_POOL_TAG_MYSELF,
                   0
                   );
                  
         ExInitializePagedLookasideList(
                   &gFileContextLookAsideList,
                   NULL,
                   NULL,
                   0,
                   sizeof(FILE_CONTEXT),
                   SFLT_POOL_TAG_MYSELF,
                   0
                   );
 
         ExInitializePagedLookasideList(
                   &gFileNameLookAsideList,
                   NULL,
                   NULL,
                   0,
                   MAX_PATH * sizeof(WCHAR),
                   SFLT_POOL_TAG_MYSELF,
                   0
                   );
 
         ExInitializeNPagedLookasideList(
                   &gReadWriteCompletionCtxLookAsideList,
                   NULL,
                   NULL,
                   0,
                   sizeof(READ_WRITE_COMPLETION_CONTEXT),
                   SFLT_POOL_TAG_MYSELF,
                   0
                   );
 
         //  初始化用于名字缓冲的后视列表。避免在堆栈上有一个大名字缓冲。它也被名字查找例程使用 (NLxxx)
    // Initialize the lookaside list for name buffering. This is used in
    // several places to avoid having a large name buffer on the stack. It is
    // also needed by the name lookup routines (NLxxx).
    //
 
    ExInitializePagedLookasideList( &gSfNameBufferLookasideList,
                                    NULL,
                                    NULL,
                                    0,
                                    SFILTER_LOOKASIDE_SIZE,
                                    SFLT_POOL_TAG_NAME_BUFFER,
                                    0 );
 
    //  创建控制设备对象,这个对象代表这个驱动。注意它没有设备扩展。
    RtlInitUnicodeString( &nameString, L"//FileSystem//Filters//SFilterCDO" );
    status = IoCreateDevice( DriverObject,
                             0,                      //has no device extension
                             &nameString,
                             FILE_DEVICE_DISK_FILE_SYSTEM,
                             FILE_DEVICE_SECURE_OPEN,
                             FALSE,
                             &gSFilterControlDeviceObject );
    if (status == STATUS_OBJECT_PATH_NOT_FOUND) {
 
        // XP 以前的版本名字空间中未加入 Filters 路径,所以将我们的控制设备对象放入
        //  对象名字空间的 /FileSystem 部分
        RtlInitUnicodeString( &nameString, L"//FileSystem//SFilterCDO" );
        status = IoCreateDevice( DriverObject,
                                 0,                  //has no device extension
                                 &nameString,
                                 FILE_DEVICE_DISK_FILE_SYSTEM,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &gSFilterControlDeviceObject );
 
        if (!NT_SUCCESS( status ))
{
            KdPrint( ("SFilter!DriverEntry: Error creating control device object /"%wZ/", status=%08x/n",
                    &nameString,
                    status ));
            return status;
        }
} else if (!NT_SUCCESS( status ))
{
 
        KdPrint(( "SFilter!DriverEntry: Error creating control device object /"%wZ/", status=%08x/n",
                &nameString, status ));
        return status;
}
 
    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
 
        DriverObject->MajorFunction[i] = SfPassThrough;
    }
    DriverObject->MajorFunction[IRP_MJ_CREATE] = SfCreate;
    DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = SfCreate;
    DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = SfCreate;
 
    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = SfFsControl;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = SfCleanupClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = SfCleanupClose;
DriverObject->MajorFunction[IRP_MJ_READ] = SfRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = SfWrite;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = SfDirectoryControl;
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = SfSetInformation;
 
 
    //  分配快速 I/O 数据结构且填入它
    //  由于历史的原因,这些快速 IO 不发送到过滤驱动,而是直接发送到基础文件系统。
    //  WINXP 及以后版本,如果你想拦截这些回调,你可以使用新的系统例程 FsRtlRegisterFileSystemFilterCallbacks
    fastIoDispatch = ExAllocatePoolWithTag( NonPagedPool,
                                            sizeof( FAST_IO_DISPATCH ),
                                            SFLT_POOL_TAG_FASTIO );
if (!fastIoDispatch)
{
        IoDeleteDevice( gSFilterControlDeviceObject );
        return STATUS_INSUFFICIENT_RESOURCES;
    }
 
    RtlZeroMemory( fastIoDispatch, sizeof( FAST_IO_DISPATCH ) );
 
    fastIoDispatch->SizeOfFastIoDispatch = sizeof( FAST_IO_DISPATCH );
    fastIoDispatch->FastIoCheckIfPossible = SfFastIoCheckIfPossible;
    fastIoDispatch->FastIoRead = SfFastIoRead;
    fastIoDispatch->FastIoWrite = SfFastIoWrite;
    fastIoDispatch->FastIoQueryBasicInfo = SfFastIoQueryBasicInfo;
    fastIoDispatch->FastIoQueryStandardInfo = SfFastIoQueryStandardInfo;
    fastIoDispatch->FastIoLock = SfFastIoLock;
    fastIoDispatch->FastIoUnlockSingle = SfFastIoUnlockSingle;
    fastIoDispatch->FastIoUnlockAll = SfFastIoUnlockAll;
    fastIoDispatch->FastIoUnlockAllByKey = SfFastIoUnlockAllByKey;
    fastIoDispatch->FastIoDeviceControl = SfFastIoDeviceControl;
    fastIoDispatch->FastIoDetachDevice = SfFastIoDetachDevice;
    fastIoDispatch->FastIoQueryNetworkOpenInfo = SfFastIoQueryNetworkOpenInfo;
    fastIoDispatch->MdlRead = SfFastIoMdlRead;
    fastIoDispatch->MdlReadComplete = SfFastIoMdlReadComplete;
    fastIoDispatch->PrepareMdlWrite = SfFastIoPrepareMdlWrite;
    fastIoDispatch->MdlWriteComplete = SfFastIoMdlWriteComplete;
    fastIoDispatch->FastIoReadCompressed = SfFastIoReadCompressed;
    fastIoDispatch->FastIoWriteCompressed = SfFastIoWriteCompressed;
    fastIoDispatch->MdlReadCompleteCompressed = SfFastIoMdlReadCompleteCompressed;
    fastIoDispatch->MdlWriteCompleteCompressed = SfFastIoMdlWriteCompleteCompressed;
    fastIoDispatch->FastIoQueryOpen = SfFastIoQueryOpen;
 
    DriverObject->FastIoDispatch = fastIoDispatch;
 
#if WINVER >= 0x0501
 
    {
        FS_FILTER_CALLBACKS fsFilterCallbacks;
 
        if (NULL != gSfDynamicFunctions.RegisterFileSystemFilterCallbacks) {
 
            //  为我们通过 FsFilter 接口接收的操作设置回调
            fsFilterCallbacks.SizeOfFsFilterCallbacks = sizeof( FS_FILTER_CALLBACKS );
            fsFilterCallbacks.PreAcquireForSectionSynchronization = SfPreFsFilterPassThrough;
            fsFilterCallbacks.PostAcquireForSectionSynchronization = SfPostFsFilterPassThrough;
            fsFilterCallbacks.PreReleaseForSectionSynchronization = SfPreFsFilterPassThrough;
            fsFilterCallbacks.PostReleaseForSectionSynchronization = SfPostFsFilterPassThrough;
            fsFilterCallbacks.PreAcquireForCcFlush = SfPreFsFilterPassThrough;
            fsFilterCallbacks.PostAcquireForCcFlush = SfPostFsFilterPassThrough;
            fsFilterCallbacks.PreReleaseForCcFlush = SfPreFsFilterPassThrough;
            fsFilterCallbacks.PostReleaseForCcFlush = SfPostFsFilterPassThrough;
            fsFilterCallbacks.PreAcquireForModifiedPageWriter = SfPreFsFilterPassThrough;
            fsFilterCallbacks.PostAcquireForModifiedPageWriter = SfPostFsFilterPassThrough;
            fsFilterCallbacks.PreReleaseForModifiedPageWriter = SfPreFsFilterPassThrough;
            fsFilterCallbacks.PostReleaseForModifiedPageWriter = SfPostFsFilterPassThrough;
 
            status = (gSfDynamicFunctions.RegisterFileSystemFilterCallbacks)( DriverObject,
&fsFilterCallbacks );
 
            if (!NT_SUCCESS( status )) {
 
                DriverObject->FastIoDispatch = NULL;
                ExFreePoolWithTag( fastIoDispatch, SFLT_POOL_TAG_FASTIO );
                IoDeleteDevice( gSFilterControlDeviceObject );
                return status;
            }
        }
    }
#endif
    //  当一个新的文件系统被装入或者当任何文件系统被卸载时,注册的回调函数
    // SfFsNotification 将被调用
 
    status = IoRegisterFsRegistrationChange( DriverObject, SfFsNotification );
if (!NT_SUCCESS( status ))
{
        KdPrint(( "SFilter!DriverEntry: Error registering FS change notification, status=%08x/n",
                status ));
        DriverObject->FastIoDispatch = NULL;
        ExFreePoolWithTag( fastIoDispatch, SFLT_POOL_TAG_FASTIO );
        IoDeleteDevice( gSFilterControlDeviceObject );
        return status;
    }
 
    //  试图附着到合适的 RAW 文件系统设备对象,因为他们没有被 IoRegisterFsRegistrationChange 枚举
    {
        PDEVICE_OBJECT rawDeviceObject;
        PFILE_OBJECT fileObject;
        //  附着到 RawDisk 设备
        RtlInitUnicodeString( &nameString, L"//Device//RawDisk" );
 
        status = IoGetDeviceObjectPointer(
                    &nameString,
                    FILE_READ_ATTRIBUTES,
                    &fileObject,
                    &rawDeviceObject );
 
        if (NT_SUCCESS( status )) {
 
            SfFsNotification( rawDeviceObject, TRUE );
            ObDereferenceObject( fileObject );
        }
        //  附着到 RawCdRom 设备
        RtlInitUnicodeString( &nameString, L"//Device//RawCdRom" );
 
        status = IoGetDeviceObjectPointer(
                    &nameString,
                    FILE_READ_ATTRIBUTES,
                    &fileObject,
                    &rawDeviceObject );
        if (NT_SUCCESS( status ))
{
 
            SfFsNotification( rawDeviceObject, TRUE );
            ObDereferenceObject( fileObject );
        }
    }
    //  清除控制设备对象上的初始化标志,因为我们现在成功完成初始化
    ClearFlag( gSFilterControlDeviceObject->Flags, DO_DEVICE_INITIALIZING );
    return STATUS_SUCCESS;
}

你可能感兴趣的:(object,File,null,System,extension,attributes)