[Bug 39346] Lego Rock Raiders crashes on startup (d3drm_device_init doesn't handle device version 3 case)

WineHQ Bugzilla wine-bugs at winehq.org
Wed Dec 9 15:40:51 CST 2020


https://bugs.winehq.org/show_bug.cgi?id=39346

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Lego Rock Raiders crashes   |Lego Rock Raiders crashes
                   |on startup                  |on startup
                   |                            |(d3drm_device_init doesn't
                   |                            |handle device version 3
                   |                            |case)
           Keywords|                            |download
                URL|                            |https://archive.org/downloa
                   |                            |d/LEGORockRaidersWindows/LE
                   |                            |GO_Rock_Raiders_Win_Files_E
                   |                            |N.7z
          Component|-unknown                    |directx-d3d
                 CC|                            |focht at gmx.net

--- Comment #10 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

confirming. Found a download for debugging:

https://archive.org/download/LEGORockRaidersWindows/LEGO_Rock_Raiders_Win_Files_EN.7z

--- snip ---
$ WINEDEBUG=+seh,+relay,+d3drm,+loaddll WINEDLLOVERRIDES=d3drm=b wine
LegoRR.exe >>log.txt 2>&1
...
0100:Call d3drm.Direct3DRMCreate(0031f0dc) ret=004784e7
...
0100:Ret  d3drm.Direct3DRMCreate() retval=00000000 ret=004784e7
...
0100:trace:d3drm:d3drm1_QueryInterface iface 0018C408, riid
{4516ec83-8f20-11d0-9b6d-0000c0781bc3}, out 00506914.
0100:trace:d3drm:d3drm3_AddRef 0018C410 increasing refcount to 1.
0100:trace:d3drm:d3drm3_CreateDeviceFromSurface iface 0018C410, guid
{84e63de0-46aa-11cf-816f-0000c020156e}, ddraw 00188FAC, backbuffer 0018C488,
flags 0, device 00506918.
0100:trace:d3drm:d3drm_device_create device 0031F090, d3drm 0018C408.
...
0100:trace:d3drm:d3drm_device3_GetDirect3DDevice2 iface 00187960, d3d_device
0031F0E8.
0100:fixme:d3drm:d3drm_device3_SetBufferCount iface 00187960, count 2 stub!
...
0100:fixme:d3drm:d3drm_device3_FindPreferredTextureFormat iface 00187960,
bitdepths 2048, flags 0x4, pf 0031EEFC stub!
0100:fixme:d3drm:d3drm_device3_FindPreferredTextureFormat iface 00187960,
bitdepths 1024, flags 0, pf 0031EEFC stub!
...
0100:fixme:d3drm:d3drm_device3_Update iface 00187960 stub!
...
0100:trace:d3drm:d3drm3_CreateViewport iface 0018C410, device 00187960, camera
0288FDB0, x 16, y 13, width 151, height 151, viewport 017C6C60.
0100:trace:d3drm:d3drm_viewport_create viewport 0031EEC4, d3drm 0018C408.
0100:trace:d3drm:d3drm_viewport2_Init iface 0288D5C4, device 00187960, camera
0288FDB0, x 16, y 13, width 151, height 151.
0100:trace:d3drm:d3drm1_AddRef 0018C408 increasing refcount to 37.
0100:trace:d3drm:d3drm_device3_GetDirect3DDevice iface 00187960, d3d_device
0031EE54!
0100:trace:d3drm:d3drm_frame3_QueryInterface iface 0288FDB0, riid
{eb16cb03-d271-11ce-ac48-0000c03825a1}, out 0288D5BC.
0100:trace:d3drm:d3drm_frame1_AddRef iface 0288FDA8.
0100:trace:d3drm:d3drm_frame3_AddRef 0288FDB0 increasing refcount to 3.
0100:trace:d3drm:d3drm_viewport2_SetAppData iface 0288D5C4, data 0x17c6c50
0100:fixme:d3drm:d3drm_device3_Update iface 00187960 stub!
...
0100:Call wined3d.wined3d_mutex_lock() ret=00ca4998
0100:Ret  wined3d.wined3d_mutex_lock() retval=00000000 ret=00ca4998
0100:Call wined3d.wined3d_texture_set_color_key(0415ed48,00000008,0031ee74)
ret=00ca4ac9
0100:Ret  wined3d.wined3d_texture_set_color_key() retval=00000000 ret=00ca4ac9
0100:Call wined3d.wined3d_mutex_unlock() ret=00ca4ad3
0100:Ret  wined3d.wined3d_mutex_unlock() retval=00000000 ret=00ca4ad3
0100:trace:seh:dispatch_exception code=c0000005 flags=0 addr=004809BC
ip=004809bc tid=0100
0100:trace:seh:dispatch_exception  info[0]=00000000
0100:trace:seh:dispatch_exception  info[1]=00000000
0100:trace:seh:dispatch_exception  eax=00000000 ebx=00000000 ecx=00000000
edx=0031eebc esi=01665508 edi=005415d4
0100:trace:seh:dispatch_exception  ebp=0031f1e4 esp=0031eebc cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00210212
0100:trace:seh:call_vectored_handlers calling handler at 7B00F270 code=c0000005
flags=0
0100:trace:seh:call_vectored_handlers handler at 7B00F270 returned 0
0100:trace:seh:call_stack_handlers calling handler at 00496A98 code=c0000005
flags=0
0100:Call KERNEL32.UnhandledExceptionFilter(0031e95c) ret=00495ffa
...
wine: Unhandled page fault on read access to 00000000 at address 004809BC
(thread 0100), starting debugger...
--- snip ---

Disassembly of crash site:

--- snip ---
00480910 | sub esp,54                         |
00480913 | mov eax,dword ptr ds:[50691C]      |
00480918 | lea edx,dword ptr ss:[esp]         |
0048091C | mov dword ptr ss:[esp+4],50        |
00480924 | mov dword ptr ss:[esp+8],3F800000  |
0048092C | mov dword ptr ss:[esp+C],3F800000  |
00480934 | mov dword ptr ss:[esp+10],3F800000 |
0048093C | mov dword ptr ss:[esp+14],3F800000 |
00480944 | mov dword ptr ss:[esp+18],0        |
0048094C | mov dword ptr ss:[esp+1C],0        |
00480954 | mov dword ptr ss:[esp+20],0        |
0048095C | mov dword ptr ss:[esp+24],0        |
00480964 | mov dword ptr ss:[esp+28],0        |
0048096C | mov dword ptr ss:[esp+2C],0        |
00480974 | mov dword ptr ss:[esp+30],0        |
0048097C | mov dword ptr ss:[esp+34],0        |
00480984 | mov dword ptr ss:[esp+38],0        |
0048098C | mov dword ptr ss:[esp+3C],0        |
00480994 | mov dword ptr ss:[esp+40],0        |
0048099C | mov dword ptr ss:[esp+44],0        |
004809A4 | mov dword ptr ss:[esp+48],0        |
004809AC | mov dword ptr ss:[esp+4C],0        |
004809B4 | mov dword ptr ss:[esp+50],0        |
004809BC | mov ecx,dword ptr ds:[eax]         | *boom*
004809BE | push edx                           |
004809BF | push eax                           |
004809C0 | call dword ptr ds:[ecx+2C]         |
--- snip ---

Using 'find references to address':

--- snip ---
00478557  push legorr.50691C
00478B90  mov eax,dword ptr ds:[50691C]
00478BB2  mov eax,dword ptr ds:[50691C]
00478C0E  mov eax,dword ptr ds:[50691C]
00480913  mov eax,dword ptr ds:[50691C]
004809F1  mov edx,dword ptr ds:[50691C]
...
--- snip ---

We arrive here:

--- snip ---
004784E2 | call <JMP.&_Direct3DRMCreate at 4> |
004784E7 | test eax,eax                    |
004784E9 | jne legorr.4785A6               |
004784EF | mov eax,dword ptr ss:[esp+4]    |
004784F3 | push legorr.506914              |
004784F8 | push legorr.4A0BD8              |
004784FD | push eax                        |
004784FE | mov ecx,dword ptr ds:[eax]      |
00478500 | call dword ptr ds:[ecx]         | d3drm.d3drm1_QueryInterface
00478502 | test eax,eax                    |
00478504 | jne legorr.4785A6               |
0047850A | mov eax,dword ptr ss:[esp+18]   |
0047850E | lea ecx,dword ptr ss:[esp+8]    |
00478512 | push ecx                        |
00478513 | push legorr.4A0338              |
00478518 | mov edx,dword ptr ds:[eax]      |
0047851A | push eax                        |
0047851B | call dword ptr ds:[edx]         | ddraw_surface4_QueryInterface
0047851D | mov ecx,dword ptr ss:[esp+8]    |
00478521 | mov eax,dword ptr ds:[506914]   |
00478526 | push legorr.506918              |
0047852B | push 0                          |
0047852D | mov edx,dword ptr ds:[eax]      |
0047852F | push ecx                        |
00478530 | mov ecx,dword ptr ss:[esp+20]   |
00478534 | push ecx                        |
00478535 | push esi                        |
00478536 | push eax                        |
00478537 | call dword ptr ds:[edx+3C]      | d3drm3_CreateDeviceFromSurface
0047853A | mov esi,eax                     |
0047853C | test esi,esi                    |
0047853E | jne legorr.47858F               |
00478540 | mov eax,dword ptr ds:[506918]   |
00478545 | lea ecx,dword ptr ss:[esp+10]   |
00478549 | push ecx                        |
0047854A | push eax                        |
0047854B | mov edx,dword ptr ds:[eax]      |
0047854D | call dword ptr ds:[edx+98]      | d3drm_device3_GetDirect3DDevice2
00478553 | mov eax,dword ptr ss:[esp+10]   |
00478557 | push legorr.50691C              |
0047855C | push legorr.4A06D8              |
00478561 | push eax                        |
00478562 | mov edx,dword ptr ds:[eax]      |
00478564 | call dword ptr ds:[edx]         | d3d_device2_QueryInterface
--- snip ---

Last call returns 0x80004002

Armed with that info, adding 'ddraw' to debug channels:

--- snip ---
...
0100:trace:d3drm:Direct3DRMCreate d3drm 0031F114.
0100:trace:d3drm:d3drm1_QueryInterface iface 001767A0, riid
{4516ec83-8f20-11d0-9b6d-0000c0781bc3}, out 00506914.
0100:trace:d3drm:d3drm3_AddRef 001767A8 increasing refcount to 1.
0100:trace:ddraw:ddraw_surface4_QueryInterface iface 001765AC, riid
{6c14db81-a733-11ce-a521-0020af0be560}, object 0031F118.
0100:trace:ddraw:ddraw_surface7_QueryInterface iface 001765A8, riid
{6c14db81-a733-11ce-a521-0020af0be560}, object 0031F118.
0100:trace:ddraw:ddraw_surface1_AddRef iface 001765B8 increasing refcount to 1.
0100:trace:ddraw:ddraw_surface_add_iface 001765A8 increasing iface count to 2.
0100:trace:ddraw:ddraw_surface7_QueryInterface (001765A8) returning
IDirectDrawSurface interface at 001765B8
0100:trace:d3drm:d3drm3_CreateDeviceFromSurface iface 001767A8, guid
{84e63de0-46aa-11cf-816f-0000c020156e}, ddraw 0016EE24, backbuffer 001765B8,
flags 0, device 00506918.
0100:trace:d3drm:d3drm_device_create device 0031F0C8, d3drm 001767A0.
...
0100:trace:ddraw:ddraw1_CreateSurface iface 0016EE24, surface_desc 0031F020,
surface 0031F09C, outer_unknown 00000000.
0100:trace:ddraw:ddraw_surface_create ddraw 0016EE18, surface_desc 0031EF14,
surface 0031EF10, outer_unknown 00000000, version 1.
0100:trace:ddraw:ddraw_surface_create Requesting surface desc:
0100:trace:ddraw:DDRAW_dump_members  - DDSD_CAPS : DDSCAPS_ZBUFFER
0100:trace:ddraw:DDRAW_dump_members  - DDSD_HEIGHT : 480
0100:trace:ddraw:DDRAW_dump_members  - DDSD_WIDTH : 640
0100:trace:ddraw:DDRAW_dump_members  - DDSD_PIXELFORMAT : ( DDPF_ZBUFFER , Z
bits: 16)
0100:trace:ddraw:ddrawformat_from_wined3dformat Returning: ( DDPF_RGB , RGB
bits: 16, R 0x0000f800 G 0x000007e0 B 0x0000001f)
...
0100:trace:ddraw:ddraw1_QueryInterface iface 0016EE24, riid
{6aae1ec1-662a-11d0-889d-00aa00bbb76a}, object 0031F098.
0100:trace:ddraw:ddraw7_QueryInterface iface 0016EE18, riid
{6aae1ec1-662a-11d0-889d-00aa00bbb76a}, out 0031F098.
0100:trace:ddraw:ddraw7_QueryInterface Returning Direct3D2 interface 0016EE30.
...
0100:trace:ddraw:d3d2_CreateDevice iface 0016EE30, riid
{a4665c60-2673-11cf-a31a-00aa00b93356}, surface 001765B8, device 0031F094.
0100:trace:ddraw:d3d_device_create ddraw 0016EE18, target 001765A8, version 2,
device 0031EF8C, outer_unknown 00000000.
0100:trace:ddraw:ddraw_surface1_AddRef iface 001765B8 increasing refcount to 3.
0100:trace:ddraw:ddraw_surface1_QueryInterface iface 001765B8, riid
{06675a80-3b9b-11d2-b92f-00609797ea5b}, object 0031EEF4.
0100:trace:ddraw:ddraw_surface7_QueryInterface iface 001765A8, riid
{06675a80-3b9b-11d2-b92f-00609797ea5b}, object 0031EEF4.
0100:trace:ddraw:ddraw_surface7_AddRef iface 001765A8 increasing refcount to 1.
0100:trace:ddraw:ddraw_surface_add_iface 001765A8 increasing iface count to 3.
0100:trace:ddraw:ddraw_surface7_QueryInterface (001765A8) returning
IDirectDrawSurface7 interface at 001765A8
0100:trace:ddraw:ddraw_surface7_GetAttachedSurface iface 001765A8, caps
00CCE338, attachment 0031EEF8.
0100:trace:ddraw:ddraw_surface7_GetAttachedSurface head_surface 001765A8,
looking for caps 0x20000, 0, 0, 0.
0100:trace:ddraw:ddraw_surface7_GetAttachedSurface Surface 00172070, caps
0x1000e238, 0, 0, 0.
0100:trace:ddraw:ddraw_surface7_GetAttachedSurface Surface 0017AF20, caps
0x10024000, 0, 0, 0.
0100:trace:ddraw:ddraw_surface7_GetAttachedSurface head_surface 001765A8,
returning surface 0017AF20.
...
0100:trace:ddraw:d3d_device_create Created device 0019F2C8.
0100:trace:ddraw:d3d2_Release iface 0016EE30.
0100:trace:ddraw:ddraw1_Release 0016EE18 decreasing refcount to 2.
0100:trace:ddraw:d3d_device2_QueryInterface iface 0019F2D0, riid
{64108800-957d-11d0-89ab-00a0c9054129}, out 0031F090.
0100:trace:ddraw:d3d_device_inner_QueryInterface iface 0019F2D8, riid
{64108800-957d-11d0-89ab-00a0c9054129}, out 0031F090.
0100:trace:ddraw:d3d_device1_AddRef iface 0019F2D4.
0100:trace:ddraw:d3d_device_inner_AddRef 0019F2C8 increasing refcount to 2.
0100:trace:ddraw:d3d_device2_Release iface 0019F2D0.
0100:trace:ddraw:d3d_device_inner_Release 0019F2C8 decreasing refcount to 1.
0100:trace:ddraw:d3d_device_inner_Release Done
0100:trace:d3drm:d3drm_device3_GetDirect3DDevice2 iface 001767E8, d3d_device
0031F120.
0100:trace:ddraw:d3d_device1_QueryInterface iface 0019F2D4, riid
{93281501-8cf8-11d0-89ab-00a0c9054129}, out 0031F120.
0100:trace:ddraw:d3d_device_inner_QueryInterface iface 0019F2D8, riid
{93281501-8cf8-11d0-89ab-00a0c9054129}, out 0031F120.
0100:trace:ddraw:d3d_device2_AddRef iface 0019F2D0.
0100:trace:ddraw:d3d_device_inner_AddRef 0019F2C8 increasing refcount to 2.
0100:trace:ddraw:d3d_device2_QueryInterface iface 0019F2D0, riid
{b0ab3b60-33d7-11d1-a981-00c04fd7b174}, out 0050691C.
0100:trace:ddraw:d3d_device_inner_QueryInterface iface 0019F2D8, riid
{b0ab3b60-33d7-11d1-a981-00c04fd7b174}, out 0050691C.
0100:warn:ddraw:d3d_device_inner_QueryInterface
{b0ab3b60-33d7-11d1-a981-00c04fd7b174} not implemented, returning
E_NOINTERFACE.
0100:trace:ddraw:d3d_device2_Release iface 0019F2D0.
0100:trace:ddraw:d3d_device_inner_Release 0019F2C8 decreasing refcount to 1.
0100:trace:ddraw:d3d_device_inner_Release Done
0100:fixme:d3drm:d3drm_device3_SetBufferCount iface 001767E8, count 2 stub!
...

'{b0ab3b60-33d7-11d1-a981-00c04fd7b174}' -> IDirect3DDevice3

d3drm_device3_GetDirect3DDevice2 
  -> d3d_device2_QueryInterface
       -> d3d_device_inner_QueryInterface 
             device->version == 2

The problem starts earlier with 'd3drm3_CreateDeviceFromSurface' call.

Wine source:

https://source.winehq.org/git/wine.git/blob/310019789f7bde12ae3f25f723957c975fb2f804:/dlls/d3drm/d3drm.c#l1615

--- snip ---
1615 static HRESULT WINAPI d3drm3_CreateDeviceFromSurface(IDirect3DRM3 *iface,
GUID *guid,
1616         IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, DWORD flags,
IDirect3DRMDevice3 **device)
1617 {
1618     struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1619     struct d3drm_device *object;
1620     BOOL use_z_surface;
1621     HRESULT hr;
1622 
1623     TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, flags %#x, device
%p.\n",
1624             iface, debugstr_guid(guid), ddraw, backbuffer, flags, device);
1625 
1626     if (!device)
1627         return D3DRMERR_BADVALUE;
1628     *device = NULL;
1629 
1630     if (!backbuffer || !ddraw)
1631         return D3DRMERR_BADDEVICE;
1632 
1633     if (FAILED(hr = d3drm_device_create(&object,
&d3drm->IDirect3DRM_iface)))
1634         return hr;
1635 
1636     use_z_surface = !(flags & D3DRMDEVICE_NOZBUFFER);
1637 
1638     if (SUCCEEDED(hr = d3drm_device_init(object, 3, ddraw, backbuffer,
use_z_surface)))
1639         *device = &object->IDirect3DRMDevice3_iface;
1640     else
1641         d3drm_device_destroy(object);
1642 
1643     return hr;
1644 }
--- snip ---

d3drm_device_init(object, 3, ...)

https://source.winehq.org/git/wine.git/blob/310019789f7bde12ae3f25f723957c975fb2f804:/dlls/d3drm/device.c#l120

--- snip ---
 120 HRESULT d3drm_device_init(struct d3drm_device *device, UINT version,
IDirectDraw *ddraw, IDirectDrawSurface *surface,
 121             BOOL create_z_surface)
 122 {
 123     DDSCAPS caps = { DDSCAPS_ZBUFFER };
 124     IDirectDrawSurface *ds = NULL;
 125     IDirect3DDevice *device1 = NULL;
 126     IDirect3DDevice2 *device2 = NULL;
 127     IDirect3D2 *d3d2 = NULL;
 128     DDSURFACEDESC desc, surface_desc;
 129     HRESULT hr;
 130 
 131     device->ddraw = ddraw;
 132     IDirectDraw_AddRef(ddraw);
 133     IDirect3DRM_AddRef(device->d3drm);
 134     device->render_target = surface;
 135     IDirectDrawSurface_AddRef(surface);
 136 
 137     desc.dwSize = sizeof(desc);
 138     hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
 139     if (FAILED(hr))
 140         return hr;
 141 
 142     if (!(desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE))
 143         return DDERR_INVALIDCAPS;
 144 
 145     hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds);
 146     if (SUCCEEDED(hr))
 147     {
 148         create_z_surface = FALSE;
 149         IDirectDrawSurface_Release(ds);
 150         ds = NULL;
 151     }
 152 
 153     if (create_z_surface)
 154     {
 155         memset(&surface_desc, 0, sizeof(surface_desc));
 156         surface_desc.dwSize = sizeof(surface_desc);
 157         surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH |
DDSD_WIDTH | DDSD_HEIGHT;
 158         surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
 159         surface_desc.u2.dwZBufferBitDepth = 16;
 160         surface_desc.dwWidth = desc.dwWidth;
 161         surface_desc.dwHeight = desc.dwHeight;
 162         hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &ds, NULL);
 163         if (FAILED(hr))
 164             return hr;
 165 
 166         hr = IDirectDrawSurface_AddAttachedSurface(surface, ds);
 167         IDirectDrawSurface_Release(ds);
 168         if (FAILED(hr))
 169             return hr;
 170     }
 171 
 172     if (version == 1)
 173         hr = IDirectDrawSurface_QueryInterface(surface,
&IID_IDirect3DRGBDevice, (void **)&device1);
 174     else
 175     {
 176         IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D2, (void**)&d3d2);
 177         hr = IDirect3D2_CreateDevice(d3d2, &IID_IDirect3DRGBDevice,
surface, &device2);
 178         IDirect3D2_Release(d3d2);
 179     }
 180     if (FAILED(hr))
 181     {
 182         IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds);
 183         return hr;
 184     }
 185 
 186     if (version != 1)
 187     {
 188         hr = IDirect3DDevice2_QueryInterface(device2,
&IID_IDirect3DDevice, (void**)&device1);
 189         IDirect3DDevice2_Release(device2);
 190         if (FAILED(hr))
 191         {
 192             IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds);
 193             return hr;
 194         }
 195     }
 196     device->device = device1;
 197     device->width = desc.dwWidth;
 198     device->height = desc.dwHeight;
 199 
 200     return hr;
 201 }
--- snip ---

I'm not an expert on this but for me it seems that version == 3 case is not
handled here. The code uses IDirect3D2_CreateDevice for all cases != 1 which
later leads to the problem that 'IDirect3DDevice3' interface can't be queried
by design. It should be using 'IDirect3D3_CreateDevice' for version == 3 case.

$ sha1sum LEGO_Rock_Raiders_Win_Files_EN.7z 
7cc3857fb6f1c7063c665ca4e88d62c8fcdadaed  LEGO_Rock_Raiders_Win_Files_EN.7z

$ du -sh LEGO_Rock_Raiders_Win_Files_EN.7z 
397M    LEGO_Rock_Raiders_Win_Files_EN.7z

$ wine --version
wine-6.0-rc1-29-g310019789f7

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.


More information about the wine-bugs mailing list