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