Search code examples
c++filewinapicreatefileunbuffered

How to append in file in Windows in UnBuffered mode using CreateFile


Every time my function is getting called it is overwriting to the file. Kindly note I am opening file in unbuffered mode using below flags.

FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH

If I am using simple buffered mode it is working fine.

FILE_ATTRIBUTE_NORMAL

I am getting following error in unbuffered mode.

** ERROR ** CreateFile failed: The parameter is incorrect.

Kindly find the code snippets below. This piece of code getting called many times.

HANDLE hFile;

LPCWSTR file_path = convertCharArrayToLPCWSTR(UNBUFFERED_FILE);

hFile = CreateFile(file_path,
    FILE_APPEND_DATA,
    FILE_SHARE_WRITE,
    NULL,
    OPEN_ALWAYS,
    FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
    NULL
);

if (hFile == INVALID_HANDLE_VALUE)
{
    std::cout << "Unable to open/create file for writing" << std::endl;
    PrintError(TEXT("CreateFile failed"));
}


Data *data = new Data();
DWORD dwBytesToWrite = sizeof(Data);
DWORD dwBytesWritten = 0;
BOOL bErrorFlag = FALSE;


bErrorFlag = WriteFile(
    hFile,                  // open file handle
    data,                   // start of data to write
    dwBytesToWrite,         // number of bytes to write
    &dwBytesWritten,        // number of bytes that were written
    NULL);

if (bErrorFlag == FALSE)
{
    std::cout << "Unable to write to file" << std::endl;
    PrintError(TEXT("Unable to write to file"));
}

if (dwBytesToWrite != dwBytesWritten)
{
    std::cout << "Error in writing: Whole data not written" << std::endl;
    PrintError(TEXT("Error in writing: Whole data not written"));
}

CloseHandle(hFile);

. Kindly suggest if any alternative idea is available.


Solution

  • from NtCreateFile

    FILE_NO_INTERMEDIATE_BUFFERING
    

    The file cannot be cached or buffered in a driver's internal buffers. This flag is incompatible with the DesiredAccess parameter's FILE_APPEND_DATA flag.

    so when you call

    CreateFile(file_path,
        FILE_APPEND_DATA, // !!
        FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        FILE_FLAG_NO_BUFFERING /*!!*/| FILE_FLAG_WRITE_THROUGH,
        NULL
    );
    

    you use FILE_FLAG_NO_BUFFERING (mapped to FILE_NO_INTERMEDIATE_BUFFERING) with FILE_APPEND_DATA - you and must got ERROR_INVALID_PARAMETER. you need remove one flag. i suggest remove FILE_FLAG_NO_BUFFERING flag, because with it you can write only integral of the sector size.