The NTFSD list has discussed the semantics of file creation and we thought it would be a good idea to capture that information (and add it to the database of information we have for Windows file systems).
Specifically, the Win32 API defines five different creation options. Each of these maps to underlying Windows behavior:
- OPEN_EXISTING - this maps to the Windows FILE_OPEN option, and causes the file to be opened if it exists. If it does not exist, the call fails.
- CREATE_NEW - this maps to the Windows FILE_CREATE option, and causes the file to be newly created. If it exists, the call fails.
- OPEN_ALWAYS - this maps to the Windows FILE_OPEN_IF option, and causes the file to be opened if it exists, created if it does not.
- CREATE_ALWAYS - this maps to the Windows FILE_OVERWRITE_IF option, and causes the file to be opened and truncated if it exists (including all streams of the file). If the file does not exist, it is newly created.
- TRUNCATE_EXISTING - this maps to the Windows FILE_OPEN but is then followed by an IRP_MJ_SET_INFORMATION call to set the size of the file to zero. If the file dos not exist, this call fails.
This mapping, and the corresponding semantics are not necessarily clear:
- FILE_OVERWRITE_IF will destroy all named streams in an NTFS file.
- FILE_SUPERSEDE requires FILE_DELETE access
- FILE_OVERWRITE and FILE_OVERWRITE_IF require FILE_WRITE_DATA access.
- FILE_OVERWRITE_IF requires FILE_DELETE access on any data streams currently open for the given file.
Note that the semantic differences between FILE_OVERWRITE_IF and FILE_SUPSERSEDE are small and subtle. For example, if a file is overwritten, the state of the attribute bits of the file are preserved (system, hidden, archive) while if the file is superseded, the attribute bits of the file are reset. Of course, there is no mapping from Win32 semantics to FILE_SUPERSEDE for any of the cases anyway, so this is not a frequently observed operation.