Hello,
I am trying to implement the GetDC method for wine d3d surfaces, as it is used
by much d3d7 apps to load the textures. I took the code from
ddraw/surface_dib.c and modified it, but I am stuck with a heap corruption.
Basically, what I am doing is:
1) Lock the surface
2) Create a DIB section with DIB_CreateDIBSection. Use the currentDesc.
{Width / Height} as the dimension and bytesPerPixel * 8 for the bitcount. The
memory for the DC is the pBits returned from LockRect()
3) Create a DC, and attach it to the dib section
4) Set the palette, if necessary.
In ReleaseDC I release the DC, destroy the DIB section and unlock the surface.
Looks nice so far, but it doesn't work.
I get a heap corruption eighter when using the DC or when deleting it. An
example winedbg output:
err:d3d_surface:IWineD3DSurfaceImpl_GetDC (0x7fd8fb08)->(0x7fbafd94): This
does not work yet
trace:d3d_surface:IWineD3DSurfaceImpl_LockRect (0x7fd8fb08) : rect@(nil)
flags(00000000), output lockedRect@0x7fbaf4a8, memory@(nil)
trace:d3d_surface:IWineD3DSurfaceImpl_LockRect Locked Rect (0x7fd8fb78) = l 0,
t 0, r 640, b 480
trace:d3d_surface:IWineD3DSurfaceImpl_LockRect Locking non-power 2 texture
trace:d3d_surface:IWineD3DSurfaceImpl_LockRect locking an ordinarary surface
trace:d3d_surface:IWineD3DSurfaceImpl_LockRect (0x7fd8fb08) Locking rect
trace:d3d_surface:IWineD3DSurfaceImpl_AddDirtyRect (0x7fd8fb08) : Dirty?1,
Rect:(0,0,640,480)
trace:d3d_surface:IWineD3DSurfaceImpl_GetContainer (0x7fd8fb08) : Relaying to
queryInterface 0x7fbaf3fc (nil)
trace:d3d_surface:IWineD3DSurfaceImpl_GetContainer (0x7fd8fb08) : Relaying to
queryInterface 0x7fbaf454 0xb7effbda
trace:d3d_surface:IWineD3DSurfaceImpl_LockRect Surface is standalone, no need
to dirty the container
trace:d3d_surface:IWineD3DSurfaceImpl_LockRect returning memory@0x7dfa0020,
pitch(4096) dirtyfied(1)
trace:d3d_surface:IWineD3DSurfaceImpl_GetDC Creating dip section 640x480x32.
memory at 0x7dfa0020 is 2097152 bytes of size
trace:d3d_surface:IWineD3DSurfaceImpl_GetDC returning 0x278
trace:d3d_surface:IWineD3DSurfaceImpl_ReleaseDC (0x7fd8fb08)->(0x278)
trace:d3d_surface:IWineD3DSurfaceImpl_ReleaseDC Selecting the object DC
First chance exception: page fault on read access to 0x7dfa0000 in 32-bit code
(0x7ff99374).
Register dump:
CS:0073 SS:007b DS:007b ES:007b FS:003b GS:0033
EIP:7ff99374 ESP:7fbaf714 EBP:7fbaf718 EFLAGS:00010206( - 00 - RIP1)
EAX:7fce0000 EBX:7ffd5540 ECX:7e5c0250 EDX:7dfa0000
ESI:7e5c0248 EDI:7fce0040
Stack dump:
0x7fbaf714: 00000030 7fbaf754 7ff99c0b 7fce0000
0x7fbaf724: 7e5c0248 7f712cd0 00000000 00004f4c
0x7fbaf734: 7ff99294 7fd8fee8 7e5c0248 7ff8dffa
0x7fbaf744: 7f6edf2b 7ffd5540 00000030 00000030
0x7fbaf754: 7fbaf798 7ff9a954 7fce0000 00000030
0x7fbaf764: 7fbaf788 7f70253b 0000027c 00004f4c
Backtrace:
=>1 0x7ff99374 HEAP_FindSubHeap+0x14(heap=0x7fce0000, ptr=0x7e5c0248)
[heap.c:375] in ntdll (0x7ff99374)
2 0x7ff99c0b HEAP_FindFreeBlock+0x7b(heap=0x7fce0000, size=0x30,
ppSubHeap=0x7fbaf788) [/usr/src/wine-wined3d/dlls/ntdll/heap.c:390] in ntdll
(0x7ff99c0b)
3 0x7ff9a954 RtlAllocateHeap(heap=0x7fce0000, flags=0x2, size=0x30)
[/usr/src/wine-wined3d/dlls/ntdll/heap.c:1163] in ntdll (0x7ff9a954)
q
4 0x7f263905 X11DRV_GetRegionData+0x55(hrgn=0x27c, hdc_lptodp=0x0)
[/usr/src/wine-wined3d/dlls/x11drv/../../include/winbase.h:2250] in winex11
(0x7f263905)
5 0x7f263aa6 X11DRV_SetDeviceClipping+0x56(physDev=0x7fd8fe68,
vis_rgn=0x280, clip_rgn=0x0)
[/usr/src/wine-wined3d/dlls/x11drv/clipping.c:118] in winex11 (0x7f263aa6)
6 0x7f6c6a1e CLIPPING_UpdateGCRegion+0xae(dc=0x7e1a0028) [clipping.c:80] in
gdi32 (0x7f6c6a1e)
7 0x7f6c84fa DC_InitDC+0x9a(dc=0x7e1a0028)
[/usr/src/wine-wined3d/dlls/gdi/dc.c:205] in gdi32 (0x7f6c84fa)
8 0x7f6c5c06 BITMAP_SelectObject(handle=0x6c, obj=0x7fce5d20, hdc=0x278)
[/usr/src/wine-wined3d/dlls/gdi/bitmap.c:568] in gdi32 (0x7f6c5c06)
9 0x7f6eea05 SelectObject(hdc=0x278, hObj=0x6c)
[/usr/src/wine-wined3d/dlls/gdi/gdiobj.c:1164] in gdi32 (0x7f6eea05)
10 0x7f5ecd10 IWineD3DSurfaceImpl_ReleaseDC+0x50(iface=0x7fd8fb08,
hDC=0x278) [/usr/src/wine-wined3d/dlls/wined3d/surface.c:1068] in wined3d
(0x7f5ecd10)
q
11 0x7fa7e0e8 IDirectDrawSurfaceImpl_ReleaseDC+0x38(iface=0x7fd8fa48,
hdc=0x278) [/usr/src/wine-wined3d/dlls/ddraw/surface.c:472] in ddraw
(0x7fa7e0e8)
12 0x7fbd5fe6 main in ddrawex (0x7fbd5fe6)
13 0x7fbd63a7 __wine_spec_exe_entry(peb=0x7ffdf540) [exe_entry.c:37] in
ddrawex (0x7fbd63a7)
14 0x7fc490a0 start_process(arg=0x0)
[/usr/src/wine-wined3d/dlls/kernel/process.c:1027] in kernel32 (0x7fc490a0)
15 0xb7f020fb wine_switch_to_stack+0x17 in libwine.so.1 (0xb7f020fb)
0x7ff99374 HEAP_FindSubHeap+0x14 [heap.c:375] in ntdll: movl 0x0(%edx),%ecx
Unable to open file 'heap.c'
Wine-dbg>
I am lost here, can someone help me? Can this code work at all? I've attached
my copy of dlls/wined3d/surface.c, so you can see the code(Watch out, it
won't compile as such in the CVS tree).
The dib member of WineD3DSurface is taken from ddraw:
typedef struct wineD3DSurface_DIB {
HBITMAP DIBsection;
void* bitmap_data;
HGDIOBJ holdbitmap;
BOOL client_memory;
DWORD d3d_data[4]; /* room for Direct3D driver data */
} wineD3DSurface_DIB;
Stefan