/*--------------------------------------------------------- 函数名称: FileSetOffset 函数描述: 重新设置文件偏移 用于读取数据后修复 输入参数: pfiInstance 过滤器实例 pfoFileObject 文件对象 pnFileOffset 文件偏移 输出参数: 返回值: 其他: 更新维护: 2011.7.17 最初版本 ---------------------------------------------------------*/ NTSTATUS FileSetOffset( __in PFLT_INSTANCE pfiInstance, __in PFILE_OBJECT pfoFileObject, __in PLARGE_INTEGER pnFileOffset ) { FILE_POSITION_INFORMATION fpiPosition; LARGE_INTEGER nOffset; // //先把偏移量拷贝出来 再设置 // nOffset.QuadPart = pnFileOffset->QuadPart; nOffset.LowPart = pnFileOffset->LowPart; fpiPosition.CurrentByteOffset = nOffset; return FltSetInformationFile(pfiInstance, pfoFileObject, &fpiPosition, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation ) ; }
/*--------------------------------------------------------- 函数名称: FileSetSize 函数描述: 非重入设置文件大小 输入参数: pfiInstance 过滤器实例 pfoFileObject 文件对象 pnFileSize 文件大小 输出参数: 返回值: STATUS_SUCCESS 成功 否则返回相应状态 其他: 更新维护: 2011.4.3 最初版本 使用IRP 2011.4.9 修改为使用FltXXX版本 ---------------------------------------------------------*/ NTSTATUS FileSetSize( __in PFLT_INSTANCE pfiInstance, __in PFILE_OBJECT pfoFileObject, __in PLARGE_INTEGER pnFileSize ) { // //直接设置文件信息 // FILE_END_OF_FILE_INFORMATION eofInformation; eofInformation.EndOfFile.QuadPart = pnFileSize->QuadPart; return FltSetInformationFile( pfiInstance, pfoFileObject, (PVOID)&eofInformation, sizeof(FILE_END_OF_FILE_INFORMATION), FileEndOfFileInformation ); }
NTSTATUS File_SetFileSize( __in PFLT_CALLBACK_DATA Data, __in PFLT_RELATED_OBJECTS FltObjects, __in PLARGE_INTEGER FileSize ) { NTSTATUS status = STATUS_SUCCESS ; FILE_END_OF_FILE_INFORMATION EndOfFile; PFSRTL_COMMON_FCB_HEADER Fcb = (PFSRTL_COMMON_FCB_HEADER)FltObjects->FileObject->FsContext ;; EndOfFile.EndOfFile.QuadPart = FileSize->QuadPart; EndOfFile.EndOfFile.LowPart = FileSize->LowPart; //修改为向下层Call status = FltSetInformationFile(FltObjects->Instance, FltObjects->FileObject, &EndOfFile, sizeof(FILE_END_OF_FILE_INFORMATION), FileEndOfFileInformation ) ; return status; }
NTSTATUS File_SetFileOffset( __in PFLT_CALLBACK_DATA Data, __in PFLT_RELATED_OBJECTS FltObjects, __in PLARGE_INTEGER FileOffset ) { NTSTATUS status; FILE_POSITION_INFORMATION NewPos; //修改为向下层Call LARGE_INTEGER NewOffset = {0}; NewOffset.QuadPart = FileOffset->QuadPart; NewOffset.LowPart = FileOffset->LowPart; NewPos.CurrentByteOffset = NewOffset; status = FltSetInformationFile(FltObjects->Instance, FltObjects->FileObject, &NewPos, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation ) ; return status; }
NTSTATUS LcFetchRemoteFile ( _In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ PUNICODE_STRING SourceFile, _In_ PUNICODE_STRING TargetFile, _In_ BOOLEAN UseCustomHandler, _Out_ PLARGE_INTEGER BytesCopied ) /*++ Summary: This function copies the remote file content to the current file object. In order for the remote file to be fetched, make sure that the network redirector device is used, i.e. the 'SourceFile' root points to the '\Device\Mup\<path>'. Arguments: FltObjects - Pointer to the 'FLT_RELATED_OBJECTS' data structure containing opaque handles to this filter, instance, its associated volume and file object. SourceFile - Path to the file to fetch content from. TargetFile - Path to the file to store content to. UseCustomHandler - Whether the file should be fetched by the user-mode client. BytesCopied - The amount of bytes copied. Return Value: The return value is the status of the operation. --*/ { NTSTATUS status = STATUS_SUCCESS; HANDLE sourceFileHandle = NULL; IO_STATUS_BLOCK statusBlock = { 0 }; FILE_STANDARD_INFORMATION standardInfo = { 0 }; FILE_END_OF_FILE_INFORMATION eofInfo = { 0 }; PAGED_CODE(); IF_FALSE_RETURN_RESULT(FltObjects != NULL, STATUS_INVALID_PARAMETER_1); IF_FALSE_RETURN_RESULT(SourceFile != NULL, STATUS_INVALID_PARAMETER_2); IF_FALSE_RETURN_RESULT(TargetFile != NULL, STATUS_INVALID_PARAMETER_3); IF_FALSE_RETURN_RESULT(BytesCopied != NULL, STATUS_INVALID_PARAMETER_5); FLT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); *BytesCopied = RtlConvertLongToLargeInteger(0); __try { LOG((DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "[LazyCopy] Fetching content from: '%wZ' -> '%wZ'\n", SourceFile, TargetFile)); if (UseCustomHandler) { NT_IF_FAIL_LEAVE(LcFetchFileInUserMode(SourceFile, TargetFile, BytesCopied)); } else { // // Open the source file and make sure it's not empty. // NT_IF_FAIL_LEAVE(LcOpenFile(SourceFile, TargetFile, &sourceFileHandle)); NT_IF_FAIL_LEAVE(ZwQueryInformationFile(sourceFileHandle, &statusBlock, &standardInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation)); if (standardInfo.EndOfFile.QuadPart == 0) { // No need to copy an empty file. __leave; } // Extend the target file, so all readers that wait for the content to be copied will get the actual file size information. // Remote file system may return incorrect information, but we are doing it only for the cases, when multiple threads // try to access the same file, while we are fetching it. eofInfo.EndOfFile.QuadPart = standardInfo.EndOfFile.QuadPart; NT_IF_FAIL_LEAVE(FltSetInformationFile(FltObjects->Instance, FltObjects->FileObject, &eofInfo, sizeof(eofInfo), FileEndOfFileInformation)); // // Copy source file contents into the local (target) file. // NT_IF_FAIL_LEAVE(LcFetchFileByChunks( FltObjects, sourceFileHandle, &standardInfo.EndOfFile, BytesCopied)); } } __finally { if (sourceFileHandle != NULL) { ZwClose(sourceFileHandle); } } return status; }