利用镜像热备份保护文件
2017-11-26
引言:系统总有崩溃的时候,为降低文件丢失的风险,把重要的大量文件及时备份到另一个磁盘是一项不错的选择。近期勒索病毒爆发引起了全球再聚焦信息安全问题。如何尽量增强硬盘中文档的安全性,笔者提出一种简单、实用也很高效的镜像热备份方案,并且备份是隐藏的。
每个人的计算机都存有许多的文档资料,有的已成为重要资产,特别是办公用计算机更是如此。一般用户每隔数年总会因为系统软件、硬件故障或其他原因而迁移文档资料,如果所在分区的磁盘发生故障则文件丢失。如果遇到类似勒索病毒的破坏情况会更糟,重要的文档资料都将丢失。为此,本文提出一种具有镜像热备份功能,且将备份目的分区隐藏的方案。
镜像备份:备份源区和目标区的文件名和目录结构完全一致,便于直观比较,方便用户定位要找的文件。
热备份:备份过程在后台自动进行。用户可认为备份不存在,正常在源区读写文件,不影响用户操作机器。
即时备份:备份程序扫描源区的时间间隔2秒。
隐藏备份:在程序控制下,备份目标区只在需要复制文件时短暂可见,平时隐藏,所在分区不能被访问,最大限度保证备份文件安全。
基本思路
为保证正常备份,F:分区的文件不宜太大,应保证能在5分钟内复制完毕。设置扫描源分区(F:)时间间隔为2秒。扫描只关心近5分钟内修改过的文件,如果存在这样的文件则进一步比较W:分区是否存在完全一样的文件,不存在则复制文件。复制结束后,用DeleteVolumeMount PointA("W:\")函数删除W:分区挂载点,则W:分区隐藏不可用,阻止通过系统访问备份文件。平时W:分区一直隐藏,只有F:分区发现有5分钟内修改过的文件才通过SetVolumeMountPoi ntA("W:\",szVolumeName)使W:分区临时取消隐藏而可用。在很大程度防止了恶意软件或非授权人访问。
详细方案
1.以BCB为例,建新应用程序,拖放定时器Timer1,设置时间间隔2000。因用到时间函数,Unit1.cpp头文件加上#include "DateUtils.hpp"。定义3个全局变量:String Arr[50000]用于存放5分内修改过文件名的数组,最多可存5万个文件名;int P=0用于数组指针;char szVolumeName[MAX_PATH]=""用于存放W:分区内部标识符。自定义2个函数 :Find_File(String) 用于遍历F:分区,Copy_File(String)用于复制文件。
2.Form1窗体过程
OnShow()过程:
void __fastcallTForm1::FormShow(TObject*Sender)
{ GetVolumeNameForVo lumeMountPointA("W:\",s zVolumeName,MAX_PATH);//获取W:的内部分区标识,存入szVolumeName,以便隐藏和取消隐藏W:分区的操作
ShowMessage(IntTo Str(aa)+"请手工更改目的分区符号为 W:并重启备份程序");
OnClose()过程:
程序正常关闭时取消隐藏W:分区,使W:分区可见。如果程序异常关闭,W:分区隐藏状态,则下次启动时OnShow过程提示“手工更改目的分区符号为W:”。
3.定时器过程
首先,定时器暂停,Arr[]指针P复位,开始扫描F:分区。Find_File("F:")返回后,如果P<1,说明没有需复制的文件,隐藏W:分区,重启定时器并返回。如果P≥1,可能有需复制的文件,取消W:分区的隐藏,移动P逐个查找W:分区中是否存在Arr[]中对应的文件。存在则比较文件写入时间与系统时间的差值,小于120秒是刚刚复制过的文件放弃复制,大于120秒的进行复制。如果不存在对应文件,则进行复制。复制完毕将Arr[]中对应的值清空。Arr[]队列处理结束后,再隐藏W:分区,重启定时器。
4.Find_File(String)过程
本过程通过递归运算遍历F:分区所有文件,如果文件5分钟内被修改过,说明文件已更新,可能需要复制备份。将这些文件装入队列Arr[],P的值就是文件数量。遍历完毕等复制过程。注意一定要过滤“..”目录,否则递归进入死循环。
5.Copy_File(String)过程
本过程使用标准SHFIL EOPSTRUCT文件复制代码,较简单。需说明复制前修改Arr[]中文件的路径,以保证镜像复制,代码为:from=AnsiString(File_Path);to="w:"+File_Path.SubString(3,File_Path.Length());为不干扰用户正常工作,在后台复制,复制时不显示对话框,对已存在文件覆盖复制,自动新建不存目录,不显示复制进度,需设置fFlags参数。代码为:fFlags=FOF_NOERRORUI |FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR |FOF_SILENT。