https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d635ce0cc0336a9b77d243ddce946876f48ec4f6

commit d635ce0cc0336a9b77d243ddce946876f48ec4f6
Author:     Kyle Katarn <[email protected]>
AuthorDate: Thu May 7 12:57:46 2020 +0200
Commit:     GitHub <[email protected]>
CommitDate: Thu May 7 12:57:46 2020 +0200

    [SYSDM][DESK] Fix GetDC/ReleaseDC error management (#2707)
    
    ## Purpose
    [SYSDM]
    - When closing System Properties page, log show
    (win32ss/user/ntuser/windc.c:749) err: [00060138] GetDC() without 
ReleaseDC()!
    because GetDC() is called (multiple times) without properly calling 
ReleaseDC() as required in order to release a device context.
    - This module also lacks some error management in case null DC are provided 
(on error).
    - LiveCD Userinit, based on SYSDM is affected too.
    
    [DESK]
    - Fix missing ReleaseDC related to the spectrum (color depth)
    
    ## Proposed changes
    - ReleaseDC() added.
    - Error management in case of null DC.
    - Overall alignement of LiveCD Userinit and SYSDM.
---
 base/system/userinit/livecd.c |  14 +++--
 dll/cpl/desk/settings.c       |   6 ++-
 dll/cpl/sysdm/general.c       | 115 ++++++++++++++++++++++++------------------
 3 files changed, 80 insertions(+), 55 deletions(-)

diff --git a/base/system/userinit/livecd.c b/base/system/userinit/livecd.c
index 57b031a716b..e4940bcade0 100644
--- a/base/system/userinit/livecd.c
+++ b/base/system/userinit/livecd.c
@@ -34,6 +34,9 @@ InitLogo(PIMGINFO pImgInfo, HWND hwndDlg)
     COLORREF *pBits;
     INT line, column;
 
+    if (hDC == NULL || hDCLogo == NULL || hDCMask == NULL)
+        goto Cleanup;
+
     ZeroMemory(pImgInfo, sizeof(*pImgInfo));
     ZeroMemory(&bmpi, sizeof(bmpi));
 
@@ -76,7 +79,7 @@ InitLogo(PIMGINFO pImgInfo, HWND hwndDlg)
                 g = GetGValue(Color) * alpha / 255;
                 b = GetBValue(Color) * alpha / 255;
 
-                *pBits++ = b | g << 8 | r << 16 | alpha << 24;
+                *pBits++ = b | (g << 8) | (r << 16) | (alpha << 24);
             }
         }
 
@@ -88,10 +91,11 @@ InitLogo(PIMGINFO pImgInfo, HWND hwndDlg)
     }
 
 Cleanup:
-    DeleteObject(hMask);
-    DeleteObject(hLogo);
-    DeleteDC(hDCMask);
-    DeleteDC(hDCLogo);
+    if (hMask != NULL) DeleteObject(hMask);
+    if (hLogo != NULL) DeleteObject(hLogo);  
+    if (hDCMask != NULL) DeleteDC(hDCMask);
+    if (hDCLogo != NULL) DeleteDC(hDCLogo);    
+    if (hDC != NULL) ReleaseDC(hwndDlg, hDC);
 }
 
 
diff --git a/dll/cpl/desk/settings.c b/dll/cpl/desk/settings.c
index c8d4761a05a..300ef616853 100644
--- a/dll/cpl/desk/settings.c
+++ b/dll/cpl/desk/settings.c
@@ -5,7 +5,7 @@
  * PURPOSE:         Settings property page
  *
  * PROGRAMMERS:     Trevor McCort ([email protected])
- *                  Herv� Poussineau ([email protected])
+ *                  Hervé Poussineau ([email protected])
  */
 
 #include "desk.h"
@@ -472,8 +472,12 @@ OnBPPChanged(IN HWND hwndDlg, IN PSETTINGS_DATA pData)
     /* Show a new spectrum bitmap */
     hSpectrumControl = GetDlgItem(hwndDlg, IDC_SETTINGS_SPECTRUM);
     hSpectrumDC = GetDC(hSpectrumControl);
+    if (hSpectrumDC == NULL)
+        return;
+
     GetClientRect(hSpectrumControl, &client);
     ShowColorSpectrum(hSpectrumDC, &client, dmNewBitsPerPel, pData);
+    ReleaseDC(hSpectrumControl, hSpectrumDC);
 
     /* Find if new parameters are valid */
     Current = pData->CurrentDisplayDevice->CurrentSettings;
diff --git a/dll/cpl/sysdm/general.c b/dll/cpl/sysdm/general.c
index 68436639e19..d56677574fe 100644
--- a/dll/cpl/sysdm/general.c
+++ b/dll/cpl/sysdm/general.c
@@ -69,22 +69,22 @@ static VOID InitLogo(HWND hwndDlg)
     COLORREF *pBits;
     INT line, column;
 
+    if (hDC == NULL || hDCLogo == NULL || hDCMask == NULL)
+        goto Cleanup;
+
     ZeroMemory(pImgInfo, sizeof(*pImgInfo));
     ZeroMemory(&bmpi, sizeof(bmpi));
 
-    hLogo = (HBITMAP)LoadImage(hApplet, MAKEINTRESOURCE(IDB_ROSBMP), 
IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
-    hMask = (HBITMAP)LoadImage(hApplet, MAKEINTRESOURCE(IDB_ROSMASK), 
IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
+    hLogo = (HBITMAP)LoadImageW(hApplet, MAKEINTRESOURCEW(IDB_ROSBMP), 
IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
+    hMask = (HBITMAP)LoadImageW(hApplet, MAKEINTRESOURCEW(IDB_ROSMASK), 
IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
 
     if (hLogo != NULL && hMask != NULL)
     {
-        GetObject(hLogo, sizeof(BITMAP), &logoBitmap);
-        GetObject(hMask, sizeof(BITMAP), &maskBitmap);
+        GetObject(hLogo, sizeof(logoBitmap), &logoBitmap);
+        GetObject(hMask, sizeof(maskBitmap), &maskBitmap);
 
-        if(logoBitmap.bmHeight != maskBitmap.bmHeight || logoBitmap.bmWidth != 
maskBitmap.bmWidth)
-            return;
-
-        pImgInfo->cxSource = logoBitmap.bmWidth;
-        pImgInfo->cySource = logoBitmap.bmHeight;
+        if (logoBitmap.bmHeight != maskBitmap.bmHeight || logoBitmap.bmWidth 
!= maskBitmap.bmWidth)
+            goto Cleanup;
 
         bmpi.bmiHeader.biSize = sizeof(BITMAPINFO);
         bmpi.bmiHeader.biWidth = logoBitmap.bmWidth;
@@ -94,17 +94,17 @@ static VOID InitLogo(HWND hwndDlg)
         bmpi.bmiHeader.biCompression = BI_RGB;
         bmpi.bmiHeader.biSizeImage = 4 * logoBitmap.bmWidth * 
logoBitmap.bmHeight;
 
+        /* Create a premultiplied bitmap */
         hAlphaLogo = CreateDIBSection(hDC, &bmpi, DIB_RGB_COLORS, 
(PVOID*)&pBits, 0, 0);
-
-        if(!hAlphaLogo)
-            return;
+        if (!hAlphaLogo)
+            goto Cleanup;
 
         SelectObject(hDCLogo, hLogo);
         SelectObject(hDCMask, hMask);
 
-        for(line = logoBitmap.bmHeight - 1; line >= 0; line--)
+        for (line = logoBitmap.bmHeight - 1; line >= 0; line--)
         {
-            for(column = 0; column < logoBitmap.bmWidth; column++)
+            for (column = 0; column < logoBitmap.bmWidth; column++)
             {
                 COLORREF alpha = GetPixel(hDCMask, column, line) & 0xFF;
                 COLORREF Color = GetPixel(hDCLogo, column, line);
@@ -114,22 +114,23 @@ static VOID InitLogo(HWND hwndDlg)
                 g = GetGValue(Color) * alpha / 255;
                 b = GetBValue(Color) * alpha / 255;
 
-                *pBits++ =  b | g << 8 | r << 16 | alpha << 24;
+                *pBits++ = b | (g << 8) | (r << 16) | (alpha << 24);
             }
-          }
-    }
-
-    pImgInfo->hBitmap = hAlphaLogo;
-    pImgInfo->cxSource = logoBitmap.bmWidth;
-    pImgInfo->cySource = logoBitmap.bmHeight;
-    pImgInfo->iBits = logoBitmap.bmBitsPixel;
-    pImgInfo->iPlanes = logoBitmap.bmPlanes;
+        }
 
-    DeleteObject(hLogo);
-    DeleteObject(hMask);
-    DeleteDC(hDCLogo);
-    DeleteDC(hDCMask);
+        pImgInfo->hBitmap = hAlphaLogo;
+        pImgInfo->cxSource = logoBitmap.bmWidth;
+        pImgInfo->cySource = logoBitmap.bmHeight;
+        pImgInfo->iBits = logoBitmap.bmBitsPixel;
+        pImgInfo->iPlanes = logoBitmap.bmPlanes;
+    }
 
+Cleanup:
+    if (hMask != NULL) DeleteObject(hMask);
+    if (hLogo != NULL) DeleteObject(hLogo);
+    if (hDCMask != NULL) DeleteDC(hDCMask);
+    if (hDCLogo != NULL) DeleteDC(hDCLogo);    
+    if (hDC != NULL) ReleaseDC(hwndDlg, hDC);
 }
 
 LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM 
lParam)
@@ -145,19 +146,23 @@ LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, 
WPARAM wParam, LPARAM lParam
                 if (timerid == 0)
                 {
                     HDC hCreditsDC, hLogoDC;
-                    HFONT hFont;
+                    HDC hDC = GetDC(NULL);
+                    HFONT hFont = NULL;
                     NONCLIENTMETRICS ncm;
                     RECT rcCredits;
                     TCHAR szCredits[2048];
                     INT iDevsHeight;
 
-                    top = 0;
+                    if (hDC == NULL)
+                        goto Cleanup;
+
+                                       top = 0;
                     offset = 0;
-                    hCreditsDC = CreateCompatibleDC(GetDC(NULL));
+                    hCreditsDC = CreateCompatibleDC(hDC);
                     hLogoDC = CreateCompatibleDC(hCreditsDC);
 
                     if (hCreditsDC == NULL || hLogoDC == NULL)
-                        break;
+                        goto Cleanup;
 
                     SetRect(&rcCredits, 0, 0, 0, 0);
 
@@ -165,6 +170,8 @@ LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, WPARAM 
wParam, LPARAM lParam
                     SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 
sizeof(NONCLIENTMETRICS), &ncm, 0);
 
                     hFont = CreateFontIndirect(&ncm.lfMessageFont);
+                    if (!hFont)
+                        goto Cleanup;
                     SelectObject(hCreditsDC, hFont);
 
                     LoadString(hApplet, IDS_DEVS, szCredits, sizeof(szCredits) 
/ sizeof(TCHAR));
@@ -174,8 +181,8 @@ LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, WPARAM 
wParam, LPARAM lParam
 
                     hCreditsBitmap = CreateBitmap(pImgInfo->cxSource, (2 * 
pImgInfo->cySource) + iDevsHeight + 1, pImgInfo->iPlanes, pImgInfo->iBits, 
NULL);
 
-                    if(!hCreditsBitmap)
-                        break;
+                    if (!hCreditsBitmap)
+                        goto Cleanup;
 
                     SelectObject(hLogoDC, pImgInfo->hBitmap);
                     SelectObject(hCreditsDC, hCreditsBitmap);
@@ -201,10 +208,13 @@ LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, 
WPARAM wParam, LPARAM lParam
                     AlphaBlend(hCreditsDC, 0, 0, pImgInfo->cxSource, 
pImgInfo->cySource, hLogoDC, 0,  0, pImgInfo->cxSource, pImgInfo->cySource, 
BlendFunc);
                     AlphaBlend(hCreditsDC, 0, offset, pImgInfo->cxSource, 
pImgInfo->cySource, hLogoDC, 0,  0, pImgInfo->cxSource, pImgInfo->cySource, 
BlendFunc);
 
-                    DeleteDC(hLogoDC);
-                    DeleteDC(hCreditsDC);
-
                     timerid = SetTimer(hwnd, 1, ANIM_TIME, NULL);
+
+Cleanup:
+                    if (hFont != NULL) DeleteObject(hFont);
+                    if (hLogoDC != NULL) DeleteDC(hLogoDC);
+                    if (hCreditsDC != NULL) DeleteDC(hCreditsDC);
+                    if (hDC != NULL) ReleaseDC(NULL, hDC);
                 }
             }
             break;
@@ -213,18 +223,22 @@ LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, 
WPARAM wParam, LPARAM lParam
             {
                 RECT rcCredits;
                 HDC hDC = GetDC(hwnd);
-
-                GetClientRect(hwnd, &rcCredits);
-                SetRect(&rcCredits, 0, 0, rcCredits.right, pImgInfo->cySource);
-                FillRect(hDC, &rcCredits, GetSysColorBrush(COLOR_3DFACE));
-
+                if (hDC != NULL)
+                {
+                    GetClientRect(hwnd, &rcCredits);
+                    SetRect(&rcCredits, 0, 0, rcCredits.right, 
pImgInfo->cySource);
+                    FillRect(hDC, &rcCredits, GetSysColorBrush(COLOR_3DFACE));
+                    ReleaseDC(hwnd, hDC);
+                }
                 KillTimer(hwnd, timerid);
-                DeleteObject(hCreditsBitmap);
-                InvalidateRect(hwnd, NULL, FALSE);
+                if (hCreditsBitmap != NULL)
+                    DeleteObject(hCreditsBitmap);
 
                 top = 0;
                 timerid = 0;
             }
+            
+            InvalidateRect(hwnd, NULL, FALSE);
             break;
         case WM_TIMER:
             top += ANIM_STEP;
@@ -233,13 +247,16 @@ LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, 
WPARAM wParam, LPARAM lParam
             {
                 RECT rcCredits;
                 HDC hDC = GetDC(hwnd);
-
-                GetClientRect(hwnd, &rcCredits);
-                SetRect(&rcCredits, 0, 0, rcCredits.right, pImgInfo->cySource);
-                FillRect(hDC, &rcCredits, GetSysColorBrush(COLOR_3DFACE));
-
+                if (hDC != NULL)
+                {
+                    GetClientRect(hwnd, &rcCredits);
+                    SetRect(&rcCredits, 0, 0, rcCredits.right, 
pImgInfo->cySource);
+                    FillRect(hDC, &rcCredits, GetSysColorBrush(COLOR_3DFACE));
+                    ReleaseDC(hwnd, hDC);
+                }
                 KillTimer(hwnd, timerid);
-                DeleteObject(hCreditsBitmap);
+                if (hCreditsBitmap != NULL)
+                    DeleteObject(hCreditsBitmap);
 
                 top = 0;
                 timerid = 0;

Reply via email to