Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Block Clone允许多个文件共享一个物理区块

Block Clone允许多个文件共享一个物理区块

原创
作者头像
用户7737280
发布于 2024-08-28 02:25:55
发布于 2024-08-28 02:25:55
14600
代码可运行
举报
运行总次数:0
代码可运行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <atlbase.h>
#include <windows.h>
#include <winioctl.h>
#include <crtdbg.h>
#include <CLocale>


constexpr LONG64 inline ROUNDUP(LONG64 file_size, ULONG cluster_size) noexcept
{
	return (file_size + cluster_size - 1) / cluster_size * cluster_size;
}


BOOL CreateForkW(HANDLE hSrc, HANDLE hDst)
{
	DWORD fs_flags;

	if (!GetVolumeInformationByHandleW(hSrc, NULL, 0, NULL, NULL, &fs_flags, NULL, 0))
	{
		return FALSE;
	}
	if (!(fs_flags & FILE_SUPPORTS_BLOCK_REFCOUNTING))
	{
		SetLastError(ERROR_NOT_CAPABLE);
		return FALSE;
	}

	FILE_END_OF_FILE_INFO file_size;
	if (!GetFileSizeEx(hSrc, &file_size.EndOfFile))
	{
		return FALSE;
	}

	FILE_BASIC_INFO file_basic;
	if (!GetFileInformationByHandleEx(hSrc, FileBasicInfo, &file_basic, sizeof file_basic)) 
	{
		return FALSE;
	}
	DWORD _;
	FSCTL_GET_INTEGRITY_INFORMATION_BUFFER get_integrity;
	if (!DeviceIoControl(hSrc, FSCTL_GET_INTEGRITY_INFORMATION, nullptr, 0, &get_integrity, sizeof get_integrity, &_, nullptr))
	{
		return FALSE;
	}


	FILE_DISPOSITION_INFO dispos = { TRUE };
	if (!SetFileInformationByHandle(hDst, FileDispositionInfo, &dispos, sizeof dispos))
	{
		return FALSE;
	}

	if (!DeviceIoControl(hDst, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &_, NULL))
	{
		return FALSE;
	}
	FSCTL_SET_INTEGRITY_INFORMATION_BUFFER set_integrity = { get_integrity.ChecksumAlgorithm, get_integrity.Reserved, get_integrity.Flags };
	if (!DeviceIoControl(hDst, FSCTL_SET_INTEGRITY_INFORMATION, &set_integrity, sizeof set_integrity, nullptr, 0, nullptr, nullptr))
	{
		return FALSE;
	}
	if (!SetFileInforma www.laipuhuo.com tionByHandle(hDst, FileEndOfFileInfo, &file_size, sizeof file_size))
	{
		return FALSE;
	}

	const LONG64 split_threshold = (1LL << 32) - get_integrity.ClusterSizeInBytes;

	DUPLICATE_EXTENTS_DATA dup_extent;
	dup_extent.FileHandle = hSrc;
	for (LONG64 offset = 0, remain = ROUNDUP(file_size.EndOfFile.QuadPart, get_integrity.ClusterSizeInBytes); remain > 0; offset += split_threshold, remain -= split_threshold)
	{
		dup_extent.SourceFileOffset.QuadPart = dup_extent.TargetFileOffset.QuadPart = offset;
		dup_extent.ByteCount.QuadPart = min(split_threshold, remain);
		_ASSERTE(dup_extent.SourceFileOffset.QuadPart % get_integrity.ClusterSizeInBytes == 0);
		_ASSERTE(dup_extent.ByteCount.QuadPart % get_integrity.ClusterSizeInBytes == 0);
		_ASSERTE(dup_extent.ByteCount.QuadPart <= UINT32_MAX);
		_RPT3(_CRT_WARN, "Remain=%llx\nOffset=%llx\nLength=%llx\n\n", remain, dup_extent.SourceFileOffset.QuadPart, dup_extent.ByteCount.QuadPart);
		if (!DeviceIoControl(hDst, FSCTL_DUPLICATE_EXTENTS_TO_FILE, &dup_extent, sizeof dup_extent, nullptr, 0, &_, nullptr))
		{
			_CrtDbgBreak();
			return FALSE;
		}
	}

	if (!(file_basic.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE))
	{
		FILE_SET_SPARSE_BUFFER set_sparse = { FALSE };
		if (!DeviceIoControl(hDst, FSCTL_SET_SPARSE, &set_sparse, sizeof set_sparse, nullptr, 0, &_, nullptr))
		{
			return FALSE;
		}
	}

	file_basic.CreationTime.QuadPart = 0;
	if (!SetFileInformationByHandle(hDst, FileBasicInfo, &file_basic, sizeof file_basic))
	{
		return FALSE;
	}
	if (!FlushFileBuffers(hDst))
	{
		return FALSE;
	}
	dispos = { FALSE };
	return !!SetFileInformationByHandle(hDst, FileDispositionInfo, &dispos, sizeof dispos);
}

BOOL CreateForkForFileW(www.laipuhuo.com LPCWSTR SrcFile, LPCWSTR DstFile)
{
#ifdef DEBUG
	_putws(SrcFile);
#endif // DEBUG

	// Judge both files are in the same volume
	WCHAR src_volume[MAX_PATH], dst_volume[MAX_PATH];
	if (GetVolumePathNameW(SrcFile, src_volume, MAX_PATH) == 0 || GetVolumePathNameW(DstFile, dst_volume, MAX_PATH) == 0)
	{
		return FALSE;
	}
	if (lstrcmpiW(src_volume, dst_volume) != 0)
	{
		SetLastError(ERROR_NOT_SAME_DEVICE);
		return FALSE;
	}

	HANDLE hSrc = CreateFileW(SrcFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
	if (hSrc == INVALID_HANDLE_VALUE)
	{
		CloseHandle(hSrc);
		return FALSE;
	}
	HANDLE hDst = CreateFileW(DstFile, GENERIC_READ | GENERIC_WRITE | DELETE, 0, nullptr, CREATE_NEW, 0, hSrc);
	if (hDst == INVALID_HANDLE_VALUE)
	{
		SetLastError(ERROR_FILE_EXISTS);
		CloseHandle(hDst);
		CloseHandle(hSrc);
		return FALSE;
	}
	BOOL ret = CreateForkW(hSrc, hDst);
	CloseHandle(hDst);
	CloseHandle(hSrc);
	return ret;
}

BOOL CreateForkForDirW(LPCWSTR SrcDir, LPCWSTR DstDir)
{
	// Judge SrcDir is a directory
	DWORD attr = GetFileAttributesW(SrcDir);
	if (attr == www.laipuhuo.com INVALID_FILE_ATTRIBUTES || !(attr & FILE_ATTRIBUTE_DIRECTORY))
	{
		return FALSE;
	}

	// Judge both directories are in the same volume
	WCHAR src_volume[MAX_PATH], dst_volume[MAX_PATH];
	if (GetVolumePathNameW(SrcDir, src_volume, MAX_PATH) == 0 || GetVolumePathNameW(DstDir, dst_volume, MAX_PATH) == 0)
	{
		return FALSE;
	}
	if (lstrcmpiW(src_volume, dst_volume) != 0)
	{
		SetLastError(ERROR_NOT_SAME_DEVICE);
		return FALSE;
	}

	HANDLE hSrc = CreateFileW(SrcDir, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
	if (hSrc == INVALID_HANDLE_VALUE)
	{
		CloseHandle(hSrc);
		return FALSE;
	}
	DWORD fs_flags;
	if (!GetVolumeInformationByHandleW(hSrc, NULL, 0, NULL, NULL, &fs_flags, NULL, 0))
	{
		return FALSE;
	}
	if (!(fs_flags & www.laipuhuo.com FILE_SUPPORTS_BLOCK_REFCOUNTING))
	{
		SetLastError(ERROR_NOT_CAPABLE);
		return FALSE;
	}
	CloseHandle(hSrc);

	if (!CreateDirectoryW(DstDir, NULL))
	{
		return FALSE;
	}

	// Enumerate all files in the directory
	WCHAR src_dir[MAX_PATH];
	lstrcpyW(src_dir, SrcDir);
	PathAppendW(src_dir, L"*");
	WIN32_FIND_DATAW find_data;
	HANDLE hFind = FindFirstFileW(src_dir, &find_data);
	if (hFind == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	do {
		// ignore current and father path
		if (StrCmpW(find_data.cFileName, L".") == 0 || StrCmpW(find_data.cFileName, L"..") == 0)
			continue;

		// if it is a directory, create a new directory. And then recursively call this function.
		if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			WCHAR src_subdir[MAX_PATH], dst_subdir[MAX_PATH];
			StrCpyW(src_subdir, SrcDir);
			StrCpyW(dst_subdir, DstDir);
			PathAppendW(www.laipuhuo.com src_subdir, find_data.cFileName);
			PathAppendW(dst_subdir, find_data.cFileName);
			if (!CreateForkForDirW(src_subdir, dst_subdir))
			{
				FindClose(hFind);
				return FALSE;
			}
		}
		else
		{
			WCHAR src_file[MAX_PATH], dst_file[MAX_PATH];
			StrCpyW(src_file, SrcDir);
			StrCpyW(dst_file, DstDir);
			PathAppendW(src_file, find_data.cFileName);
			PathAppendW(dst_file, find_data.cFileName);
			if (!www.laipuhuo.com CreateForkForFileW(src_file, dst_file))
			{
				CloseHandle(hFind);
				return FALSE;
			}
		}
	} while (FindNextFile(hFind, &find_data) != 0);
	return TRUE;
}

int main()
{
	setlocale(LC_ALL, "chs");
	CreateForkForDirW(L"E:\\开发项目", L"E:\\test");
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
windows 下文件的高级操作
本文主要说明在Windows下操作文件的高级方法,比如直接读写磁盘,文件的异步操作,而文件普通的读写方式在网上可以找到一大堆资料,在这也就不再进行专门的说明。
Masimaro
2018/08/31
2.2K0
记一次蓝队—反钓鱼的策略研究
鄙人最近在某某群中寻找到了一个不知道谁的后门,心血来潮写下此文,以此提供一些蓝队简易反钓鱼的策略
亿人安全
2024/12/27
1470
记一次蓝队—反钓鱼的策略研究
C/C++ Zlib库封装MyZip压缩类
Zlib是一个开源的数据压缩库,提供了一种通用的数据压缩和解压缩算法。它最初由Jean-Loup Gailly和Mark Adler开发,旨在成为一个高效、轻量级的压缩库,其被广泛应用于许多领域,包括网络通信、文件压缩、数据库系统等。其压缩算法是基于DEFLATE算法,这是一种无损数据压缩算法,通常能够提供相当高的压缩比。
王 瑞
2023/11/30
5830
C/C++ Zlib库封装MyZip压缩类
如何快速生成Verilog代码文件列表?(内附开源C代码)
环境:Windows 7操作系统或其它常用Windows操作系统 编译器:DEV C++或其它 使用方法:随便找个C语言的编译器,静态编译生成exe文件后,可随意拷贝至某文件夹下,双击运行,等待输出rtl.f文件即可。
网络交换FPGA
2019/10/29
1.7K0
如何快速生成Verilog代码文件列表?(内附开源C代码)
windows下,c /c++实现磁盘扫描,结合配置文件,读取特定后缀文件目录代码
http://download.csdn.net/detail/wangyaninglm/8301303
流川疯
2019/01/18
1.8K0
自己手动复现一个熊猫烧香病毒
最近逛了一下 bilibili ,偶然的一次机会,我在 bilibili 上看到了某个 up 主分享了一个他自己仿照熊猫病毒的原型制作的一个病毒的演示视频,虽然这个病毒的出现距离现在已经十多年之久了,但是它的威胁性仍然不亚于永恒之蓝,出现了很多变种病毒。我觉得蛮有意思的,有必要深究一下,所以我花上几天的时间研究了一下熊猫烧香病毒的源码,仿照熊猫烧香病毒原型,也制作了一个类似的软件,实现的源码我会在文章的末尾给出 GitHub 项目链接,喜欢的朋友不要忘记给我一个 star and follow 呀!
Angel_Kitty
2018/09/21
7.4K0
自己手动复现一个熊猫烧香病毒
11.1 文件拷贝移动与删除
在编程中,针对磁盘与目录的操作也是非常重要的,本章将重点介绍如何实现针对文件目录与磁盘的操作方法,其中包括了删除文件,文件拷贝,文件读写,目录遍历输出,遍历磁盘容量信息,磁盘格式化,输出分区表数据,监控目录变化等。
王 瑞
2023/11/20
2940
windows 格式化磁盘_磁盘0没有初始化
新买来的硬盘是未初始化的,以我的理解就是没有引导扇区的,通常是没有MBR,如下图磁盘1,右边有大小,但显示“未分配”,
全栈程序员站长
2022/11/08
2K0
windows 格式化磁盘_磁盘0没有初始化
分享一个自写的Python远程命令和文件(夹)传输类
最近在跟一个自动化发布平台的建设事项,其中 Linux 系统的远程控制通道则由我独立开发完成,其中涉及到了 Linux 系统远程命令和文件传输操作。 因为之前写 Linux 系统密码管理系统的时候,用的是 Paramiko 的 SSHClient。所以,我这次依然采用 Paramiko 来做实现,代码虽短,说起其中的坑,我也是一把辛酸一把泪的填上了。 先上完整代码:、 # -*- coding: utf-8 -*- import os import socket import paramiko import
张戈
2018/03/21
2.5K0
Windows核心编程:第11章 Windows线程池
https://github.com/gongluck/Windows-Core-Program.git
gongluck
2019/02/22
1.2K0
C++ MiniZip实现目录压缩与解压
Zlib是一个开源的数据压缩库,提供了一种通用的数据压缩和解压缩算法。它最初由Jean-Loup Gailly和Mark Adler开发,旨在成为一个高效、轻量级的压缩库,其被广泛应用于许多领域,包括网络通信、文件压缩、数据库系统等。其压缩算法是基于DEFLATE算法,这是一种无损数据压缩算法,通常能够提供相当高的压缩比。
王 瑞
2023/11/23
1.7K0
C++ MiniZip实现目录压缩与解压
实战DeviceIoControl 之中的一个:通过API訪问设备驱动程序
Q 在NT/2000/XP中,我想用VC编写应用程序訪问硬件设备,如获取磁盘參数、读写绝对扇区数据、測试光驱实际速度等,该从哪里入手呢?
全栈程序员站长
2021/12/08
7470
ProcessGhosting-一套通用的免杀,自删除解决方案
本文来自项目https://github.com/hasherezade/process_ghosting
JDArmy
2022/06/06
8660
ProcessGhosting-一套通用的免杀,自删除解决方案
5.2 磁盘CRC32完整性检测
CRC校验技术是用于检测数据传输或存储过程中是否出现了错误的一种方法,校验算法可以通过计算应用与数据的循环冗余校验(CRC)检验值来检测任何数据损坏。通过运用本校验技术我们可以实现对特定内存区域以及磁盘文件进行完整性检测,并以此来判定特定程序内存是否发生了变化,如果发生变化则拒绝执行,通过此种方法来保护内存或磁盘文件不会被非法篡改。总之,内存和磁盘中的校验技术都是用于确保数据和程序的完整性和安全性的重要技术。
王 瑞
2023/10/11
2480
5.2 磁盘CRC32完整性检测
DeviceIOControl实战「建议收藏」
大家好,又见面了,我是你们的朋友全栈君。 实战DeviceIoControl 之一:通过API访问设备驱动程序
全栈程序员站长
2022/10/04
2.2K0
11.15 监控目录文件变化
监视对指定目录的更改,并将有关更改的信息打印到控制台,该功能的实现不仅可以在内核层,在应用层同样可以。程序中使用ReadDirectoryChangesW函数来监视目录中的更改,并使用FILE_NOTIFY_INFORMATION结构来获取有关更改的信息。
王 瑞
2023/11/21
4020
11.15 监控目录文件变化
应用层,驱动层,硬件层_windows组件向导在哪里
其中MyDispatchDeviceControl用来与应用层通过DeviceIoControl通信
全栈程序员站长
2022/10/04
5700
CFile::GetStatus 获取文件大小有问题
这个代码是在VS2015上, 文件大小大于2GB, fileStatus.m_size获取到的文件大小结果不对, GetStatus还返回执行成功
ClearSeve
2022/02/11
1.2K0
CFile::GetStatus 获取文件大小有问题
DotNet4应用程序打包工具->升级版【二】安装工具分析
-------------------------------------------------------
liulun
2022/05/09
3710
DotNet4应用程序打包工具->升级版【二】安装工具分析
应用程序与驱动程序通信 DeviceIoControl
这种通信方式,就是驱动程序和应用程序自定义一种IO控制码,然后调用DeviceIoControl函数,IO管理器会产生一个MajorFunction 为IRP_MJ_DEVICE_CONTROL(DeviceIoControl函数会产生此IRP),MinorFunction 为自己定义的控制码的IRP,系统就调用相应的处理IRP_MJ_DEVICE_CONTROL的派遣函数,你在派遣函数中判断MinorFunction ,是自定义的控制码你就进行相应的处理。
战神伽罗
2019/10/12
1.8K0
推荐阅读
相关推荐
windows 下文件的高级操作
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验