0

我有一个 USB 密钥,我想直接写入它的第一个扇区,但它根本不起作用。我试图为此编写一个跨平台(BSD/Linux/Windows)代码(下面的代码),但它什么也没做:

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>

int main(int argc, char * argv[])
{
    if(argc < 4)
    {
        printf("Usage : %s src_path dst_path bytecount", argv[0]);
    }   

    FILE * src;
    FILE * dst;
    char buffer[512];

    int readcount;
    int writecount;

    src = fopen(argv[1], "rb");
    if(src == NULL)
    {
        printf("Couldn't open file %s for reading : %s\n", argv[1], strerror(errno));
        exit(EXIT_FAILURE);
    }

    dst = fopen(argv[2], "wb");
    if(dst == NULL)
    {
        printf("Couldn't open file %s for writing : %s\n", argv[2], strerror(errno));
        exit(EXIT_FAILURE);
    }

    readcount  = fread(buffer,  1, atoi(argv[3]), src);
    writecount = fwrite(buffer, 1, atoi(argv[3]), dst);

    fclose(src);
    fclose(dst);

    return(EXIT_SUCCESS);
}

因为它不起作用,我想至少我会尝试使用 posix 函数的平台特定代码,如下所示:

//same previous headers plus some extra
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>

int main(int argc, char * argv[])
{
    //same condition here   

    int src;
    int dst;
    char buffer[512];

    int readcount;
    int writecount;

    src = open(argv[1], O_RDONLY);
    if(src == -1)
    {
        //same error message
    }

    dst = open(argv[2], O_WRONLY);
    if(dst == -1)
    {
        //same error message
    }

    readcount  = read(src,  buffer, atoi(argv[3]));
    writecount = write(dst, buffer, atoi(argv[3]));

    close(src);
    close(dst);

    return(EXIT_SUCCESS);
}

它也没有工作。我不得不提一下,我在 FreeBSD 上以 sudo 的身份尝试了这两个代码,在 Windows 上以管理员身份尝试了第一个代码 因为我知道,从我发现的另一个代码中,我需要权限才能运行这个东西。

如上所述,我发现另一个代码几乎可以满足我的需求,但它位于 WIN API C++ 中(C++ 使用一些 Windows 特定指令)。不幸的是,它不仅不是跨平台的,而且我对 WIN API C++ 的了解还不够,无法制作它的跨平台 C 版本或更改它,而不是填充整个扇区或更多扇区,而是从源文件中复制足够多的内容,我想要复制到目标扇区。

[编辑]

当我在 FreeBSD 上运行我的程序时,我使用命令sudo ./copier source.bin /dev/da0s1436,它运行时没有告诉我发生任何错误,对于 Windows,我copier.exe e:\source.bin \\.\N:在管理员 cmd 中使用命令(N:作为分区 N),我得到“权限被拒绝”

此外,我刚刚添加了更多指令以了解读取和写入的字节数:

printf("read %d byte(s)\n", readcount);
printf("wrote %d byte(s)\n", writecount);

我使用上述命令读取了 436 个字节并写入了 -1 个字节。至少在posix代码上。跨平台代码告诉我写入了 436 个字节,但是当我检查分区的十六进制原始数据时;什么也没有变。

正如 Erdal Küçük 所建议的,我添加了以下指令以在写入后获取错误消息:

在 Posix 代码中:

if(writecount == -1)
{
    printf("Couldn't write to file %s : %s\n", argv[2], strerror(errno));
}

在 ANSI C 代码中:

if(writecount != atoi(argv[3]))
{
    printf("Couldn't write to file %s : %s\n", argv[2], strerror(errno));
}

当我在 FreeBSD 上运行 POSIX 代码时,我收到一条错误消息

无法写入文件 /dev/da0s1:参数无效

当我在 FreeBSD 上运行跨平台代码时;错误消息根本没有出现。在 Windows 上,跨平台代码给了我一个奇怪的错误信息:

无法写入文件 \\.\N: : 没有错误

基本上它不能写但errno不是错误?

Windows 告诉我 0 字节在哪里写入。

4

1 回答 1

-1

也许您应该通过运行 sudo mount 来检查设备的挂载标志。

确保主题设备安装为 r/w 而不是 ro。如果这没有帮助,我怀疑您可以通过调用 sync() 来解决这个问题

另一个相关的设计选择是通过调用 malloc() 来动态分配缓冲区,而不是使用可能导致缓冲区溢出和未定义行为的固定大小。确保使用相应的 free() 调用来释放该内存

于 2021-03-08T15:13:03.953 回答