https://bugs.winehq.org/show_bug.cgi?id=38967
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW CC| |focht@gmx.net Component|-unknown |ole32 Summary|Lotus Approach crashes on |Lotus Approach from Lotus |start |Smartsuite 9.8 crashes on | |startup (failure to read | |from OLE compound document | |files) Ever confirmed|0 |1
--- Comment #2 from Anastasius Focht focht@gmx.net --- Hello folks,
confirming.
No, it's not dupe of bug 19661 (that is win16 brain damage/garbage).
--- snip --- $ pwd /home/focht/.wine/drive_c/lotus/approach
$ WINEDEBUG=+tid,+seh,+relay,+ole,+storage wine ./approach.exe >>log.txt 2>&1 ... 002c:Call ole32.StgIsStorageFile(0032c500 L"C:\lotus\smasters\approach\db2www.mpr") ret=5f1038e2 002c:trace:storage:StgIsStorageFile L"C:\lotus\smasters\approach\db2www.mpr" 002c:Call KERNEL32.CreateFileW(0032c500 L"C:\lotus\smasters\approach\db2www.mpr",80000000,00000007,00000000,00000003,00000080,00000000) ret=7e8b97e3 002c:Ret KERNEL32.CreateFileW() retval=00000104 ret=7e8b97e3 002c:Call KERNEL32.ReadFile(00000104,0032c47c,00000008,0032c478,00000000) ret=7e8b9822 002c:Ret KERNEL32.ReadFile() retval=00000001 ret=7e8b9822 002c:Call KERNEL32.CloseHandle(00000104) ret=7e8b988e 002c:Ret KERNEL32.CloseHandle() retval=00000001 ret=7e8b988e 002c:trace:storage:StgIsStorageFile -> YES 002c:Ret ole32.StgIsStorageFile() retval=00000000 ret=5f1038e2 ... 002c:Call ole32.StgOpenStorage(0032c4e8 L"C:\lotus\smasters\approach\db2www.mpr",00000000,00000020,00000000,00000000,0032c6fc) ret=5f1037db 002c:trace:storage:StgOpenStorage (L"C:\lotus\smasters\approach\db2www.mpr", (nil), 20, (nil), 0, 0x32c6fc) 002c:Call KERNEL32.CreateFileW(0032c4e8 L"C:\lotus\smasters\approach\db2www.mpr",80000000,00000001,00000000,00000003,10000080,00000000) ret=7e8b81ff 002c:Ret KERNEL32.CreateFileW() retval=00000104 ret=7e8b81ff 002c:Call KERNEL32.GetFileSize(00000104,00000000) ret=7e8b827e 002c:Ret KERNEL32.GetFileSize() retval=000a7600 ret=7e8b827e ... 002c:trace:storage:StorageImpl_LoadFileHeader 002c:trace:storage:FileLockBytesImpl_ReadAt (0x15a7a0)-> 0 0x32b008 512 0x32affc ... 002c:trace:storage:FileLockBytesImpl_ReadAt finished 002c:trace:storage:StorageImpl_ReadDirEntry storage name: L"Root Entry" 002c:Call ntdll.RtlAllocateHeap(00110000,00000000,00002044) ret=7e8b5947 002c:Ret ntdll.RtlAllocateHeap() retval=02250380 ret=7e8b5947 002c:trace:storage:BlockChainStream_ReadAt (0x224bcc8)-> 0 0x32b064 128 0x32b01c 002c:trace:storage:StorageImpl_ReadDirEntry storage name: L"Root Entry" 002c:Call ntdll.RtlAllocateHeap(00110000,00000000,000000c0) ret=7e8b5444 002c:Ret ntdll.RtlAllocateHeap() retval=0224dd18 ret=7e8b5444 002c:trace:storage:FileLockBytesImpl_ReadAt (0x15a7a0)-> 512 0x32a180 512 0x32a12c 002c:Call KERNEL32.SetFilePointerEx(00000104,00000200,00000000,00000000,00000000) ret=7e879f7b 002c:Ret KERNEL32.SetFilePointerEx() retval=00000001 ret=7e879f7b 002c:Call KERNEL32.ReadFile(00000104,0032a180,00000200,0032a064,00000000) ret=7e879fbe 002c:Ret KERNEL32.ReadFile() retval=00000001 ret=7e879fbe 002c:trace:storage:FileLockBytesImpl_ReadAt finished ... 002c:trace:storage:StorageBaseImpl_AddRef (0x2249a40) AddRef to 3 002c:trace:storage:StorageBaseImpl_Release (0x2249a40) ReleaseRef to 2 002c:Call KERNEL32.lstrcpynA(0032ca0c,0032c744 "C:\lotus\smasters\approach\db2www.mpr",0000007f) ret=0044a8b4 002c:Ret KERNEL32.lstrcpynA() retval=0032ca0c ret=0044a8b4 002c:Call KERNEL32.lstrlenA(006bdf34 "INFO") ret=5f10f730 002c:Ret KERNEL32.lstrlenA() retval=00000004 ret=5f10f730 002c:Call KERNEL32.MultiByteToWideChar(00000000,00000000,006bdf34 "INFO",00000005,0032c50c,00000005) ret=5f10f745 002c:Ret KERNEL32.MultiByteToWideChar() retval=00000005 ret=5f10f745 002c:trace:storage:StorageBaseImpl_OpenStream (0x2249a40, L"INFO", (nil), 10, 0, 0x32c71c) 002c:trace:storage:BlockChainStream_ReadAt (0x224bcc8)-> 0 0x32c2d4 128 0x32c28c 002c:trace:storage:StorageImpl_ReadDirEntry storage name: L"Root Entry" 002c:trace:storage:BlockChainStream_ReadAt (0x224bcc8)-> 256 0x32c2d4 128 0x32c28c 002c:trace:storage:StorageImpl_ReadDirEntry storage name: L"USERS" 002c:trace:storage:BlockChainStream_ReadAt (0x224bcc8)-> 128 0x32c2d4 128 0x32c28c 002c:trace:storage:StorageImpl_ReadDirEntry storage name: L"INFO" 002c:Call ntdll.RtlAllocateHeap(00110000,00000000,00000028) ret=7e8a92f2 002c:Ret ntdll.RtlAllocateHeap() retval=0015b890 ret=7e8a92f2 002c:trace:storage:StorageBaseImpl_AddStream Stream added (stg=0x2249a40 strm=0x15b890) 002c:trace:storage:StorageBaseImpl_OpenStream <-- IStream 0x15b890 002c:trace:storage:StorageBaseImpl_OpenStream <-- 00000000 ... 002c:trace:storage:StgStreamImpl_Stat 0x15b890 0x32ca8c 0 002c:trace:storage:BlockChainStream_ReadAt (0x224bcc8)-> 128 0x32c554 128 0x32c50c 002c:trace:storage:StorageImpl_ReadDirEntry storage name: L"INFO" 002c:Call ntdll.RtlAllocateHeap(00110000,00000000,0000000a) ret=7e882307 002c:Ret ntdll.RtlAllocateHeap() retval=0015a660 ret=7e882307 002c:Call ole32.CoGetMalloc(00000001,0032c6d0) ret=5f102011 002c:Ret ole32.CoGetMalloc() retval=00000000 ret=5f102011 002c:Call ntdll.RtlAllocateHeap(00110000,00000000,00000005) ret=7e882307 002c:Ret ntdll.RtlAllocateHeap() retval=0015a678 ret=7e882307 002c:Call KERNEL32.WideCharToMultiByte(00000000,00000000,0015a660 L"INFO",00000005,0015a678,00000005,00000000,00000000) ret=5f10f899 002c:Ret KERNEL32.WideCharToMultiByte() retval=00000005 ret=5f10f899 002c:Call ole32.CoGetMalloc(00000001,0032c6e8) ret=5f102043 002c:Ret ole32.CoGetMalloc() retval=00000000 ret=5f102043 002c:Call ntdll.RtlFreeHeap(00110000,00000000,0015a660) ret=7e882758 002c:Ret ntdll.RtlFreeHeap() retval=00000001 ret=7e882758 002c:trace:storage:StgStreamImpl_Read (0x15b890, 0x18313ac, 277, (nil)) 002c:trace:storage:BlockChainStream_ReadAt (0x224bcc8)-> 128 0x32c4f4 128 0x32c4ac 002c:trace:storage:StorageImpl_ReadDirEntry storage name: L"INFO" 002c:Call ntdll.RtlAllocateHeap(00110000,00000000,00002044) ret=7e8b5947 002c:Ret ntdll.RtlAllocateHeap() retval=02252e68 ret=7e8b5947 002c:trace:storage:BlockChainStream_ReadAt (0x224bcc8)-> 128 0x32c394 128 0x32c34c 002c:trace:storage:StorageImpl_ReadDirEntry storage name: L"INFO" 002c:Call ntdll.RtlAllocateHeap(00110000,00000000,000000c0) ret=7e8b5444 002c:Ret ntdll.RtlAllocateHeap() retval=0015aa48 ret=7e8b5444 002c:trace:storage:FileLockBytesImpl_ReadAt (0x15a7a0)-> 512 0x32b4b0 512 0x32b45c 002c:Call KERNEL32.SetFilePointerEx(00000104,00000200,00000000,00000000,00000000) ret=7e879f7b 002c:Ret KERNEL32.SetFilePointerEx() retval=00000001 ret=7e879f7b 002c:Call KERNEL32.ReadFile(00000104,0032b4b0,00000200,0032b394,00000000) ret=7e879fbe 002c:Ret KERNEL32.ReadFile() retval=00000001 ret=7e879fbe 002c:trace:storage:FileLockBytesImpl_ReadAt finished 002c:warn:storage:StorageImpl_GetNextBlockInChain depotBlockCount 8388607, bigBlockDepotCount 11 .. 002c:trace:storage:StgStreamImpl_Read <-- 8007000e ... 002c:trace:storage:StgStreamImpl_Release (0x15b890) 002c:trace:storage:StorageBaseImpl_RemoveStream Stream removed (stg=0x2249a40 strm=0x15b890) ... 002c:Call msvcrt.strstr(00000000,0032caf4 "\n\n") ret=00467f01 002c:trace:seh:raise_exception code=c0000005 flags=0 addr=0xf73a21ed ip=f73a21ed tid=002c 002c:trace:seh:raise_exception info[0]=00000000 002c:trace:seh:raise_exception info[1]=00000000 002c:trace:seh:raise_exception eax=f74ec000 ebx=00000000 ecx=00000000 edx=00000008 esi=0032c730 edi=00000000 002c:trace:seh:raise_exception ebp=0032caf4 esp=0032c670 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010202 002c:trace:seh:call_vectored_handlers calling handler at 0x7d965bd2 code=c0000005 flags=0 --- snip ---
The app reads from a compound storage document and parses the returned block data.
The memory block is initialized with patterns prior to calling 'ole32.StgStreamImpl_Read()':
--- snip --- 00A809A0 00 00 00 00 8C 09 C9 00 01 01 01 01 01 01 01 01 00A809B0 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00A809C0 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00A809D0 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00A809E0 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00A809F0 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00A80A00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00A80A10 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00A80A20 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00A80A30 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00A80A40 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00A80A50 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 00A80A60 01 01 01 01 01 01 01 01 01 01 01 00 54 0A DF 00 .T... 00A80A70 4C 6F 74 75 73 20 41 70 70 72 6F 61 63 68 0D 0A .Lotus Approach.. --- snip ---
After 'ole32.StgStreamImpl_Read':
--- snip --- 00A809A0 00 00 00 00 8C 09 C9 00 4C 6F 74 75 73 20 41 70 ........Lotus Ap 00A809B0 70 72 6F 61 63 68 0A 0A 43 6F 6E 74 61 63 74 20 proach..Contact 00A809C0 4D 61 6E 61 67 65 72 20 53 6D 61 72 74 4D 61 73 Manager SmartMas 00A809D0 74 65 72 0A 0A 4D 61 6E 61 67 65 73 20 63 6F 6E ter..Manages con 00A809E0 74 61 63 74 73 20 69 6E 63 6C 75 64 69 6E 67 20 tacts including 00A809F0 61 63 74 69 6F 6E 20 69 74 65 6D 73 2C 20 63 61 action items, ca 00A80A00 6C 6C 20 64 65 74 61 69 6C 2C 20 64 69 72 65 63 ll detail, direc 00A80A10 74 20 64 69 61 6C 20 69 6E 66 6F 72 6D 61 74 69 t dial informati 00A80A20 6F 6E 2C 20 61 6E 64 20 6D 61 73 73 20 6D 61 69 on, and mass mai 00A80A30 6C 69 6E 67 20 73 75 70 70 6F 72 74 2E 0A 0A 0A ling support.... 00A80A40 0A 31 31 2F 36 2F 39 35 0A 0A 36 3A 31 36 20 41 .11/6/95..6:16 A 00A80A50 4D 0A 0A 31 31 2F 32 30 2F 39 36 0A 0A 37 3A 34 M..11/20/96..7:4 00A80A60 31 20 50 4D 0A 0A 33 30 0A 0A 01 00 54 0A DF 00 1 PM..30....T.ß. 00A80A70 4C 6F 74 75 73 20 41 70 70 72 6F 61 63 68 0D 0A Lotus Approach.. --- snip ---
The app loops over the block data and replaces any occurrence of '\n\n' with '\r\n'.
--- snip --- 00A809A0 00 00 00 00 8C 09 C9 00 4C 6F 74 75 73 20 41 70 ........Lotus Ap 00A809B0 70 72 6F 61 63 68 0D 0A 43 6F 6E 74 61 63 74 20 proach..Contact 00A809C0 4D 61 6E 61 67 65 72 20 53 6D 61 72 74 4D 61 73 Manager SmartMas 00A809D0 74 65 72 0D 0A 4D 61 6E 61 67 65 73 20 63 6F 6E ter..Manages con 00A809E0 74 61 63 74 73 20 69 6E 63 6C 75 64 69 6E 67 20 tacts including 00A809F0 61 63 74 69 6F 6E 20 69 74 65 6D 73 2C 20 63 61 action items, ca 00A80A00 6C 6C 20 64 65 74 61 69 6C 2C 20 64 69 72 65 63 ll detail, direc 00A80A10 74 20 64 69 61 6C 20 69 6E 66 6F 72 6D 61 74 69 t dial informati 00A80A20 6F 6E 2C 20 61 6E 64 20 6D 61 73 73 20 6D 61 69 on, and mass mai 00A80A30 6C 69 6E 67 20 73 75 70 70 6F 72 74 2E 0D 0A 0D ling support.... 00A80A40 0A 31 31 2F 36 2F 39 35 0D 0A 36 3A 31 36 20 41 .11/6/95..6:16 A 00A80A50 4D 0D 0A 31 31 2F 32 30 2F 39 36 0D 0A 37 3A 34 M..11/20/96..7:4 00A80A60 31 20 50 4D 0D 0A 33 30 0D 0A 01 00 54 0A DF 00 1 PM..30....T.ß. 00A80A70 4C 6F 74 75 73 20 41 70 70 72 6F 61 63 68 0D 0A Lotus Approach.. --- snip ---
It then proceeds further...
The app has some crappy error handling in case the storage stream reader returns failure (such as 'E_OUTOFMEMORY').
It detects the failure, releases the storage stream and resets the block ptr to zero but still calls the code to parse data from the block, passing ptr which is now NULL.
I've used some other tools on that compound storage file to check the validity.
'Structured Storage Viewer' -> http://www.mitec.cz/ssv.html 'Compound File Explorer (CFX)' -> http://coco.co.uk/developers/CFX.html
Those tools make use of ole32 (= Wine's impl) to read content of compound storage and get it wrong too. Although the storage root directory structure can be read and displayed, the entry values are completely off (size, creation/access/modified dates etc.). There is also failure to read certain file entries, such as 'INFO' (same where 'Lotus Approach' fails at).
One tool I found reliably to work is from here:
--- quote --- MVOLE is program for reading Microsoft OLE Storage file (such as MS Word .doc or MS Excel .xls). You can get content of any OLE object in this file, even it is damaged. OLE object's content may be translated from MS Office UNICODE format to plain text with correct charset, HTML and binary format (for pictures).
Code of MVOLE is based on original code of cole library, but it is more stable and it can work with damaged and truncated files. See readme.txt for more information --- quote ---
Guess .. it uses its own compound storage reader code, based off 'cole' library.
--- snip --- $ wine ./mvole.exe list "db2www.mpr"
MVOLE Ms OLE storage manipulation 0.30b by Andrey S. Cherepanov & Tomasz Lis, 2001-2007 ------------------------------- Mounting OLE file db2www.mpr, size 685568 bytes... Reading big blocks allocation table... Info: Allocated memory for 11 BD alloc. table blocks Info: Processing allocation table part 0, entry 000000 Info: Processing allocation table part 1, entry 000080 Info: Processing allocation table part 2, entry 000100 Info: Processing allocation table part 3, entry 000180 Info: Processing allocation table part 4, entry 0001fd Info: Processing allocation table part 5, entry 000259 Info: Processing allocation table part 6, entry 0002e2 Info: Processing allocation table part 7, entry 0002e3 Info: Processing allocation table part 8, entry 0002e4 Info: Processing allocation table part 9, entry 000452 Info: Processing allocation table part 10, entry 000453 Info: Readed 5632 bytes of Big Block depot Info: Filled 1408 entries of BD allocation table Reading small blocks allocation table... Info: Processing allocation entry 000002 to extract block Info: Processing allocation entry 000015 to extract block ... Info: Processing allocation entry 000237 to extract block Info: Loaded 11264 bytes to form SD alloc. table Info: Created 2816 entries in SD alloc. table Reading root entry... Info: Processing allocation entry 000001 to extract block Info: Processing allocation entry 000004 to extract block Info: Processing allocation entry 000005 to extract block ... Info: Processing allocation entry 000535 to extract block Reading objects tree... Info: Created entry "Root Entry"; size 174208, first alloc entry 000003 Info: Created entry "INFO"; size 277, first alloc entry 000000 Info: Created entry "USERS"; size 223, first alloc entry 0000de Info: Created entry "PRIVILEGES"; size 70, first alloc entry 000005 Info: Created entry "SCRIPT"; size 415, first alloc entry 00019e Info: Created entry "ApproachDoc"; size 447, first alloc entry 0001be Info: Created entry "OPENING"; size 479, first alloc entry 0001de Info: Created entry "Body"; size 513, first alloc entry 0001fe ... Info: Created entry "CurrentView"; size 1884, first alloc entry 000a84 Info: Entry 382 does not exist, skipped Info: Entry 383 does not exist, skipped Done, file mounted. block: 11(0), ext.block: 0, num of real blocks: 1339(685568 bytes) --- 0: ROOT 174208 Root Entry 1: FILE 277 INFO 2: DIR 223 USERS 3: FILE 70 PRIVILEGES 4: DIR 415 SCRIPT 5: DIR 447 ApproachDoc 6: DIR 479 OPENING 7: DIR 513 Body 8: FILE 4 ObjText.e 9: FILE 0 ObjText.o ... 374: FILE 4825 A007AppAppObj888.o 375: FILE 5666 A007AppAppObj888.s 376: FILE 69484 A007ApprGlobObj897.o 377: FILE 186772 A007ApprGlobObj897.s 378: FILE 4 VERSION 379: FILE 115043 DOCUMENT 380: DIR 4 QUICKVIEW 381: FILE 1884 CurrentView --- snip ---
$ sha1sum Lotus\ SmartSuite\ 9.8\ -\ Int\ English.exe 889d337d6a6f2a0c25978ce2168b86ea5e8a4069 Lotus SmartSuite 9.8 - Int English.exe
$ du -sh Lotus\ SmartSuite\ 9.8\ -\ Int\ English.exe 149M Lotus SmartSuite 9.8 - Int English.exe
$ wine --version wine-1.7.47-196-g4e6e9a1
Regards