c++windowsiousb-drive

`WriteFile` error 1006 when writing to VirtualBox-redirected USB flash drive


I need to decompress an archive (.zip) file onto a USB stick, but after a successful number of CreateFile()/WriteFile() calls, I get various errors from WriteFile(), most of the time the first ones are FILE INVALID (GetLastError() gives error code 1006).

Please note that when starting the computer (I'm working on a Virtualized Windows 11) and launching the program for the first time, it works and fully decompress the archive. Any other attempt fails.

Here's the pseudo-code:


// *dst is my usb stick mounpoint, most of the time its "E:"

static int decompress_file(const char * zip,
    const char * dst) {
    struct zip_stat sb;
    struct zip * za = zip_open(zip, ZIP_RDONLY, NULL);
    size_t readLen, totalLen = 0;
    char buffer[4096];

    for (long int i = 0; i < zip_get_num_entries(za, 0); i++) {
        zip_stat_index(za, i, 0, & sb);
        const std::string file = std::string(dst) + sb.name;
        struct zip_file * zf = zip_fopen_index(za, i, 0);
        HANDLE fd = CreateFile(
            file.c_str(),
            GENERIC_WRITE,
            0,
            NULL,
            CREATE_ALWAYS,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        );

        totalLen = 0;
        while (totalLen != sb.size) {
            readLen = zip_fread(zf, buffer, 4096);
            WriteFile(fd, buffer, readLen, NULL, NULL);
            totalLen += readLen;
        }

        CloseHandle(fd);
        zip_fclose(zf);
    }
    zip_close(za);
    return 0;
}

I tried to simplify the code, please note that it won't compile as-is. I'm using libzip.

The same code using open()/write() works fine on Linux/macOS.

This code is executed in a separate thread, the main thread is displaying a GUI (wxWidget) and waiting for this task to finish.

I tried to size my buffer according to a page size, 4096 bytes I guess for most of us? I also tried to set the buffer size to 512 and 8192 but It did not changed anything.

The error is always happening in the middle/end of the program's execution, after plenty of successful call to CreateFile()/WriteFile().

I tried to monitor my program with Process Monitor and Process Explorer. I'm correctly closing the file descriptor, there are no red flags on Process Monitor except the one I'm describing to you.

Here's a capture of Proc Monitor's output :

procmon output

I also get a 0x80000016 error, which according to MSDN relates to constant STATUS_VERIFY_REQUIRED:

The media has changed and a verify operation is in progress so no reads or writes may be performed to the device, except those used in the verify operation.

https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-FSCC/%5BMS-FSCC%5D-130808.pdf

I saw that a direct write to an external drive (when opened as a Physical drive with \\\\.\ syntax) must be sector-aligned, but this is not my case here? I also tried to switch to _open()/_write(), but had the exact same issue.

Can anyone help me, please?


Solution

  • 1006 is

    ERROR_FILE_INVALID

    1006 (0x3EE)

    The volume for a file has been externally altered so that the opened file is no longer valid.

    "Externally altered" seems like a definite possibility when working with mapped drives (mapped from virtual machine host or from network server could both reasonably create that error). It seems that the actual filesystem in control (running on the host) has removed the file, rendering your open handle stale and unusable.

    Do you get better results if extracting to a virtual disk (VMDK) rather than a mapped drive?

    Or if you give the VM control over the entire USB volume without having it mounted in the host?