From 90a31e1daf3bad24713ca6b758465f6df7df763f Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Tue, 30 Oct 2018 17:54:14 +0100 Subject: [PATCH] limit resolutions in EnumDisplayModes to prevent crashes --- src/main.c | 40 +++++++++++++++++++++++++++++++++++++--- src/surface.c | 20 +++++++++++++++++--- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index fc0d9b3..b39100f 100644 --- a/src/main.c +++ b/src/main.c @@ -147,7 +147,6 @@ HRESULT __stdcall ddraw_DuplicateSurface(IDirectDrawImpl *This, LPDIRECTDRAWSURF HRESULT __stdcall ddraw_EnumDisplayModes(IDirectDrawImpl *This, DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback) { DWORD i = 0; - DEVMODE m; DDSURFACEDESC s; printf("DirectDraw::EnumDisplayModes(This=%p, dwFlags=%08X, lpDDSurfaceDesc=%p, lpContext=%p, lpEnumModesCallback=%p)\n", This, (unsigned int)dwFlags, lpDDSurfaceDesc, lpContext, lpEnumModesCallback); @@ -157,6 +156,41 @@ HRESULT __stdcall ddraw_EnumDisplayModes(IDirectDrawImpl *This, DWORD dwFlags, L return DDERR_UNSUPPORTED; } + SIZE resolutions[] = + { + { 320, 200 }, + { 640, 400 }, + { 640, 480 }, + { 800, 600 }, + { 1024, 768 }, + { 1280, 960 }, + { 1280, 1024 }, + { 1280, 720 }, + { 1600, 900 }, + { 1920, 1080 }, + }; + + for (i = 0; i < sizeof(resolutions) / sizeof(resolutions[0]); i++) + { + memset(&s, 0, sizeof(DDSURFACEDESC)); + s.dwSize = sizeof(DDSURFACEDESC); + s.dwFlags = DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_WIDTH | DDSD_PIXELFORMAT; + s.dwHeight = resolutions[i].cy; + s.dwWidth = resolutions[i].cx; + s.dwRefreshRate = 60; + s.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); + s.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB; + s.ddpfPixelFormat.dwRGBBitCount = 8; + + if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL) + { + printf(" DDENUMRET_CANCEL returned, stopping\n"); + break; + } + } + + /* Some games crash when you feed them with too many resolutions... + DEVMODE m; while (EnumDisplaySettings(NULL, i, &m)) { #if _DEBUG_X @@ -179,7 +213,7 @@ HRESULT __stdcall ddraw_EnumDisplayModes(IDirectDrawImpl *This, DWORD dwFlags, L } i++; } - + */ return DD_OK; } @@ -1064,7 +1098,7 @@ HRESULT __stdcall ddraw_SetCooperativeLevel(IDirectDrawImpl *This, HWND hWnd, DW /* Red Alert for some weird reason does this on Windows XP */ if(hWnd == NULL) { - return DDERR_INVALIDPARAMS; + return DD_OK; } if (This->hWnd == NULL) diff --git a/src/surface.c b/src/surface.c index 2d8819f..db81d40 100644 --- a/src/surface.c +++ b/src/surface.c @@ -451,10 +451,24 @@ HRESULT __stdcall ddraw_surface_GetPalette(IDirectDrawSurfaceImpl *This, LPDIREC return DD_OK; } -HRESULT __stdcall ddraw_surface_GetPixelFormat(IDirectDrawSurfaceImpl *This, LPDDPIXELFORMAT a) +HRESULT __stdcall ddraw_surface_GetPixelFormat(IDirectDrawSurfaceImpl *This, LPDDPIXELFORMAT ddpfPixelFormat) { - printf("IDirectDrawSurface::GetPixelFormat(This=%p, ...) ???\n", This); - return DD_OK; + printf("IDirectDrawSurface::GetPixelFormat(This=%p, ...)\n", This); + + DWORD size = ddpfPixelFormat->dwSize; + + if (size == sizeof(DDPIXELFORMAT)) + { + memset(ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT)); + + ddpfPixelFormat->dwSize = size; + ddpfPixelFormat->dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB; + ddpfPixelFormat->dwRGBBitCount = 8; + + return DD_OK; + } + + return DDERR_INVALIDPARAMS; } HRESULT __stdcall ddraw_surface_Initialize(IDirectDrawSurfaceImpl *This, LPDIRECTDRAW a, LPDDSURFACEDESC b)