воскресенье, 29 августа 2010 г.

Почему FindFirstFile находит короткие имена файлов?

Это перевод Why does FindFirstFile find short names? Автор: Реймонд Чен.

Функция FindFirstFile находит соответствия среди коротких и длинных имён. Это может давать вам несколько неожиданные результаты. К примеру, если вы просите "*.htm", то эта маска вернёт вам файл "x.html", потому что его короткое имя - "X~1.HTM".

Почему функция смотрит на короткие имена файлов? Разве не должна она смотреть только на длинные имена? В конце концов, только старые 16-ти битные программы должны использовать короткие имена.

Но в этом-то и проблема: 16-ти битные программы используют короткие имена файлов.

С помощью процесса, известного как generic thunks, 16-ти битная программа может загрузить 32-х битную DLL и вызвать её. Windows 95 и слой эмуляции 16-ти битных Windows в Windows NT сильно зависят от generic thunks, так что им не нужно иметь две версии кода (прим.пер.: как это имеет место быть для 32-х и 64-х разрядного кода). Вместо этого, 16-ти битная версия просто используют 32-х битную версию через "переходник".

Заметьте, однако, что это означает, что 32-х битная DLL будет иметь два разных вида на файловую системы, в зависимости от того, загружена ли она 16-ти битным процессом или 32-х битным.

"Тогда пусть функция FindFirstFile проверяет, кто её вызывал, и меняет своё поведение соответствующим образом" - не сработает, потому что вы не можете доверять адресу возврата.

Даже если вы решите эту проблему, у вас всё равно останется проблема взаимодействия 16-ти разрядного и 32-х разрядного кода через границы процессов.

К примеру, предположим, что 16-ти битная программа вызывает WinExec("notepad X~1.HTM"). 32-х битному Блокноту лучше бы открыть файл X~1.HTM - даже хотя это короткое имя файла. Более того, частым способом получить некоторые свойства файла (типа даты последнего доступа) является вызов FindFirstFile на имя файла, потому что это даёт вам запись WIN32_FIND_DATA, в которой есть эта информация о файле (заметим: GetFileAttributesEx является лучшим выбором, но она относительно новая). Если бы функция FindFirstFile не работала бы для коротких имён файлов, то такой трюк не работал бы для некоторых файлов - файлов с короткими именами.

Другой пример: предположим, что DLL сохраняет имя файла в некоторое хранилище, к примеру, файл конфигурации, реестр или разделяемый блок памяти (shared memory). Если вызов этой DLL был сделан из 16-ти битной программы, то она передаст в неё короткие имена файлов, в то время как вызов DLL из 32-х разрядного приложения передаст длинные имена. Если бы функции файловой системы возвращали бы длинные имена только для 32-х разрядных программ, а короткие - только для 16-ти разрядных, тогда эта DLL, загруженная в 32-х разрядный процесс, не смогла бы воспользоваться данными, записанными ей же, но будучи загруженной в 16-ти битную программу.

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.