Коротко: в моем проекте c ++ мне нужно читать / писать расширенные свойства файла.Мне это удалось с помощью альтернативных потоков данных (ADS).Моя проблема заключается в том, что для открытия ADS мне нужно использовать CreateFile
API.Но это не удовлетворяет мои потребности.NtCreateFile удовлетворит все мои потребности.(Или же NtSetEaFile
и NtQueryEaFile
) Но NtCreateFile
напрямую недоступен из консольного приложения win32.
Я знаю, что могу легко использовать эту функцию через GetProcAdres
s.Но мне нравится знать мнение всех вас, если я что-то пропустил?Некоторые другие библиотеки уже используют этот шаблон, например, Chromium (https://github.com/chromium-googlesource-mirror/chromium/blob/1c1996b75d3611f56d14e2b30e7ae4eabc101486/src/sandbox/src/win_utils.cc function: ResolveNTFunctionPtr
), но я не уверен, потому что проект c ++ - это не хобби, и я спрашиваю себя, опасно это или нет.
Я думаю, NtCreateFile
, возможно, самый безопасный способ сделать это, потому что он хорошо документирован и поддерживается заголовком winternl.h
.Тем более, что этот метод остается неизменным со времен Windows 2000. Но что с NtSetEaFile
, NtQueryEaFile
, которые идеально соответствуют моим потребностям.Они только наполовину документированы.Документация для ZwSetEaFile
и ZwQueryEaFile
существует (без изменений, начиная с Windows 2000).
Причина, по которой я хочу это сделать:
Я хочу писать и читать расширенные свойства из файлов через ADS,Но в случае написания расширенного свойства данного файла в первый раз, мне нужно открыть файл с OPEN_ALWAYS
.Если файл не существует, он создаст новый файл, даже если я получу доступ только к потоку содержимого файла.Чтобы избежать этого, я сначала получаю дескриптор исходного файла и проверяю с помощью этой РУЧКИ, существует ли файл.Но я не хочу писать в блоге какие-либо файлы с ограниченными правами доступа, потому что, с моей точки зрения, это очень плохая модель.Пользователь должен иметь полный доступ к любому файлу в любое время.Из-за этого мы открываем все РУЧКИ с флагом FILE_SHARE_DELETE
|FILE_SHARE_READ
|FILE_SHARE_WRITE
.И теперь у меня есть гонка.
auto hFile = CreateFileW(originalPath, …, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, …).
// this is the little race: if somebody at least rename originalPath the
// second CreateFileW call will cause the creation of a empty file with the
// path originalPath (the old path).
auto hADS = CreateFileW(originalPath + adsName, …, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_ALWAYS, …).
Это главная проблема, особенно потому, что это время от времени происходит в наших тестах.NtCreateFile
исправит это, потому что я могу создать второй HANDLE
с помощью первого HANDLE
.Из-за этого нет расы.Или NtSetEaFile
и NtQueryEaFile
помогут, потому что мне нужна только одна РУЧКА.
Дело в том, что приложение не нужно сохранять в будущем, потому что ADS работает только на NTFS
.И кто знает, когда NTFS
будет обменен.Но я не хочу грубого поведения.Я хочу доверять этим методам.Я в порядке, если API изменится в будущем, и программное обеспечение должно адаптироваться к нему.Но я хочу быть уверен, что все Windows выше или равные 7 могут справиться с этим.Кто-нибудь поделиться опытом?Я бы очень хотел их услышать.