在 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++ - 如何在内存中的位图上绘制文字[无MFC]

c - 在 c 程序中使用 ffmpeg header

c++ - 示例 2.1,K&R : Wrong symbolic constants value for LONG_MIN and LONG_MAX?

c - 使用结构时出错?

windows - 发送到多播目的地的 UDP 数据包通过环回接口(interface)发送

c++ - 使用 SetCount 的 CAtlArray 奇怪行为

c - 如何在 C 中用 2 个数组中的数据替换字符串?

JavaScript setInterval() 不适用于 Windows CE 设备

C#等待其他服务启动

c++ - MDI 子窗口大小