From b2b014afd2c69e18dae2fbf1aeb1ff8b6def4e93 Mon Sep 17 00:00:00 2001 From: cracyc Date: Mon, 12 Jul 2021 14:19:20 -0500 Subject: [PATCH 1/2] make createbitmap at screen depth a dib and map it into a hglobal --- gdi/gdi.c | 25 +++++++++++++++++++++++++ krnl386/global.c | 24 ++++++++++++++++++++++-- krnl386/krnl386.def | 1 + krnl386/krnl386.exe16.spec | 1 + 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/gdi/gdi.c b/gdi/gdi.c index 3d09b50a862..ee61a54ac6d 100644 --- a/gdi/gdi.c +++ b/gdi/gdi.c @@ -65,6 +65,7 @@ static HGDIOBJ16 stock[STOCK_LAST + 1] = {0}; void WINAPI DibMapGlobalMemory(WORD sel, void *base, DWORD size); void WINAPI DibUnmapGlobalMemory(void *base, DWORD size); +void WINAPI GlobalMapInternal(WORD sel, void *base, DWORD size); struct dib_driver { struct list entry; @@ -651,6 +652,7 @@ static SEGPTR alloc_segptr_bits( HBITMAP bmp, void *bits32 ) bits->bmp = HBITMAP_16( bmp ); bits->count = (size + 0xffff) / 0x10000; bits->sel = AllocSelectorArray16( bits->count ); + GlobalMapInternal(bits->sel, bits32, size); for (i = 0; i < bits->count; i++) { @@ -672,6 +674,7 @@ static void free_segptr_bits( HBITMAP16 bmp ) if (bits->bmp != bmp) continue; for (i = 0; i < bits->count; i++) FreeSelector16( bits->sel + (i << __AHSHIFT) ); + GlobalMapInternal(bits->sel, NULL, 0); list_remove( &bits->entry ); HeapFree( GetProcessHeap(), 0, bits ); return; @@ -1588,6 +1591,28 @@ HBITMAP16 WINAPI CreateBitmap16( INT16 width, INT16 height, UINT16 planes, ReleaseDC(NULL, dc); return HBITMAP_16(ret); } + else if ((planes == 1) && ((bpp > 8))) + { + HDC dc = GetDC(NULL); + if (bpp == GetDeviceCaps(dc, BITSPIXEL)) + { + BITMAPINFO bmpinfo = {0}; + VOID *bmp; + HDC16 dc16 = HDC_16(dc); + bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmpinfo.bmiHeader.biWidth = width; + bmpinfo.bmiHeader.biHeight = -height; + bmpinfo.bmiHeader.biPlanes = 1; + bmpinfo.bmiHeader.biBitCount = bpp; + HBITMAP16 ret = CreateDIBSection16(dc16, &bmpinfo, DIB_RGB_COLORS, &bmp, NULL, NULL); + if (bits) + SetDIBits(dc, HBITMAP_32(ret), 0, height, bits, &bmpinfo, DIB_RGB_COLORS); + ReleaseDC(NULL, dc); + return ret; + } + ReleaseDC(NULL, dc); + } + return HBITMAP_16( CreateBitmap( width, height, planes & 0xff, bpp & 0xff, bits ) ); } diff --git a/krnl386/global.c b/krnl386/global.c index cfafe607ebf..6077fd34d94 100644 --- a/krnl386/global.c +++ b/krnl386/global.c @@ -383,6 +383,8 @@ HGLOBAL16 WINAPI GlobalReAlloc16( } pArena = GET_ARENA_PTR( handle ); + if (pArena->wType == GT_INTERNAL) + return 0; /* Discard the block if requested */ if ((size == 0) && (flags & GMEM_MOVEABLE) && !(flags & GMEM_MODIFY)) @@ -563,10 +565,13 @@ HGLOBAL16 WINAPI GlobalFree16( WARN("Invalid handle 0x%04x passed to GlobalFree16!\n",handle); return 0; } - ptr = GET_ARENA_PTR(handle)->base; + GLOBALARENA *pArena = GET_ARENA_PTR(handle); + ptr = pArena->base; + if (pArena->wType == GT_INTERNAL) + return 0; TRACE("%04x\n", handle ); - if (GET_ARENA_PTR(handle)->dib_avail_size) + if (pArena->dib_avail_size) { FIXME("DIB.DRV\n"); return 0; @@ -1353,3 +1358,18 @@ void WINAPI DibUnmapGlobalMemory(void *base, DWORD size) } } } + +void WINAPI GlobalMapInternal(WORD sel, void *base, DWORD size) +{ + GLOBALARENA *pArena = GET_ARENA_PTR(sel); + if (!sel || pArena->base) + return; + if (!base || !size) + { + memset(pArena, 0, sizeof(GLOBALARENA)); + return; + } + pArena->base = base; + pArena->size = size; + pArena->wType = GT_INTERNAL; +} diff --git a/krnl386/krnl386.def b/krnl386/krnl386.def index b7cbf9dbb31..1c01c16b500 100644 --- a/krnl386/krnl386.def +++ b/krnl386/krnl386.def @@ -225,6 +225,7 @@ EXPORTS get_aflags DibMapGlobalMemory DibUnmapGlobalMemory + GlobalMapInternal make_thunk_32 free_thunk_32 get_resource_table diff --git a/krnl386/krnl386.exe16.spec b/krnl386/krnl386.exe16.spec index 48259dfb733..db3ae46df16 100644 --- a/krnl386/krnl386.exe16.spec +++ b/krnl386/krnl386.exe16.spec @@ -778,6 +778,7 @@ @ cdecl -arch=win32 krnl386_search_executable_file(str ptr long long) @ stdcall -arch=win32 DibMapGlobalMemory(long ptr long) @ stdcall -arch=win32 DibUnmapGlobalMemory(ptr long) +@ stdcall -arch=win32 GlobalMapInternal(long ptr long) @ cdecl -arch=win32 make_thunk_32(ptr str str long long long) @ cdecl -arch=win32 free_thunk_32(long) @ cdecl -arch=win32 get_resource_table(long str ptr) From de4f35e3b27abb1a51c0a106e003623dbea4492f Mon Sep 17 00:00:00 2001 From: cracyc Date: Tue, 13 Jul 2021 16:59:50 -0500 Subject: [PATCH 2/2] don't check the base address --- krnl386/global.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/krnl386/global.c b/krnl386/global.c index 6077fd34d94..ffaca8aae63 100644 --- a/krnl386/global.c +++ b/krnl386/global.c @@ -1362,7 +1362,7 @@ void WINAPI DibUnmapGlobalMemory(void *base, DWORD size) void WINAPI GlobalMapInternal(WORD sel, void *base, DWORD size) { GLOBALARENA *pArena = GET_ARENA_PTR(sel); - if (!sel || pArena->base) + if (!sel) return; if (!base || !size) {