NTSTATUS NPInstanceSetup ( __in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_SETUP_FLAGS Flags, __in DEVICE_TYPE VolumeDeviceType, __in FLT_FILESYSTEM_TYPE VolumeFilesystemType ) { NTSTATUS status = STATUS_SUCCESS; PVOLUME_CONTEXT context = NULL; ULONG retLen; UCHAR volPropBuffer[sizeof(FLT_VOLUME_PROPERTIES)+512]; PFLT_VOLUME_PROPERTIES volProp = (PFLT_VOLUME_PROPERTIES)volPropBuffer; PDEVICE_OBJECT devObj = NULL; UNREFERENCED_PARAMETER( Flags ); UNREFERENCED_PARAMETER( VolumeDeviceType ); UNREFERENCED_PARAMETER( VolumeFilesystemType ); PAGED_CODE(); PT_DBG_PRINT( PTDBG_TRACE_ROUTINES, ("minifilter1!NPInstanceSetup: Entered\n") ); try { // Allocate a volume context structure. status = FltAllocateContext( FltObjects->Filter, FLT_VOLUME_CONTEXT, sizeof(VOLUME_CONTEXT), NonPagedPool, &context ); if( !NT_SUCCESS(status) ) leave; // Get the volume properties, so I can get a sector size status = FltGetVolumeProperties( FltObjects->Volume, volProp, sizeof(volPropBuffer), &retLen ); if( !NT_SUCCESS(status) ) leave; // Get sector size ASSERT((volProp->SectorSize == 0) || (volProp->SectorSize >= MIN_SECTOR_SIZE)); context->SectorSize = max(volProp->SectorSize, MIN_SECTOR_SIZE); // Get device object, so I can get disk name context->Name.Buffer = NULL; status = FltGetDiskDeviceObject( FltObjects->Volume, &devObj ); if( !NT_SUCCESS(status) ) leave; status = IoVolumeDeviceToDosName( devObj, &context->Name); if( !NT_SUCCESS(status) ) leave; // Set the context status = FltSetVolumeContext( FltObjects->Volume, FLT_SET_CONTEXT_KEEP_IF_EXISTS, context, NULL ); DbgPrint("minifilter1!NPInstanceSetup: [%wZ 0x%04x/0x%04x]\n", &context->Name, context->SectorSize, volProp->SectorSize); DbgPrint("[%wZ - %wZ - %wZ]\n", &volProp->FileSystemDriverName, &volProp->FileSystemDeviceName, &volProp->RealDeviceName); if (status == STATUS_FLT_CONTEXT_ALREADY_DEFINED ) { status = STATUS_SUCCESS; } } finally { // Always release the context. If the set failed, it will free the // context. If not, it will remove the reference added by the set. // Note that the name buffer in the context will get freed by the // NPCleanupVolumeContext() routine. if(context) FltReleaseContext( context ); if(devObj) ObDereferenceObject( devObj ); } return status; }
NTSTATUS PtInstanceSetup ( __in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_SETUP_FLAGS Flags, __in DEVICE_TYPE VolumeDeviceType, __in FLT_FILESYSTEM_TYPE VolumeFilesystemType ) { PDEVICE_OBJECT devObj = NULL; PVOLUME_CONTEXT ctx = NULL; PFILE_FS_SIZE_INFORMATION VolumeBuffer = NULL; NTSTATUS status = STATUS_SUCCESS; ULONG retLen; PUNICODE_STRING workingName; USHORT size; IO_STATUS_BLOCK IoStatus; UCHAR volPropBuffer[sizeof(FLT_VOLUME_PROPERTIES)+512]; PFLT_VOLUME_PROPERTIES volProp = (PFLT_VOLUME_PROPERTIES)volPropBuffer; PAGED_CODE(); UNREFERENCED_PARAMETER( Flags ); UNREFERENCED_PARAMETER( VolumeDeviceType ); UNREFERENCED_PARAMETER( VolumeFilesystemType ); try { //我们在卷上下文中保存扇区大小跟一个资源,用卷上下文完成vcb的工作 status = FltAllocateContext( FltObjects->Filter, FLT_VOLUME_CONTEXT, sizeof(VOLUME_CONTEXT), NonPagedPool, &ctx ); if (!NT_SUCCESS(status)) { leave; } status = FltGetVolumeProperties( FltObjects->Volume, volProp, sizeof(volPropBuffer), &retLen ); if (!NT_SUCCESS(status)) { leave; } ASSERT((volProp->SectorSize == 0) || (volProp->SectorSize >= MIN_SECTOR_SIZE)); if(volProp->SectorSize > MAX_SECTOR_SIZE) { DbgPrint("不支持这么大的扇区的磁盘 %d \n",volProp->SectorSize ); status = STATUS_UNSUCCESSFUL; leave; } ctx->SectorSize = max(volProp->SectorSize ,MIN_SECTOR_SIZE); ctx->VolResource = X70FsdAllocateResource(); ctx->DeviceType = volProp->DeviceType; VolumeBuffer = FltAllocatePoolAlignedWithTag(FltObjects->Instance,NonPagedPool,sizeof(FILE_FS_SIZE_INFORMATION),'clu'); if(VolumeBuffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; leave; } status = FltQueryVolumeInformation( FltObjects->Instance, &IoStatus, VolumeBuffer, sizeof(FILE_FS_SIZE_INFORMATION), FileFsSizeInformation ); if (NT_SUCCESS(status)) { ctx->SectorsPerAllocationUnit = VolumeBuffer->SectorsPerAllocationUnit; } else { ctx->SectorsPerAllocationUnit = 1; //网络设备会返回失败。 } FltIsVolumeWritable(FltObjects->Volume,&ctx->IsWritable ); status = FltSetVolumeContext( FltObjects->Volume, FLT_SET_CONTEXT_KEEP_IF_EXISTS, ctx, NULL ); if (status == STATUS_FLT_CONTEXT_ALREADY_DEFINED) { status = STATUS_SUCCESS; } } finally { if (ctx != NULL) { FltReleaseContext( ctx ); } if(VolumeBuffer != NULL) { FltFreePoolAlignedWithTag(FltObjects->Instance,VolumeBuffer,'clu'); } } return status; }
__checkReturn NTSTATUS FLTAPI InstanceSetup ( __in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_SETUP_FLAGS Flags, __in DEVICE_TYPE VolumeDeviceType, __in FLT_FILESYSTEM_TYPE VolumeFilesystemType ) { NTSTATUS status = STATUS_UNSUCCESSFUL; PInstanceContext pInstanceCtx = NULL; PVolumeContext pVolumeContext = NULL; UNREFERENCED_PARAMETER( Flags ); ASSERT( FltObjects->Filter == gFileMgr.m_FileFilter ); if ( FLT_FSTYPE_RAW == VolumeFilesystemType) { return STATUS_FLT_DO_NOT_ATTACH; } if ( FILE_DEVICE_NETWORK_FILE_SYSTEM == VolumeDeviceType ) { return STATUS_FLT_DO_NOT_ATTACH; } __try { status = FltAllocateContext( gFileMgr.m_FileFilter, FLT_INSTANCE_CONTEXT, sizeof( InstanceContext ), NonPagedPool, (PFLT_CONTEXT*) &pInstanceCtx ); if ( !NT_SUCCESS( status ) ) { pInstanceCtx = NULL; __leave; } RtlZeroMemory( pInstanceCtx, sizeof( InstanceContext ) ); status = FltAllocateContext( gFileMgr.m_FileFilter, FLT_VOLUME_CONTEXT, sizeof( VolumeContext ), NonPagedPool, (PFLT_CONTEXT*) &pVolumeContext ); if ( !NT_SUCCESS( status ) ) { pVolumeContext = NULL; __leave; } RtlZeroMemory( pVolumeContext, sizeof( VolumeContext ) ); // just for fun pInstanceCtx->m_VolumeDeviceType = VolumeDeviceType; pInstanceCtx->m_VolumeFilesystemType = VolumeFilesystemType; status = FillVolumeProperties( FltObjects, pVolumeContext ); if ( !NT_SUCCESS( status ) ) { __leave; } ASSERT( VolumeDeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM ); VERDICT Verdict = VERDICT_NOT_FILTERED; if ( gFileMgr.m_FltSystem->IsFiltersExist() ) { VolumeInterceptorContext event( FltObjects, pInstanceCtx, pVolumeContext, VOLUME_MINIFILTER, OP_VOLUME_ATTACH, 0, PostProcessing ); PARAMS_MASK params2user; status = gFileMgr.m_FltSystem->FilterEvent( &event, &Verdict, ¶ms2user ); if ( NT_SUCCESS( status ) && FlagOn( Verdict, VERDICT_ASK ) ) { status = ChannelAskUser( &event, params2user, &Verdict ); if ( NT_SUCCESS( status ) ) { } } } status = FltSetInstanceContext( FltObjects->Instance, FLT_SET_CONTEXT_KEEP_IF_EXISTS, pInstanceCtx, NULL ); pVolumeContext->m_Instance = FltObjects->Instance; status = FltSetVolumeContext( FltObjects->Volume, FLT_SET_CONTEXT_KEEP_IF_EXISTS, pVolumeContext, NULL ); } __finally { ReleaseContext( (PFLT_CONTEXT*) &pInstanceCtx ); ReleaseContext( (PFLT_CONTEXT*) &pVolumeContext ); } return STATUS_SUCCESS; }