Why does writing raw byte to a partition not working [sector writing]?

234 Views Asked by At

I have a usb key I want to write on directly to its first sector but it doesn't work at all. I tried to write a cross-platform (BSD/Linux/Windows) code for that (code below) but it doesn't do anything:

#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);
}

since it wasn't working I thought at least I would try a platform specific code using posix function like so:

//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);
}

it too didn't work either. I have to mention that I try both code on FreeBSD as sudo and the first code on windows as administrator Since I know, from another code I found, that I needed permission to run this thing.

As mentioned above I found another code that does almost what I want but it's in WIN API C++ (C++ using some Windows specific instructions). Unfortunately not only it's not cross platform but I don't know enough about WIN API C++ to make a cross platform C version of it or to change it so that instead of fill a whole sector or more it copies enough from the source file that I want to copy to the destination sector(s).

[EDIT]

When I run my program on FreeBSD I use the command sudo ./copier source.bin /dev/da0s1 436 it runs without telling me any error happened and for windows I use the command copier.exe e:\source.bin \\.\N: (N: being the partition N) in a administrator cmd and I get "Permission denied"

Also I just added to more instructions to know how many bytes were read and written:

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

I get a 436 bytes read with the above command and -1 bytes written. at least on the posix code. The cross-platform code tells me 436 bytes were written but when I check the hexadecimal raw data for the partition ; nothing has changed.

As suggested by Erdal Küçük I added the following instruction to get the error message after the write:

in Posix code :

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

in ANSI C code :

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

When I run the POSIX code on FreeBSD I get an error message

Couldn't write to file /dev/da0s1 : Invalid argument

When I run the cross platform code on FreeBSD ; the error message doesn't appear at all. On windows the cross platform code gives me a strange error message :

Couldn't write to file \\.\N: : No error

basically it couldn't write but errno is not an error ?

Windows tells me 0 byte(s) where written.

1

There are 1 best solutions below

3
user1546245 On

Perhaps you should check the mount flags of the device by running sudo mount.

Ensure that the subject device is mounted as r/w and not ro. If that doesn’t help, I have a suspicion that you could remedy this with a call to sync()

Another relevant design choice would be to make buffer dynamically allocated with a call to malloc(), rather than a fixed size which can cause buffer overrun and undefined behavior. Be sure to free that memory with the corresponding call to free()