在 C 中创建最大大小文件 : drive (OS drive) fails

标签 c windows winapi file-io privileges

我开发了一个磁盘和文件删除软件(使用WIN32 api),它还包含删除驱动器可用空间的选项。为此,我创建一个文件,该文件的大小与驱动器的可用空间大小相同,然后在该文件上写入随机字节(应用各种标准删除方案)。

我的问题是,它在除安装了 Windows 操作系统的驱动器(在我的例子中为 C:)之外的所有其他驱动器上运行良好。尽管该驱动器有大量可用空间,但它会给出“磁盘空间不足”错误。我的程序以管理权限运行。这是某种特权问题吗?即使以管理员身份运行程序后,我是否还需要为其授予更多权限?我想使用 winapi 以编程方式完成此操作。

我主要在 NTFS 文件系统上进行测试。我正在使用 CreateFile winapi 调用创建文件,并确保创建的文件大小等于可用空间,我使用碎片 api 来获取可用空间,然后使用 SetEndOfFile winapi 方法来扩展文件的大小。 任何帮助,将不胜感激。

最佳答案

Windows 不能很好地处理磁盘空间不足的情况,因此如果系统保留一些普通用户甚至管理员都无法使用的磁盘空间,我不会感到惊讶。然而,无论这是否属实,你的计划都是有缺陷的。在您发现有多少可用空间和尝试分配全部空间之间,分配的空间量很容易发生变化。即使它有效,事情也可能会因为磁盘已满而开始出现故障,即使只是很短的一段时间。

由于您已经在使用碎片整理 API,因此我将使用它来删除磁盘上的所有簇,而无需尝试将它们全部分配一次。首先创建一个文件,该文件填满大部分磁盘空间,但为其他进程分配文件留下足够的空间。然后使用 FSCTL_GET_VOLUME_BITMAP 获取未分配扇区的位图,并使用 FSCTL_MOVE_FILE 将簇从您创建的文件移动到位图中找到的空闲簇中。您需要做好 FSCTL_MOVE_FILE 失败的准备,因为分配的某个集群标记为空闲。在这种情况下,我会继续将您一次移动的集群数量减半,直到它起作用为止。如果只有一个集群失败,那么您就知道这是已分配的集群(或集群之一)。

像这样的伪代码:

// unalloc_start and unalloc_len describe an unallocated region in the free space bitmap
wipe_unallocated_clusters(hwipefile, unalloc_start, unalloc_len, max_chunk_len) {
    unalloc_vcn = unalloc_start
    unalloc_end = unalloc_start + unalloc_len
    max_chunck_len = max(max_chunk_len, unalloc_len)
    clen = max_chunk_len
    while(unalloc_vcn < unalloc_end) {
        clen = max(clen, unalloc_end - unalloc_vcn)
        while (fsctl_move_file(hwipefile, 0, unalloc_vcn, clen) == FAILED) {
            if (clen == 1) {
                unalloc_vcn++   // skip over allocated cluster
                continue
            }
            clen /= 2  // try again with half as many clusters
        }
        unalloc_vcn += clen
        clen = max(clen * 2, max_chunk_len)  // double the clusters if it worked
    }
}

关于在 C 中创建最大大小文件 : drive (OS drive) fails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25508245/

相关文章:

c++ - 正确处理listview中可编辑子项的子项编辑(或取消子项编辑)

winapi - Windows SDK 许可证

c - 反向打印数组然后将其相加

c - 查找二维数组中的路径最大值

c - 使用有限的位运算符将无符号整数乘以 10

windows - 按顺序递归重命名所有子文件夹中的文件

c - 如何使用 C 在控制台上打印 UTF-8 字符

c - 为什么 OSX 命令行中使用 Bash

windows - 如何禁用 Shift/Ctrl/Alt 键的 WM_KEYDOWN 重复事件?

c++ - Windows中的变量类型