在windows中,如果一个文件以独占的方式被打开了,一般来讲,别的应用程序就不能再打开这个文件了,但是如果要备份这个文件,怎么办呢?
一般有两种方法来处理。
第一种方法:
使用VSS,这也是微软推荐备份的方法,对该文件所在的卷做volume snapshot, 就可以从VSS里面读取该文件内容了。关于VSS编程开发相关信息,可以参考微软文档。
第二种方法:
可以在内核中比如mini filter中打开这个文件,然后将文件的handle传到应用层,应用层就可以使用这个handle去读文件内容了。
比如内核程序打开这个被占用的文件代码如下:
NTSTATUS
GetFileHandleByFileName(
IN PUNICODE_STRING FullFileName,
OUT PHANDLE Handle
)
{
HANDLE FileHandle = NULL;
PFILE_OBJECT FileObject = NULL;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatus;
InitializeObjectAttributes(
&ObjectAttributes,
FullFileName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
NTSTATUS status = FltCreateFileEx(
gFilterHandle,
NULL,
&FileHandle,
&FileObject,
GENERIC_READ,
&ObjectAttributes,
&IoStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY ,
NULL,
0,
IO_IGNORE_SHARE_ACCESS_CHECK
);
PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, ("SSMF:GetFileHandleByFileName open the file status is status=%08x\n", status));
if (NT_SUCCESS(status) && FileObject)
{
status = ObOpenObjectByPointer(
FileObject,
0,
0,
GENERIC_READ,
*IoFileObjectType,
UserMode,
Handle
);
PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, ("SSMF:ObOpenObjectByPointer open the file (%p) status is status=%08x\n", Handle,status));
}
if (FileHandle)
FltClose(FileHandle);
if (FileObject)
ObDereferenceObject(FileObject);
return status;
}