0

I am pretty new to C, but using the standard library I would use something like the following code if I wanted to open a file and write data to a certain offset without overwriting the entire file.

ptrdiff_t offset = 0x44;             // start offset of data I want to overwrite
FILE* f = fopen("file.sra", "r+b");  // open file in read/update mode
fseek(f, offset, SEEK_SET);
fwrite(buffer, 8, 1, f);                       
fclose(f);   

I am learning how to use the Win32 API, and I can't seem to get equivalent functionality from the CreateFile() function. I have searched for similar questions, like these:
https://cboard.cprogramming.com/windows-programming/30783-overwrite-data-file.html
C++ Insert text at specific position in append with Windows API
Inserting text into file at specific offset using Win32 API

These posters seem to be asking the same general question, but the threads all dead end with no real answer.

Of course, I could just call fopen()/fwrite() and be done with it, but since I'm trying to learn the basics of Win32 API, I'd like to know if there is a way to achieve read/update functionality with just the Windows functions, particularly CreateFile().

Also, I know I can read the data and append and shift and all that, but that's not what I'm after. I want to achieve similar functionality to the example C code above by figuring out how to set CreateFile() to have a similar read/update mode.

Windows code I tried:

HANDLE hFile = CreateFile(pszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);

....<irrelevant code>....

SetFilePointer(hFile, offset, NULL, FILE_BEGIN);
if(WriteFile(hFile, buffer, 8, NULL, NULL))
    bSuccess = TRUE;
}
CloseHandle(hFile);
  • CREATE_ALWAYS always creates a new file. OPEN_EXISTING opens a file, only if it exists. The official doc is pretty thorough https://learn.microsoft.com/en-us/windows/win32/fileio/creating-and-opening-files – Simon Mourier Nov 17 '22 at 18:33
  • EDIT: It looks like it was as easy as just using OPEN_EXISTING, thank you! Thanks for the link @SimonMourier, I did stumble on that page at one point but the solution wasn't obvious to me after scanning through. Some of the Microsoft documentation is very technical and it's hard for me to distill all that information down to something that makes sense to me. I'll see if I can make better sense of it and figure out what combination of the flags and attributes would get me something like "r+b" in plain C. – Jayson Gazeley Nov 17 '22 at 19:05

1 Answers1

0

Thanks to Simon in the comments, I was able to figure this out. The key was to replace CREATE_ALWAYS with OPEN_EXISTING like so:

HANDLE hFile = CreateFile(pszFileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

....<irrelevant code>....

SetFilePointer(hFile, offset, NULL, FILE_BEGIN);
if(WriteFile(hFile, buffer, 8, NULL, NULL))
    bSuccess = TRUE;
}
CloseHandle(hFile);

This opens an existing file, sets the file pointer to a certain offset, and then writes 8 bytes to the existing file, overwriting only the previous 8 bytes at that location, leaving the rest of the file intact.