В один из дней Брюс попытался, используя стандартную функцию проводника Send To Compressed (zipped) Folder, упаковать последние исходники Process Monitor и послать мне.

Вместо обычного диалога о ходе упаковки, Проводник выдал ошибку:

Брюс был озадачен. Ошибка на первый взгляд не имела никакого смысла, так как определенно он имел права на чтение выбранных файлов, он их только что закончил редактировать, а сжатие не может затрагивать дополнительных файлов, которые могли бы быть не найдены. Он повторил операцию сжатия, но ошибка снова проявилась, правда, после другого количества файлов.
К счастью, в этот момент я появился на пороге его офиса, и он показал мне странное поведение программы. Теперь мы двое были озадачены. Пришло время провести расследование и инструментом в нем, как бы иронично это не выглядело, послужит Process Monitor.
Мы запустили программу, воспроизвели ошибку, остановили захват и начали просматривать тысячи операций в поисках ошибки. Мы увидели несколько ошибок NOT FOUND в начале лога, что обычно свидетельствует о попытке приложения проверить существование файла. На самом деле их были сотни в начале лога, все были запросы на файл, в котором будут помещены архивируемые файлы:

Это вызывало тревогу, но на самом деле не относилось к исследуемой нами проблеме, так что я отложил дело до более удобного случая.
Несколько сотен событий после мы наткнулись на ошибку SHARING VIOLATION:

Когда процесс открывает файл, он может определить, каким образом и при каких условиях он хочет разделить его с другими процессами, в ходе того как файл будет открыт. Три типа разделения - это чтение, запись, удаление, и каждый определяется своим флагом, который процесс передает CreateFile API. В операции, которая не удалась, Explorer не определил ни один из флагов, что означает его нежелание разделять файл, что видно в поле ShareMode:

Для удачного открытия файла тип разделения открывающего должен быть совместим с разделением, которое разрешается процессом, уже открывшим файл. Таким образом, объяснение этой ошибки состояло в том, что другой процесс уже открыл файл.
Вернувшись к трассировке, мы определили, что ошибке предшествовало открытие файла процессом Inort.exe. Закрытия файлов процессом не видно, так как оно случилось гораздо позднее ситуации с ошибкой. Это подтверждает, что конфликт разделения файла связан с Inort, даже несмотря на то что процесс указал возможность чтения, записи и удаления в своих условиях открытия файла.
Process Monitor закрыл дело - именно Inort держал файл открытым и вызвал ошибку разделения доступа с Explorer-ом, что и привело к появлению самой первой ошибки. Нам необходимо было определить принадлежность Inort для исправления ситуации. Process Monitor ответил и на этот вопрос:

eTrust, антивирусный сканер Computer Associates, вероятно, открыл файл для сканирования на вирусы, но его действия и операция Проводника наложились. Антивирус должен быть прозрачным для системы, так что в данном случае это полностью ошибка eTrust. Решением для Брюса стало исключение директории из списка сканируемых в реальном времени каталогов.
Когда я вернулся в офис, воспроизвести ошибку мне не удалось, я начал подозревать, что у меня другая версия антивируса, нежели чем у Брюса. Страница процессов Process Monitor действительно показала отличия. У меня была более поздняя версия - 7.01.0501.000:


Почему у нас разные версии, для меня до сих пор остается догадкой, ведь оба мы используем образы, созданные и задеплоенные администраторами Microsoft. Но зато стало ясно, что Computer Associates исправила баг в новом релизе.
Теперь настала пора вернуться к неэффективной работе процедуры сжатия в Проводнике. Я отследил компрессию одного файла и связанные с ней операции. Даже в таком простом случае Explorer открывает целевой ZIP-файл 14 раз, 12 раз до того как он на самом деле создается - все с ошибкой NOT FOUND. Кроме того, 19 раз выполняется обзор каталога. Избыточно открывается и исходный файл - 28 раз, 17 раз читаются его свойства. Похоже, Explorer предоставил eTrust массу возможностей для возникновения ошибки...
Оставалось убедиться, что за всей это вакханалией стоит именно Explorer^

Zipfldr.dll - оригинальный файл для компрессии, он светился в большинстве записей, значит именно он сам был причиной таких потерь. К тому же, учтите, что такие мусорные операции будут только возрастать с увеличением количества сжимаемых файлов! Однако совершенно очевидны пути для улучшения, и будем надеяться, что мы увидим более эффективный алгоритм в Windows 7. Собственно, уже известно, что движок архивации будет обновлен в Vista SP1.
www.xakep.ru





