Search code examples
cwindowsusbusb-driveraw-data

How can I Read&Write raw data to a USB-Drive using C on windows


So I made my own encryption scheme and I came up with an idea that I can have a USB drive with raw data (no file-system at all) that I can use as a "key" in my encryption scheme.

I need a way to read and write data right into the USB, Iv'e tried using libusb but I couldn't figure it out (too low-level for me).

Iv'e also seen that there's a way to open a handle to the USB drive using CreateFile function on windows but I couldn't figure out the required parameters and I got ERROR_INVALID_PARAMETER when trying to read.

I understand that the OS will think that the drive/its file system are corrupted (since it won't have one) but it doesn't matter, I just need a way to store raw data.

Any help appreciated, thank you!


Solution

  • The problem with your approach is, that windows always asks if the drive should be formatted. And it may be very likely that the one or other day the question will be answered the wrong way ;)

    However you can open a volume, if you know the correct name, that windows uses internally for it. You can get Sysinternals WinObj which can show you all names. For drives Windows also creates symlinks like \\.\C: to access them via the drive letter. Make sure that the backslashes are escaped correctly in your code (usually "\\\\.\\C:") and that there is no trailing slash after the colon.

    But I like to point you to the documentation of CreateFile especially the remarks section (https://learn.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-createfilea#remarks):

    Maybe you missed one of the following points:

    The following requirements must be met for such a call to succeed:

    • The caller must have administrative privileges. For more information, see Running with Special Privileges.
    • The dwCreationDisposition parameter must have the OPEN_EXISTING flag.
    • When opening a volume or floppy disk, the dwShareMode parameter must have the FILE_SHARE_WRITE flag.

    As Eryksun pointed out: for a drive that itself reports to be removable, the administrative privileges are not required.

    Example to open an USB-Drive that has the letter 'D';

    HANDLE h = CreateFile("\\\\.\\D:", (GENERIC_READ | GENERIC_WRITE), FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    
    if (h != INVALID_HANDLE_VALUE) {
      unsigned char buffer[512];
      DWORD readBytes = 0;
      ReadFile(h, buffer, sizeof(buffer), &readBytes, NULL);
      /* .. */
      CloseHandle(h);
    }
    

    Please also note that according to citings in https://stackoverflow.com/a/31712818/2331592 the read/written data blocks must sector aligned.
    So to be safe determine the sector size first(e.g. with GetDiskFreeSpace)