Windows и case-sensitive filesystem

в 15:22, , рубрики: c++, linux, ntfs, Windows 10, WSL, Блог компании «Лаборатория Касперского», Настройка Linux, системное администрирование, системное программирование

Давным-давно, на заре своего рождения Windows использовала файловую систему FAT. Потом ей на смену Microsoft и IBM разработали NTFS. В те давние времена возникло два противоположных подхода к файловой системе. В Linux используется case-sensitive файловая система, а в Microsoft — case-insensitive.

Суть в том, что в case-sensitive файловой системе считается, что имена, написанные в разных регистрах (например, FILE.txt и file.txt) — это разные имена. А для Windows между ними нет разницы.

Windows и case-sensitive filesystem - 1

Несмотря на нечувствительность Windows к регистру букв, разработчики NTFS подошли к делу ответственно, и бережно сохраняют регистр имен каталогов и файлов. Возможно, они не теряли надежды на сближение с противоборствующим лагерем.

Первые жертвы

Шли годы, информационные технологии не стояли на месте, и дистрибутивы Linux научились монтировать NTFS-разделы. Операционные системы стали ближе, а наши противники впервые столкнулись на одном поле — и появились первые проблемы. Присоединив NTFS-раздел, пользователь Linux мог создать в одном каталоге несколько различных файлов с именами, которые отличаются только регистром. А как мы знаем, NTFS сохраняет регистр букв при создании объектов файловой системы. Если потом подключить тот же NTFS-раздел к Windows, то операционная система начнет путать файлы-близнецы между собой. С ее точки зрения, они имеют одинаковые имена! Пользователь кликает по одному файлу, а открывается совсем другой. Короче, хаос и безобразие.

В 2016 году Microsoft сделала шаг навстречу Linux и выпустила Windows 10 Anniversary Update с подсистемой WSL. Windows Subsystem for Linux (WSL) предоставляет интерфейсы, во многом совместимые с интерфейсами ядра Linux. Что позволяет запускать большинство Linux-приложений, в том числе оригинальные образы некоторых Linux-дистрибутивов. Например, Ubuntu 14.04! Это была революция! Linux и Windows работают на одном компьютере одновременно, как партнеры. Но к сожалению, партнеры все еще по-разному смотрели на регистрочувствительность в плане работы с файловой системой. Ввести Windows в замешательство с помощью создания файлов или каталогов с именами, отличающимися только регистром, стало еще проще.

Попытка примирения

В новой версии Windows 10 Spring Creators Update компания Microsoft добавила возможность задания режима case-sensitivity для отдельно взятого каталога. Сделать это можно с помощью утилиты fsutil. Читатель, наверное, уже знаком с этой полезной утилитой.

Теперь у нее появились две новые команды:

fsutil file queryCaseSensitiveInfo
Windows и case-sensitive filesystem - 2

fsutil file setCaseSensitiveInfo

Windows и case-sensitive filesystem - 3

Для того чтобы воспользоваться этими командами, у вас должна быть активирована WSL-подсистема, а команда setCaseSensitiveInfo требует прав администратора.

После включения режима case-sensitivity файлы и каталоги, находящиеся внутри, будут доступны только при указании их точного имени! И Windows теперь четко видит разницу между FILE.txt и file.txt.

С другой стороны, WSL-подсистема тоже должна учитывать, включен или выключен режим case-sensitivity у каталога, в котором она создает файл или дочерний каталог. Каталоги, которые формируют структуру WSL или создаются из WSL, сразу имеют включенный case-sensitivity. Все остальные каталоги по умолчанию режим case-sensitivity не включают.

Если в WSL зайти в каталог с выключенным case-sensitivity режимом и попробовать создать в нем два файла, имена которых будут отличаться только регистром, то получите ошибку.

Таким образом, WSL и Windows поделили логический диск между собой. Часть каталогов поддерживает режим case-sensitivity, а другая часть – нет.

Спускаемся ниже

Под капотом для получения и задания флага case-sensitivity используются функции NtQueryInformationFile и NtSetInformationFile c новым параметром FileCaseSensitiveInformation.

Пример:

HANDLE h = CreateFile(
              path,
              FILE_READ_ATTRIBUTES,
              FILE_SHARE_READ,
              0,
              OPEN_EXISTING,
              FILE_SUPPORTS_USN_JOURNAL,
              0);

 if( INVALID_HANDLE_VALUE == h )
     return;

 IO_STATUS_BLOCK io;
 uint32_t csFlags = 0;

 DWORD error = NtQueryInformationFile(
                 testHandle,
                 &io,
                 &csFlags,
                 sizeof(csFlags),
                 (FILE_INFORMATION_CLASS)0x47); // FileCaseSensitiveInformation

 CloseHandle(h);

В результате работы функции в переменной csFlags будет 1, если режим case-sensitivity включен, и 0 — если выключен.

Еще ниже — Raw NTFS

На уровне NTFS флаг case-sensitivity хранится в атрибуте StandartInfoData, в поле NumVersion.
Если атрибут выставлен, то NumVersion = 1, иначе NumVersion = 0

typedef struct _StandartInfoData_
{
   FILETIME CreateTime;
   FILETIME LastModTime;
   FILETIME LastModMFT;
   FILETIME LastAccess;
   DWORD FileAttrib;
   DWORD MaxVersions;
   DWORD NumVersion; // <--
   DWORD ClassId;
   DWORD OwnerId;
   DWORD SecureId;
   ULONGLONG Quota;
   ULONGLONG SequenceNumber;
} StandartInfoData;

Заключение

Мы видим, что Microsoft прикладывает значительные усилия для того, чтобы объединить в одной системе два разных мира — Windows и Linux. И для успеха своей миссии они пошли на уступки в плане регистрочувствительности своей файловой системы. Поможет ли это? Решит ли противоречия? И какие еще проблемы всплывут? Все это покажет лишь Его Величество Время.

Wanted

Кстати. Или не совсем кстати. У нас тут коллеги ищут руководителя группы разработки автотестов. Правда работа в Новосибирске. Если кому-то это интересно, то вот вакансия.

Автор: OldMaster

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js