Bug 1372

Summary: модуль cabinet.dll: WINE падает после некорректного вызова FDICopy()
Product: WINE@Etersoft Reporter: Виталий Перов <vitperov>
Component: Консоль ; Вызов программAssignee: Виталий Перов <vitperov>
Status: CLOSED INVALID QA Contact:
Severity: minor    
Priority: P5 CC: lav
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Linux   
Whiteboard:
Заявки RT: Связано с:
Дата напоминания:
Bug Depends on:    
Bug Blocks: 1217    

Description Виталий Перов 2008-03-13 19:29:30 MSK
При вызове FDICopy() ей, в качестве параметра, надо передавать адрес
функции, которая будет показывать статус распаковки

 5-й параметр FDICopy() - PFNFDINOTIFY   pfnfdin
Описание MSDN:
pfnfdin
    A pointer to a file notification function that is called periodically to
update the application on the status of the decoder. For more information, see
Remarks.

Сама функция выглядит примерно так:
INT_PTR __cdecl CopyProgress (FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
{
    return FALSE;
}

Когда функция возвращет FALSE, то всё нормально. Но если она возвращает TRUЕ, или вообще ничего не возвращает, то wine падает, сообщая:
wine: Unhandled page fault on read access to 0x00000008 at address 0x7ec9b867 (thread 0009), starting debugger...
Unhandled exception: page fault on read access to 0x00000008 in 32-bit code (0x7ec9b867).
....
далее следует содержание регистров процессора и стек вызовов

Тест, воспроизводящий данную ошибку, добавил в:
wine-etersoft-public/patches/check/test-cabinet-FDICopy-system_crashes.patch
Comment 1 Виталий Перов 2008-03-13 19:36:42 MSK
а дело в том, что
вначале функции FDICopy() определено:
struct fdi_folder *fol = NULL

где-то внутри (fdi.c:2511) происходит вызов функции, которая должна показывать прогресс распаковки.
Если она возвратит true, то выполняется код, а в конце стоит goto bail_and_fail;

Первая комманда после метки bail_and_fail:
switch (fol->comp_type & .....

Здесь и происходит обращение по несуществующему адресу.
Comment 2 Виталий Перов 2008-03-13 19:45:10 MSK
По-моему простой проверки на правильность указателя *fol не достаточно. Для корректного освобождения памяти надо почти полностью переписывать код после метки bail_and_fail
Comment 3 Виталий Перов 2008-04-10 17:00:20 MSD
Никакой ошибки нет, просто мы длолжны возвращать указатель на int. Если мы возвращаем FALSE, т.е  NULL, то, всё нормально, а если какое-то другое число, то вызывающая функция пытается прочитать по указанному адресу. Память не выделена, возникает ошибка. 
Только вот странно, почему винда в этом случае нормально реагирует.