Remove Windows registry hive files from CBT

This commit is contained in:
Martin 2020-05-10 13:02:01 +02:00
parent 8b32769b88
commit 9728fa5f89
3 changed files with 124 additions and 2 deletions

View File

@ -6178,6 +6178,55 @@ bool IndexThread::normalizeVolume(std::string & volume)
}
bool IndexThread::finishCbt(std::string volume, int shadow_id, std::string snap_volume, bool for_image_backup)
inline int64 roundDown(int64 numToRound, int64 multiple)
{
return ((numToRound / multiple) * multiple);
}
bool IndexThread::addFileToCbt(const std::string& fpath, const DWORD& blocksize, const PURBCT_BITMAP_DATA& bitmap_data)
{
std::auto_ptr<IFsFile> hive_file(Server->openFile(fpath, MODE_READ));
if (hive_file.get() != nullptr)
{
bool ret = true;
bool more_exts = true;
int64 offset = 0;
while (more_exts)
{
std::vector<IFsFile::SFileExtent> exts = hive_file->getFileExtents(offset, blocksize, more_exts);
for (size_t j = 0; j < exts.size(); ++j)
{
for (int64 k = roundDown(exts[j].volume_offset, URBT_BLOCKSIZE);
k < exts[j].volume_offset + exts[j].size; k += URBT_BLOCKSIZE)
{
int64 block = k / URBT_BLOCKSIZE;
int64 bitmap_byte_wmagic = block / 8;
int64 real_block_size = bitmap_data->SectorSize - URBT_MAGIC_SIZE;
int64 bitmap_byte = (bitmap_byte_wmagic / real_block_size)
* bitmap_data->SectorSize + URBT_MAGIC_SIZE + bitmap_byte_wmagic % real_block_size;
unsigned int bitmap_bit = block % 8;
if (bitmap_byte >= bitmap_data->BitmapSize)
{
VSSLog("Registry hive extent outside of cbt data", LL_WARNING);
ret = false;
}
else
{
bitmap_data->Bitmap[bitmap_byte] |= (1 << bitmap_bit);
}
}
}
}
return ret;
}
else
{
return false;
}
}
{
#ifdef _WIN32
ScopedUnlockCbtMutex unlock_cbt_mutex;
@ -6269,7 +6318,18 @@ bool IndexThread::finishCbt(std::string volume, int shadow_id, std::string snap_
{
BytesPerSector = alignmentDescr.BytesPerPhysicalSector;
}
DWORD sectors_per_cluster;
DWORD bytes_per_sector;
DWORD NumberOfFreeClusters;
DWORD TotalNumberOfClusters;
b = GetDiskFreeSpaceW((Server->ConvertToWchar(volume) + L"\\").c_str(), &sectors_per_cluster, &bytes_per_sector, &NumberOfFreeClusters, &TotalNumberOfClusters);
if (!b)
{
VSSLog("Error in GetDiskFreeSpaceW. "+os_last_error_str(), LL_ERROR);
return false;
}
DWORD blocksize = bytes_per_sector * sectors_per_cluster;
ULONGLONG bitmapBlocks = lengthInfo.Length.QuadPart / URBT_BLOCKSIZE + (lengthInfo.Length.QuadPart%URBT_BLOCKSIZE == 0 ? 0 : 1);
@ -6501,6 +6561,62 @@ bool IndexThread::finishCbt(std::string volume, int shadow_id, std::string snap_
}
}
if (!snap_volume.empty())
{
HKEY profile_list;
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
Server->ConvertToWchar("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList").c_str(),
0, KEY_READ, &profile_list) == ERROR_SUCCESS)
{
wchar_t buf[300];
for (DWORD i = 0; RegEnumKeyW(profile_list, i, buf, sizeof(buf) == ERROR_SUCCESS); ++i)
{
DWORD rsize = sizeof(buf) * sizeof(wchar_t);
if (RegGetValueW(profile_list, std::wstring(buf).c_str(), L"ProfileImagePath",
RRF_RT_REG_SZ, NULL, buf, &rsize) == ERROR_SUCCESS)
{
std::string profile_path = Server->ConvertFromWchar(buf);
if (next(profile_path, 0, volume))
{
profile_path.erase(0, volume.size());
addFileToCbt(snap_volume + profile_path + "\\NTUSER.DAT", blocksize, bitmap_data);
for (size_t n = 1; n < 100; ++n)
{
if (!addFileToCbt(snap_volume + profile_path + "\\ntuser.dat.LOG"+convert(n), blocksize, bitmap_data))
break;
}
}
}
}
RegCloseKey(profile_list);
}
if (strlower(volume) == "c:")
{
char* locations[] = { "\\Windows\\System32\\config\\SYSTEM",
"\\Windows\\System32\\config\\SOFTWARE",
"\\Windows\\System32\\config\\SECURITY",
"\\Windows\\System32\\config\\SAM",
"\\Windows\\System32\\config\\DEFAULT" };
for (size_t i = 0; i < sizeof(locations) / sizeof(locations[0]); ++i)
{
std::string loc = locations[i];
addFileToCbt(snap_volume + loc, blocksize, bitmap_data);
for (size_t n = 1; n < 100; ++n)
{
if (!addFileToCbt(snap_volume + loc +"LOG" + convert(n), blocksize, bitmap_data))
break;
}
}
}
}
if (for_image_backup)
{
if (!saveMergeBitmap("urbackup\\hdat_file_" + conv_filename(strlower(volume)) + ".cbt", bitmap_data))

View File

@ -310,6 +310,11 @@ struct SQueueRef
}
};
#ifdef _WIN32
struct _URBCT_BITMAP_DATA;
typedef struct _URBCT_BITMAP_DATA* PURBCT_BITMAP_DATA;
#endif
class IndexThread : public IThread, public IFileServ::IReadErrorCallback, public IDeregisterFileSrvScriptFn
{
public:
@ -461,6 +466,7 @@ private:
void removeUnconfirmedVssDirs();
std::string expandPath(BSTR pathStr);
void removeBackupcomReferences(IVssBackupComponents *backupcom);
bool addFileToCbt(const std::string& fpath, const DWORD& blocksize, const PURBCT_BITMAP_DATA& bitmap_data);
#else
bool start_shadowcopy_lin( SCDirs * dir, std::string &wpath, bool for_imagebackup, bool * &onlyref, bool* not_configured);
std::string get_snapshot_script_location(const std::string& name);

View File

@ -40,7 +40,7 @@ void ClientDAO::prepareQueries()
{
q_get_files=db->Prepare("SELECT data, num, generation FROM files WHERE name=? AND tgroup=?", false);
q_add_files=db->Prepare("INSERT OR REPLACE INTO files (name, tgroup, num, data) VALUES (?,?,?,?)", false);
q_get_dirs=db->Prepare("SELECT name, path, id, optional, tgroup, symlinked, server_default, reset_keep FROM backupdirs", false);
q_get_dirs=db->Prepare("SELECT name, path, id, optional, tgroup, symlinked, server_default, reset_keep FROM backupdirs ORDER BY id ASC", false);
q_remove_all=db->Prepare("DELETE FROM files", false);
q_get_changed_dirs=db->Prepare("SELECT id, name FROM mdirs WHERE name GLOB ? UNION SELECT id, name FROM mdirs_backup WHERE name GLOB ?", false);
q_modify_files=db->Prepare("UPDATE files SET data=?, num=?, generation=? WHERE name=? AND tgroup=? AND generation=?", false);