Конфигурация не устанавливается с ошибкой "FDICopy() failed: code 2 [ci-temp0.cab]" на этапе создания временных файлов.
trace:file:CreateFileW returning 0x64 trace:file:ReadFile 0x64 0x7e429764 36 0x7e4296e8 (nil) err:cabinet:FDICopy FDIIsCabinet failed.
Код, возвращающий ошибку: /* check if it's really a cabfile. Note that this doesn't implement the bug */ if (!FDI_read_entries(hfdi, cabhf, &fdici, &(CAB(mii)))) { ERR("FDIIsCabinet failed.\n"); PFDI_CLOSE(hfdi, cabhf); return FALSE; }
Проверка проваливается, если cab-файл не содержит файлов или каталогов. А исследуемый файл весит всего 36 байт.
Created attachment 213 [details] ci-temp0.cab
Подстановка нативного cabinet.dll позволяет обойти проблему маленького cab-файла. Впоследствии может возникнуть проблема с кодировками имён файлов. Системная кодировка не должна быть KOI8 (проверено - на CP1251 работает).
Когда мы будем писать комментарии, в которых будет суть проблемы? Один из файлов в архиве содержит в имени знак № (номер), и установка не сможет пройти в кодировке локали, которая не имеет такого знака (например, с кодировкой koi8-r). По коду проверки CAB-файла - нужен патч, отключающий return FALSE, с сохранением сообщения об ошибке.
Почему разборки с багами начинаются, и не заканчиваются? Надо уж написать тест красивый, отправить в wine-patches, проблему исправить...
Надо исправить окончательно к релизу.
Как я понял, FDICopy вызвает функцию FDI_read_entries, в которой и происходит ошибка. А ошибка в следующем: Где-то в FDI_read_entries (fdi.c:565) идёт проверка на то сколько директорий содержит cab-файл. Если не содержит ни одной, то возвращает FALSE. Далее FDICopy видит, что проверка не выполнилась, и тоже возвращает FALSE. А Windows в этом случае возвращает TRUE
Проверил: могут быть такие cab-файлы, которые содержат файлы, но не содержат директории (бага 1086 - тестовый файл test6.cab) Очевидно, что проверку на отсутствие директорий надо просто выкинуть. При этом функция FDI_read_entries() или вызывающая её FDICopy() может работать с ошибками. Надо проверить
Проверил: Если в cab-файле нету папок, но есть, хотя бы один файл, то комманда num_folders = EndGetI16(buf+cfhead_NumFolders); Всё-равно находит 1 директорию. В случает, если в cab-файле нет ни папок, ни файлов, то данная комманда говорит, что директорий 0. Думаю, что в данном случае, не следует удалять проверку на количесво директорий, а сделать так, чтобы она возвращала, например, EMPTY_CABINET. Далее FDI_Copy смотрит возвращаемое значение, и если оно EMPTY_CABINET, то просто возвращает TRUE. Таким образом, если папок 0, значит сab-файл пустой. Значит можно сразу возвратить TRUE (т.к он правильный, но нечего распаковывать)
Проблемы могут возникнуть в том случае, когда cab-файл битый, а мы будем считать его правильным. Но думаю, что это не произойдёт, ведь до проверки на наличие папок стоит ещё несколько проверок.
Исправил. Тест проходит. Ещё несколько функций используют FDI_read_entries(). И если она возвратит EMPTY_CABINET, то они будут считать это как TRUE. Попробовал убрать в FDICopy() проверку на EMPTY_CABINET (т.е FDICopy считает, что FDI_read_entries() возвращает TRUE, и идёт дальше. В результате возникает ошибка доступа. Получается, что просто TRUE или EMPTY_CABINET возвращать нельзя. Иначе придётся переписывать и другие функции, чтобы они тоже ловили EMPTY_CABINET.
Попробовал просто убрать проверку на наличие директорий и файлов. В итоге FDI_read_entries() завершается без ошибок, а ошибка возникает в FDICopy() при чтении папок
Нет, всё-таки чтение папок и файлов проходит нормально, а ошибка возникает при чтени файлов в выражении: for (file = CAB(firstfile); (file); file = file->next) { ....
Заполнение структуры pfdici происходит в конце функции FDI_read_entries(). Поэтому, если количество папок=0, то возвращать EMPTY_CABINET надо не сразу после проверки на количество папок, а в самом конце, перед выходом. Тогда структура pfdici будет нормально заполнена. Ещё можно добавить проверку на ситуацию когда папок не 0, а файлов 0. Такого быть не может.
Думаю, что бага исправлена. Патч находится в wine-etersoft-public/patches/check/dlls_cabinet_empty-cab.patch
Ты не можешь возвращать из FDI_read_entries TRUE, FALSE, EMPTY_CABINET надо 3 самостоятельные константы. И нельзя ли всё-таки обустроить так, чтобы FDI_read_entries возвращала TRUE/FALSE, а дальше с 0 количеством файлов разборка шла как-то общим порядком (без особого исключения для 0 количества файлов)
Согласен, что мой вариант не особо красивый. Но возвращать какие-то константы вместо TRUE и FALSE нельзя: ведь другие функции, использующие FDI_read_entries() ожидают именно TRUE или FALSE. Но всё должно работать потому, что EMPTY_CABINET != 0 , а следовательно другие программы считают его за TRUE.
Переписал. Теперь при пустом cab-файле FDI_read_entries() возвращает TRUE. При этом пришлось поправить FDICopy(), так как она при этом падала
Итак, каков результат по данной баге?
Всё должно работать, надо только проверить в "1С Универсал". Последнюю версию патча я, вроде, не закоммитил. Надо проверить
в текущей версии патч отсутствует. Сделал патч для git. Осталось только проверить 1С Универсал
Будет в сборке -eter12 commit 5e3b980bb4d0079b3472617605cc128367f1c513 Author: Vitaly Perov <vitperov@etersoft.ru> Date: Sun Jun 22 14:10:02 2008 +0400 cabinet: fix bug #930: empty *.cab is count as invalid
(In reply to comment #24) > Будет в сборке -eter12 > > commit 5e3b980bb4d0079b3472617605cc128367f1c513 > Author: Vitaly Perov <vitperov@etersoft.ru> > Date: Sun Jun 22 14:10:02 2008 +0400 > > cabinet: fix bug #930: empty *.cab is count as invalid > Проверил на последней бете - не работает
Конфигурация для тестирования установки: /var/ftp/pvt/Windows/1C/2008-07/universal-080707-full.exe
Created attachment 555 [details] ?1 И снова эти квадратики...
Created attachment 556 [details] ?2 Вылет
Такого файла в директории нет.
Установку нельзя запускать в локали koi8-r (в этой кодировке нет символа №) запускай через $ LANG=ru_RU.CP1251 wine
Да -так всё работает. сборка wine-1.0.9-alt15