null

Проблемы совместимости, или жжешь Microsoft!

Так сложилось, что в рамках подготовки курса SI-365 Solaris Internals, я разбирался со строением драйвера pcfs (эмулятора файловых систем FAT), c целью показать на простом примере, как организована внутренняя файловая кухня в Solaris. И дернуло меня заглянуть в файл /usr/include/sys/fs/pc_dir.h! Насторожили буквально первые строчки: Long filename support (introduced by Windows 95) is an interesting exercise in compatibility. Интересно, думаю, что это за упражнение? Остаток дня я провел в гомерическом хохоте, закатывая глаза и бессильно дрыгая ногами.

 

Простите, если байан, я раньше даже не мог задуматься о таком «элегантном» решении! В общем судите сами.

 

Как мы с вами знаем, запись в каталоге о файле DOS-like файловых систем, состоит из следующих полей:

  

struct pcdir {

    char pcd_filename[PCFNAMESIZE]; /* file name */

    char pcd_ext[PCFEXTSIZE]; /* file extension */

    uchar_t pcd_attr; /* file attributes */

    uchar_t pcd_ntattr; /* reserved for NT attributes */

    uchar_t pcd_crtime_msec; /* milliseconds after the minute */

    struct pctime pcd_crtime; /* creation time/date */

    ushort_t pcd_ladate; /* last-access date */

    union {

        uint16_t pcd_eattr; /* OS/2 extended attribute */

        pc_cluster16_t pcd_scluster_hi;

    } un;

    struct pctime pcd_mtime; /* last modified time/date */

    pc_cluster16_t pcd_scluster_lo; /* starting cluster (little endian) */

    uint_t pcd_size; /* file size (little endian) */

}; 

Эти поля предназначены для хранения записи о имени файла состоящего из 8 символов имени и 3 символов расширения, представленными в национальной восьми-битной кодировке (используется альтернативная таблица ГОСТ). Дык вот, длинное имя файла — это последовательность подобных структур, которые завершаются коротким именем файла. Подобные — значит что в стандартную структуру директории, во всевозможные ее места, пытаются вставить кусочки имени файла:

#define PCLF_FIRSTNAMESIZE 10

#define PCLF_SECONDNAMESIZE 12

#define PCLF_THIRDNAMESIZE 4

/*

* A long filename entry. It must match the 'pcdir' structure in size,

* and pcdl_attr must overlap pcd_attr.

*/

struct pcdir_lfn {

    uchar_t pcdl_ordinal; /* lfn order. First is 01, next 02, */

                          /* last has bit 7 (0x40) set */

    uchar_t pcdl_firstfilename[PCLF_FIRSTNAMESIZE];

    uchar_t pcdl_attr;

    uchar_t pcdl_type; /* type - always contains 0 for an LFN entry */

    uchar_t pcdl_checksum; /* checksum to validate the LFN entry - */

                           /* based on the short name */

    uchar_t pcdl_secondfilename[PCLF_SECONDNAMESIZE];

    pc_cluster16_t pcd_scluster; /* (not used, always 0) */

    uchar_t pcdl_thirdfilename[PCLF_THIRDNAMESIZE];

};

Как видно, каждый компонент длинного имени состоит из 13 символов Unicode, разбитого на три! части. При этом первый компонент используется как счетчик компонентов имени и указание на последний компонент (установлен бит 0x40). Кроме того, каждая часть длинного имени файла содержит отдельные атрибуты (скрытый, системный, только для чтения, ...). Обычное имя «This is a very long filename indeed» выглядит так:

 

 Offset  Sequence      Component         Attributes    Cluster    Size

   0      0x43       "me indeed"          RSHV           0         0

  32      0x02       "y long filena"      RSHV           0         0

  64      0x01       "This is a ver"      RSHV           0         0

  96      ----       "THISIS~1.TXT"       <whatever>  2122       110


 

В общем, представьте себе ежика. Покажите на него пальцем и скажите — это слон. Не верят?! Тогда возьмите череп коровы, порвите зад ежика на три части, натяните череп, а из всего остального сделайте хобот. Немного косметики, и можете спокойно говорить, что это хоть и маленький, но слон. А когда подрастет!!! Люблю майкрософт.

 

Хотя и понимаю иногда. Как расширить имя, сохранив совместимость? Писать правильно изначально.

 

А я то думаю, как полечу файловую систему дос, все левые файлы вылезают! Теперь понятно откуда.