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.
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()