На стадии копирования файлов прерывается с сообщением, что установка не завершена. Ни LT, ни полная версия.
Ошибка в распаковке *.cab err:msi:msi_cabextract FDICopy failed err:msi:ACTION_InstallFiles Failed to extract cabinet: L"Data1.cab"
Ошибка в переписанной недавно функции cabinet_notify. (патч называется msi: Factor out media handling and use the new interface to efficiently extract assemblies.) Сначала файлы копируются нормально, но на каком-то определённом файле (C:\\Program Files\\ASCON\\KOMPAS-3D V10\\Libs\\load\\1.LOA) возникает ошибка cabinet_notify вызывается FDI_Copy c сообщением непосредственно перед копированием файла fdintCOPY_FILE. cabinet_notify должна вернуть 0 для продолжения или -1 для отмены копирования. В данном случае возвращается -1. в случае копирования cabinet_notify вызывает вспомогательную функцию cabinet_copy_file, которая выполняет проверку записи. Для этого она создаёт файл по указанному адресу (если он существует, то перезаписывает) Ошибка возникает когда CreateFileW возвращает INVALID_HANDLE_VALUE
Последняя ошибка ERROR_ACCESS_DENIED проваливается NtCreateFile. Возможно проблема в атрибутах. У предыдущих файлов attr=0x80 (FILE_ATTRIBUTE_NORMAL), а у этого 0x1 (FILE_ATTRIBUTE_READONLY)
Данная проблема решается если: 1) Проверять атрибуты файла перед его созданием. Если он read-only, то снимать этот атрибут. 2) При создании файла брать атрибуты не из *.cab файла, а ставить FILE_ATTRIBUTE_NORMAL После внесённых изменений бага появляется уже в другом месте. В файле "C:\\windows\\system32\\msvcp60.dll" Этот файл является ссылкой.
Появилас идея: Если CreateFileW проваливается, то попытаться удалить файл, а потом создать заново. Проверил. Оказалось, что ссылку удалить не получается. Вообще, со стороны винды никак не увидить обычный это файл или ссылка. Поэтому если создание файла проваливается, невозможно определить провалилось ли оно потому, что *.cab был неверный или потому, что файл является ссылкой. Поэтому вся проверка получается бессмысленной. Думаю, что следует её убрать
теперь установка прерывается при: err:msi:ACTION_InstallFiles compressed file wasn't extracted (L"C:\\windows\\winsxs\\amd64_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_9d1c6ce0\\msvcr80.dll") в патче (см #2) была добавлена функция installfiles_cb. И была существенно исправлена система вызова распаковщика *.cab файлов из msi. Думаю можно откатить весь патч, но там много полезного.
после окончания распаковки FDICopy должна вызвать cabinet_notify с атрибутом fdintCLOSE_FILE_INFO, сообщив тем самым об окончании распаковки. Но этого не происходит
Дописал cabinet_copy_file так, что при каждом выхове при успешном завершении выставлялось f->state = msifs_installed; Это временное решение. Потом надо будет обязательно проверить почему не вызывается сabinet_notify с атрибутом fdintCLOSE_FILE_INFO. Теперь *.cab успешно распаковывается, но установка всё-равно завершается с ошибкой
ошибка в регистрации библиотеки err:msi:ITERATE_RegisterTypeLibraries Failed to load type library: 80029c4a файл библиотеки находится по адресу: TargetPath = L"C:\\Program Files\\ASCON\\KOMPAS-3D V10\\Bin\\kAPI5.TLB" При использовании встроенного oleaut32 возвращается ошибка: err:ole:TLB_ReadTypeLib Loading of typelib L"C:\\Program Files\\ASCON\\KOMPAS-3D V10\\Bin\\kAPI5.TLB" failed with error 2 что соответствует ERROR_FILE_NOT_FOUND И действительно, такого файла там нет
Проверил Data1.cab: Файл такой там есть! Поэтому проблема в распаковке *.cab файла. Наверное поэтому и не вызывается cabinet_notify с атрибутом fdintCLOSE_FILE_INFO
Проверил Data1.cab - kAPI5.tlb (именно .tlb а не TLB) в нём содержится. Думаю регистр тут не причём. Вообще в папке bin слишком мало файлов, поэтому очевидно, что не всё распаковывается. Убрал добавления, свызанные с f->state = msifs_installed В итоге вернулась ошибка err:msi:ACTION_InstallFiles compressed file wasn't extracted (L"C:\\windows\\winsxs\\Manifests\\amd64_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_9d1c6ce0.manifest") Пробовал распаковать Data1.cab с помощью сabextract и extrac32: *.manifest файлов там не содержится!
Разобрался в проблеме: В ACTION_InstallFiles в цикле обрабатываются все файлы Если стоит флаг file->IsCompressed, то файл распаковывается (как Data1.cab). Если же этот флаг не стоит, то файл должен быть просто скопирован. Проблема в том, что на таких файлах, как \\Bin\\KOMPAS.Exe флаг всё-таки стоит! поэтому вместо простого копирования msi пытается их распаковать
Проверил: флаг file->IsCompressed выставляется исходя флагов в атрибуте file->Attributes, а тот непосредственно читается из файла. Поэтому неверное выставление флага file->IsCompressed исключено. В процессе выполнения этот флаг нигде не изменяется Сейчас File->IsCompressed устанавливается если в file->Attributes выставлен бит msidbFileAttributesCompressed, и сбрасывается если выставлен бит msidbFileAttributesNoncompressed Проверил: ни у одного файла бит msidbFileAttributesNoncompressed НЕ установлен! Отсюда предположение, что File->IsCompressed следует всё-таки выставлять не по file->Attributes.
разобрался. На всех файлах выставлен атрибут File->IsCompressed потому, что их всех следует брать из исходного *.cab. Если же этот атрибут не выставлен, то файлы берутся из текущей директории. Проблема в том, что сначала распаковывается весь *.cab, а потом msi начинает искать по внутреннему списку файлы, которые требуются установить. Возможно надо распаковывать не весь *.cab, а брать конкретный файл из него.
Файлы распаковываются с помощью FDICopy(). Проблема в том, что FDICopy() распаковавает сразу все файлы! Нашёл главную проблему: CALLBACK функция cabinet_notify нужна не только для оповещения msi о процессе установки, в ней msi должна сама создать файл, и вернуть его handle, а FDICopy будет писать в этот открытый файл.
Была ещё одна проблема: handle файла возвращался без всяких проверок. Если программа пыталась перезаписать файл, который является ссылкой (см. выше), то возвращалось handle == INVALID_HANDLE_VALUE, что соответствует -1. А возвращение функцией cabinet_notify для FDICopy означает отмену всей распаковки. Если в данном случае возвращать 0, то текущий файл не будет распаковываться, но распаковка продолжится. После сделанных изменений программа начала устанавливаться.
Сделал патч. Проверил. Всё работает
Устанавливается. Проверил со сборкой eter22
При обновлении репозитория откатил патч: commit 912b40ce507f6e8992f0b8fee8a923dcd67539b4 Author: Alexander Morozov <amorozov@etersoft.ru> Date: Wed Feb 4 13:45:52 2009 +0300 ntdll: Prevent crash (eterbug #2827). Требуется проверить сохранилась ли бага, и переделать патч
Опубликовал обновлённый eterhack. Можно проверять
Тестировал установку Компас Demo. На текущем eterhack бага не воспроизводится.
wine 7.23/14 проверил большинство версий компаса проблем при установке не обнаружено Принята
Закрываю. Выпущен давно WINE@Etersoft CAD, в котором установка происходит корректно.