mirror of
https://github.com/uroni/urbackup_backend.git
synced 2025-10-26 11:36:50 +00:00
218 lines
5.7 KiB
C++
218 lines
5.7 KiB
C++
#ifndef CHANGEJOURNALWATCHER_H
|
|
#define CHANGEJOURNALWATCHER_H
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <windows.h>
|
|
#include <WinIoCtl.h>
|
|
|
|
#include "../Interface/Database.h"
|
|
#include "../Interface/Query.h"
|
|
#include "PersistentOpenFiles.h"
|
|
|
|
#include "watchdir/JournalDAO.h"
|
|
|
|
class DirectoryWatcherThread;
|
|
|
|
struct SChangeJournal
|
|
{
|
|
std::vector<std::string> path;
|
|
USN last_record;
|
|
DWORDLONG journal_id;
|
|
HANDLE hVolume;
|
|
_i64 rid;
|
|
std::string vol_str;
|
|
};
|
|
|
|
struct SDeviceInfo
|
|
{
|
|
bool has_info;
|
|
DWORDLONG journal_id;
|
|
USN last_record;
|
|
bool index_done;
|
|
};
|
|
|
|
class uint128
|
|
{
|
|
public:
|
|
uint128()
|
|
:lowPart(0), highPart(0)
|
|
{
|
|
|
|
}
|
|
|
|
explicit uint128(BYTE data[16])
|
|
{
|
|
memcpy(&lowPart, data, sizeof(lowPart));
|
|
memcpy(&highPart, data+sizeof(lowPart), sizeof(highPart));
|
|
}
|
|
|
|
explicit uint128(uint64 lowPart)
|
|
: lowPart(lowPart), highPart(0)
|
|
{
|
|
|
|
}
|
|
|
|
uint128(uint64 lowPart, uint64 highPart)
|
|
: lowPart(lowPart), highPart(highPart)
|
|
{
|
|
|
|
}
|
|
|
|
bool hasHighPart()
|
|
{
|
|
return highPart!=0;
|
|
}
|
|
|
|
bool operator==(const uint128& other)
|
|
{
|
|
return lowPart==other.lowPart &&
|
|
highPart==other.highPart;
|
|
}
|
|
|
|
bool operator!=(const uint128& other)
|
|
{
|
|
return !(*this==other);
|
|
}
|
|
|
|
void set(uint64 low, uint64 high)
|
|
{
|
|
lowPart = low;
|
|
highPart = high;
|
|
}
|
|
|
|
uint64 highPart;
|
|
uint64 lowPart;
|
|
};
|
|
|
|
struct UsnInt
|
|
{
|
|
DWORD version;
|
|
uint128 FileReferenceNumber;
|
|
uint128 ParentFileReferenceNumber;
|
|
USN Usn;
|
|
DWORD Reason;
|
|
std::string Filename;
|
|
USN NextUsn;
|
|
DWORD attributes;
|
|
};
|
|
|
|
const uint128 c_frn_root((uint64)-1, (uint64)-1);
|
|
|
|
class IChangeJournalListener;
|
|
|
|
class ChangeJournalWatcher
|
|
{
|
|
public:
|
|
ChangeJournalWatcher(DirectoryWatcherThread * dwt, IDatabase *pDB);
|
|
~ChangeJournalWatcher(void);
|
|
|
|
void watchDir(const std::string &dir);
|
|
|
|
void update(std::string vol_str="");
|
|
void update_longliving(void);
|
|
|
|
void set_freeze_open_write_files(bool b);
|
|
|
|
void set_last_backup_time(int64 t);
|
|
|
|
void add_listener(IChangeJournalListener *pListener);
|
|
|
|
private:
|
|
std::vector<IChangeJournalListener*> listeners;
|
|
std::map<std::string, SChangeJournal> wdirs;
|
|
|
|
SDeviceInfo getDeviceInfo(const std::string &name);
|
|
_i64 hasRoot(const std::string &root);
|
|
int64 addFrn(const std::string &name, uint128 parent_id, uint128 frn, _i64 rid);
|
|
void addFrnTmp(const std::string &name, uint128 parent_id, uint128 frn, _i64 rid);
|
|
void renameEntry(const std::string &name, _i64 id, uint128 pid);
|
|
void resetRoot(_i64 rid);
|
|
_i64 hasEntry( _i64 rid, uint128 frn);
|
|
std::vector<uint128> getChildren(uint128 frn, _i64 rid);
|
|
void deleteEntry(_i64 id);
|
|
void deleteEntry(uint128 frn, _i64 rid);
|
|
void saveJournalData(DWORDLONG journal_id, const std::string &vol, const UsnInt& rec, USN nextUsn);
|
|
void setIndexDone(const std::string &vol, int s);
|
|
void deleteJournalData(const std::string &vol);
|
|
void deleteJournalId(const std::string &vol);
|
|
void applySavedJournalData(const std::string &vol, SChangeJournal &cj, std::map<std::string, bool>& local_open_write_files, bool& started_transaction);
|
|
|
|
void deleteWithChildren( uint128 frn, _i64 rid, bool has_children);
|
|
std::string getFilename(const SChangeJournal &cj, uint128 frn, bool fallback_to_mft, bool& filter_error, bool& has_error);
|
|
|
|
void indexRootDirs(_i64 rid, const std::string &root, uint128 parent, size_t& nDirFrns);
|
|
void indexRootDirs2(const std::string &root, SChangeJournal *sj, bool& not_supported);
|
|
|
|
uint128 getRootFRN( const std::string & root );
|
|
|
|
void updateWithUsn(const std::string &vol, const SChangeJournal &cj, const UsnInt *UsnRecord, bool fallback_to_mft, std::map<std::string, bool>& local_open_write_files);
|
|
|
|
void reindex(_i64 rid, std::string vol, SChangeJournal *sj);
|
|
void logEntry(const std::string &vol, const UsnInt *UsnRecord);
|
|
|
|
std::string getNameFromMFTByFRN(const SChangeJournal &cj, uint128 frn, uint128& parent_frn, bool& has_error);
|
|
|
|
void hardlinkChange(const SChangeJournal &cj, const std::string& vol, uint128 frn, uint128 parent_frn, const std::string& name, bool closed);
|
|
|
|
void hardlinkDelete(const std::string& vol, uint128 frn);
|
|
|
|
void resetAll(const std::string& vol);
|
|
|
|
IDatabase *db;
|
|
|
|
IQuery *q_add_frn_tmp;
|
|
|
|
int64 last_index_update;
|
|
|
|
bool has_error;
|
|
bool indexing_in_progress;
|
|
std::string indexing_volume;
|
|
|
|
bool freeze_open_write_files;
|
|
|
|
std::map<std::string, bool> open_write_files_frozen;
|
|
|
|
std::vector<std::string> error_dirs;
|
|
|
|
DirectoryWatcherThread * dwt;
|
|
|
|
int64 last_backup_time;
|
|
|
|
JournalDAO journal_dao;
|
|
|
|
bool unsupported_usn_version_err;
|
|
|
|
std::string rename_old_name;
|
|
bool usn_logging_enabled;
|
|
|
|
size_t num_changes;
|
|
|
|
PersistentOpenFiles open_write_files;
|
|
};
|
|
|
|
class IChangeJournalListener
|
|
{
|
|
public:
|
|
virtual int64 getStartUsn(int64 sequence_id)=0;
|
|
virtual void On_FileNameChanged(const std::string & strOldFileName, const std::string & strNewFileName, bool closed)=0;
|
|
virtual void On_DirNameChanged(const std::string & strOldFileName, const std::string & strNewFileName, bool closed)=0;
|
|
virtual void On_FileRemoved(const std::string & strFileName, bool closed)=0;
|
|
virtual void On_FileAdded(const std::string & strFileName, bool closed)=0;
|
|
virtual void On_DirAdded(const std::string & strFileName, bool closed)=0;
|
|
virtual void On_FileModified(const std::string & strFileName, bool closed)=0;
|
|
virtual void On_FileOpen(const std::string & strFileName)=0;
|
|
virtual void On_ResetAll(const std::string & vol)=0;
|
|
virtual void On_DirRemoved(const std::string & strDirName, bool closed)=0;
|
|
|
|
struct SSequence
|
|
{
|
|
int64 id;
|
|
int64 start;
|
|
int64 stop;
|
|
};
|
|
|
|
virtual void Commit(const std::vector<SSequence>& sequences)=0;
|
|
};
|
|
|
|
#endif //CHANGEJOURNALWATCHER_H
|