[OOPS]
[reactos.git] / reactos / win32ss / user / ntuser / cursoricon.c
index 0c772a2..f7ecbfc 100644 (file)
@@ -77,7 +77,7 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
         return NULL;
     }
 
-    CurIcon = (PCURICON_OBJECT)UserReferenceObjectByHandle(hCurIcon, otCursorIcon);
+    CurIcon = (PCURICON_OBJECT)UserReferenceObjectByHandle(hCurIcon, TYPE_CURSOR);
     if (!CurIcon)
     {
         /* We never set ERROR_INVALID_ICON_HANDLE. lets hope noone ever checks for it */
@@ -178,7 +178,7 @@ IntFindExistingCurIconObject(HMODULE hModule,
     LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
     {
 
-        // if (NT_SUCCESS(UserReferenceObjectByPointer(Object, otCursorIcon))) // <- huh????
+        // if (NT_SUCCESS(UserReferenceObjectByPointer(Object, TYPE_CURSOR))) // <- huh????
 //      UserReferenceObject(  CurIcon);
 //      {
         if ((CurIcon->hModule == hModule) && (CurIcon->hRsrc == hRsrc))
@@ -203,13 +203,13 @@ IntFindExistingCurIconObject(HMODULE hModule,
     return NULL;
 }
 
-PCURICON_OBJECT
-IntCreateCurIconHandle()
+HANDLE
+IntCreateCurIconHandle(BOOLEAN Anim)
 {
     PCURICON_OBJECT CurIcon;
     HANDLE hCurIcon;
 
-    CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
+    CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, TYPE_CURSOR, sizeof(CURICON_OBJECT));
 
     if (!CurIcon)
     {
@@ -220,27 +220,29 @@ IntCreateCurIconHandle()
     CurIcon->Self = hCurIcon;
     InitializeListHead(&CurIcon->ProcessList);
 
-    if (! ReferenceCurIconByProcess(CurIcon))
+    if (!ReferenceCurIconByProcess(CurIcon))
     {
         ERR("Failed to add process\n");
-        UserDeleteObject(hCurIcon, otCursorIcon);
+        UserDeleteObject(hCurIcon, TYPE_CURSOR);
         UserDereferenceObject(CurIcon);
         return NULL;
     }
 
     InsertHeadList(&gCurIconList, &CurIcon->ListEntry);
 
-    return CurIcon;
+    UserDereferenceObject(CurIcon);
+
+    return hCurIcon;
 }
 
 BOOLEAN FASTCALL
 IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
 {
     PSYSTEM_CURSORINFO CurInfo;
-    HBITMAP bmpMask, bmpColor, bmpAlpha;
+    HBITMAP bmpMask, bmpColor;
     BOOLEAN Ret, bListEmpty, bFound = FALSE;
     PCURICON_PROCESS Current = NULL;
-    
+
     /* For handles created without any data (error handling) */
     if(IsListEmpty(&CurIcon->ProcessList))
         goto emptyList;
@@ -256,7 +258,7 @@ IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
             break;
         }
     }
-    
+
     if(!bFound)
     {
         /* This object doesn't belong to this process */
@@ -273,7 +275,7 @@ IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
         {
             /* Set the first process of the list as owner */
             Current = CONTAINING_RECORD(CurIcon->ProcessList.Flink, CURICON_PROCESS, ListEntry);
-            UserSetObjectOwner(CurIcon, otCursorIcon, Current->Process);
+            UserSetObjectOwner(CurIcon, TYPE_CURSOR, Current->Process);
         }
         UserDereferenceObject(CurIcon);
         return TRUE;
@@ -291,33 +293,26 @@ emptyList:
         UserSetCursor(NULL, TRUE);
     }
 
-    bmpMask = CurIcon->aFrame[0].hbmMask;
-    bmpColor = CurIcon->aFrame[0].hbmColor;
-    bmpAlpha = CurIcon->aFrame[0].hbmAlpha;
+    bmpMask = CurIcon->IconInfo.hbmMask;
+    bmpColor = CurIcon->IconInfo.hbmColor;
 
     /* Delete bitmaps */
     if (bmpMask)
     {
         GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
         GreDeleteObject(bmpMask);
-        CurIcon->aFrame[0].hbmMask = NULL;
+        CurIcon->IconInfo.hbmMask = NULL;
     }
     if (bmpColor)
     {
         GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
         GreDeleteObject(bmpColor);
-        CurIcon->aFrame[0].hbmColor = NULL;
-    }
-    if (bmpAlpha)
-    {
-        GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED);
-        GreDeleteObject(bmpAlpha);
-        CurIcon->aFrame[0].hbmAlpha = NULL;
+        CurIcon->IconInfo.hbmColor = NULL;
     }
 
     /* We were given a pointer, no need to keep the reference anylonger! */
     UserDereferenceObject(CurIcon);
-    Ret = UserDeleteObject(CurIcon->Self, otCursorIcon);
+    Ret = UserDeleteObject(CurIcon->Self, TYPE_CURSOR);
 
     return Ret;
 }
@@ -368,21 +363,18 @@ NtUserGetIconInfo(
     {
         goto leave;
     }
-    
-    /* Fill data */
-    ii.fIcon = CurIcon->bIcon;
-    ii.xHotspot = CurIcon->ptlHotspot.x;
-    ii.yHotspot = CurIcon->ptlHotspot.y;
+
+    RtlCopyMemory(&ii, &CurIcon->IconInfo, sizeof(ICONINFO));
 
     /* Copy bitmaps */
-    ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask);
-    ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor);
+    ii.hbmMask = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmMask);
+    ii.hbmColor = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmColor);
 
     if (pbpp)
     {
         PSURFACE psurfBmp;
 
-        psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
+        psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
         if (psurfBmp)
         {
             colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
@@ -396,6 +388,18 @@ NtUserGetIconInfo(
         ProbeForWrite(IconInfo, sizeof(ICONINFO), 1);
         RtlCopyMemory(IconInfo, &ii, sizeof(ICONINFO));
 
+        /// @todo Implement support for lpInstName
+        if (lpInstName)
+        {
+            RtlInitEmptyUnicodeString(lpInstName, NULL, 0);
+        }
+
+        /// @todo Implement support for lpResName
+        if (lpResName)
+        {
+            RtlInitEmptyUnicodeString(lpResName, NULL, 0);
+        }
+
         if (pbpp)
         {
             ProbeForWrite(pbpp, sizeof(DWORD), 1);
@@ -623,8 +627,8 @@ NtUserClipCursor(
 BOOL
 APIENTRY
 NtUserDestroyCursor(
-    HANDLE hCurIcon,
-    DWORD Unknown)
+  _In_  HANDLE hCurIcon,
+  _In_  BOOL bForce)
 {
     PCURICON_OBJECT CurIcon;
     BOOL ret;
@@ -809,103 +813,35 @@ NtUserSetCursorContents(
         goto done;
     }
 
-#if 0
-    /* Check if we get valid information */
-    if(IconInfo.fIcon != CurInfo->bIcon)
+    /* Delete old bitmaps */
+    if ((CurIcon->IconInfo.hbmColor)
+                       && (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor))
     {
-        EngSetLastError(ERROR_INVALID_PARAMETER);
-        goto done;
+        GreDeleteObject(CurIcon->IconInfo.hbmColor);
+    }
+    if ((CurIcon->IconInfo.hbmMask)
+                       && CurIcon->IconInfo.hbmMask != IconInfo.hbmMask)
+    {
+        GreDeleteObject(CurIcon->IconInfo.hbmMask);
     }
-#endif
 
-    /* Delete old bitmaps */
-    if (CurIcon->aFrame[0].hbmColor)
-        GreDeleteObject(CurIcon->aFrame[0].hbmColor);
-    if (CurIcon->aFrame[0].hbmMask)
-        GreDeleteObject(CurIcon->aFrame[0].hbmMask);
-    if(CurIcon->aFrame[0].hbmAlpha)
-        GreDeleteObject(CurIcon->aFrame[0].hbmAlpha);
-
-    /* Set fields */
-    CurIcon->bIcon = IconInfo.fIcon;
-    CurIcon->ptlHotspot.x = IconInfo.xHotspot;
-    CurIcon->ptlHotspot.y = IconInfo.yHotspot;
-    CurIcon->aFrame[0].hbmMask = IconInfo.hbmMask;
-    CurIcon->aFrame[0].hbmColor = IconInfo.hbmColor;
-    CurIcon->aFrame[0].hbmAlpha = NULL;
-
-    if (IconInfo.hbmColor)
-    {
-        BOOLEAN bAlpha = FALSE;
-        psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmColor);
+    /* Copy new IconInfo field */
+    CurIcon->IconInfo = IconInfo;
+
+    if (CurIcon->IconInfo.hbmColor)
+    {
+        psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
         if (!psurfBmp)
             goto done;
+
         CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
         CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
-        
-        /* 32bpp bitmap is likely to have an alpha channel */
-        if(psurfBmp->SurfObj.iBitmapFormat == BMF_32BPP)
-        {
-            PFN_DIB_GetPixel fn_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel;
-            INT i, j;
-
-            fn_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel;
-            for (i = 0; i < psurfBmp->SurfObj.sizlBitmap.cx; i++)
-            {
-                for (j = 0; j < psurfBmp->SurfObj.sizlBitmap.cy; j++)
-                {
-                    bAlpha = ((BYTE)(fn_GetPixel(&psurfBmp->SurfObj, i, j) >> 24)) != 0;
-                    if (bAlpha)
-                        break;
-                }
-                if (bAlpha)
-                    break;
-            }
-        }
-        /* We're done with this one */
         SURFACE_ShareUnlockSurface(psurfBmp);
-        GreSetObjectOwner(IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
-        
-        if(bAlpha)
-        {
-            UCHAR Alpha;
-            PUCHAR ptr;
-            INT i, j;
-            /* Copy the bitmap */
-            CurIcon->aFrame[0].hbmAlpha = BITMAP_CopyBitmap(IconInfo.hbmColor);
-            if(!CurIcon->aFrame[0].hbmAlpha)
-            {
-                ERR("BITMAP_CopyBitmap failed!");
-                goto done;
-            }
-
-            psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmAlpha);
-            if(!psurfBmp)
-            {
-                ERR("SURFACE_LockSurface failed!\n");
-                goto done;
-            }
-
-            /* Premultiply with the alpha channel value */
-            for (i = 0; i < psurfBmp->SurfObj.sizlBitmap.cy; i++)
-            {
-                       ptr = (PBYTE)psurfBmp->SurfObj.pvScan0 + i*psurfBmp->SurfObj.lDelta;
-                for (j = 0; j < psurfBmp->SurfObj.sizlBitmap.cx; j++)
-                {
-                    Alpha = ptr[3];
-                    ptr[0] = (ptr[0] * Alpha) / 0xff;
-                    ptr[1] = (ptr[1] * Alpha) / 0xff;
-                    ptr[2] = (ptr[2] * Alpha) / 0xff;
-                               ptr += 4;
-                }
-            }
-            SURFACE_ShareUnlockSurface(psurfBmp);
-            GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
-        }
+        GreSetObjectOwner(CurIcon->IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
     }
     else
     {
-        psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmMask);
+        psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmMask);
         if (!psurfBmp)
             goto done;
 
@@ -914,18 +850,12 @@ NtUserSetCursorContents(
 
         SURFACE_ShareUnlockSurface(psurfBmp);
     }
-    GreSetObjectOwner(IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+    GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
 
     Ret = TRUE;
 
 done:
 
-    if(!Ret)
-    {
-        IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
-        CurIcon = NULL;
-    }
-
     if (CurIcon)
     {
         UserDereferenceObject(CurIcon);
@@ -942,21 +872,20 @@ CLEANUP:
 /*
  * @implemented
  */
-#ifdef NEW_CURSORICON
+#if 0
 BOOL
 APIENTRY
 NtUserSetCursorIconData(
-  _In_ HCURSOR Handle,
-  _In_ HINSTANCE hinst,
-  _In_ HRSRC hrsrc,
-  _In_ PICONINFO pIconInfo)
+    HANDLE Handle,
+    HMODULE hModule,
+    PUNICODE_STRING pstrResName,
+    PICONINFO pIconInfo)
 {
     PCURICON_OBJECT CurIcon;
     PSURFACE psurfBmp;
     NTSTATUS Status = STATUS_SUCCESS;
     BOOL Ret = FALSE;
     DECLARE_RETURN(BOOL);
-    ICONINFO ii;
 
     TRACE("Enter NtUserSetCursorIconData\n");
     UserEnterExclusive();
@@ -966,96 +895,54 @@ NtUserSetCursorIconData(
         RETURN(FALSE);
     }
 
-    CurIcon->hModule = hinst;
-    CurIcon->hRsrc =hrsrc;
+    CurIcon->hModule = hModule;
+    CurIcon->hRsrc = NULL; //hRsrc;
+    CurIcon->hGroupRsrc = NULL; //hGroupRsrc;
 
     _SEH2_TRY
     {
         ProbeForRead(pIconInfo, sizeof(ICONINFO), 1);
-        ii = *pIconInfo;
+        RtlCopyMemory(&CurIcon->IconInfo, pIconInfo, sizeof(ICONINFO));
+
+        CurIcon->IconInfo.hbmMask = BITMAP_CopyBitmap(pIconInfo->hbmMask);
+        CurIcon->IconInfo.hbmColor = BITMAP_CopyBitmap(pIconInfo->hbmColor);
+
+        if (CurIcon->IconInfo.hbmColor)
+        {
+            if ((psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmColor)))
+            {
+                CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
+                CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
+                SURFACE_UnlockSurface(psurfBmp);
+                GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+            }
+        }
+        if (CurIcon->IconInfo.hbmMask)
+        {
+            if (CurIcon->IconInfo.hbmColor == NULL)
+            {
+                if ((psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmMask)))
+                {
+                    CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
+                    CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
+                    SURFACE_UnlockSurface(psurfBmp);
+                }
+            }
+            GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+        }
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
         Status = _SEH2_GetExceptionCode();
     }
     _SEH2_END
-    
+
     if (!NT_SUCCESS(Status))
-    {
         SetLastNtError(Status);
-        goto done;
-    }
-    
-    /* This is probably not what windows does, but consistency checks can't hurt */
-    if(CurIcon->bIcon != ii.fIcon)
-    {
-        EngSetLastError(ERROR_INVALID_PARAMETER);
-        goto done;
-    }
-    CurIcon->ptlHotspot.x = ii.xHotspot;
-    CurIcon->ptlHotspot.y = ii.yHotspot;
-    
-    if(!ii.hbmMask)
-    {
-        EngSetLastError(ERROR_INVALID_PARAMETER);
-        goto done;
-    }
-        
-    CurIcon->aFrame[0].hbmMask = BITMAP_CopyBitmap(ii.hbmMask);
-    if(!CurIcon->aFrame[0].hbmMask)
-        goto done;
-
-    if(ii.hbmColor)
-    {
-        CurIcon->aFrame[0].hbmColor = BITMAP_CopyBitmap(ii.hbmColor);
-        if(!CurIcon->aFrame[0].hbmColor)
-            goto done;
-    }
-
-    if (CurIcon->aFrame[0].hbmColor)
-    {
-        if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor)))
-        {
-            CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
-            CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
-            SURFACE_ShareUnlockSurface(psurfBmp);
-            GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
-        }
-        else
-            goto done;
-    }
     else
-    {
-       if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmMask)))
-        {
-            CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
-            CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy/2;
-            SURFACE_ShareUnlockSurface(psurfBmp);
-        }
-        else
-            goto done;
-    }
-    GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
-    
-    Ret = TRUE;
+        Ret = TRUE;
 
-done:
     UserDereferenceObject(CurIcon);
-    if(!Ret)
-    {
-        if (CurIcon->aFrame[0].hbmMask)
-        {
-            GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_POWNED);
-            GreDeleteObject(CurIcon->aFrame[0].hbmMask);
-            CurIcon->aFrame[0].hbmMask = NULL;
-        }
-        if (CurIcon->aFrame[0].hbmColor)
-        {
-            GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_POWNED);
-            GreDeleteObject(CurIcon->aFrame[0].hbmColor);
-            CurIcon->aFrame[0].hbmColor = NULL;
-        }
-    }
     RETURN(Ret);
 
 CLEANUP:
@@ -1076,6 +963,7 @@ NtUserSetCursorIconData(
 {
     PCURICON_OBJECT CurIcon;
     NTSTATUS Status;
+    POINT SafeHotspot;
     BOOL Ret = FALSE;
     DECLARE_RETURN(BOOL);
 
@@ -1094,7 +982,7 @@ NtUserSetCursorIconData(
     /* Copy fields */
     if (fIcon)
     {
-        Status = MmCopyFromCaller(&CurIcon->bIcon, fIcon, sizeof(BOOL));
+        Status = MmCopyFromCaller(&CurIcon->IconInfo.fIcon, fIcon, sizeof(BOOL));
         if (!NT_SUCCESS(Status))
         {
             SetLastNtError(Status);
@@ -1109,12 +997,16 @@ NtUserSetCursorIconData(
 
     if (Hotspot)
     {
-        Status = MmCopyFromCaller(&CurIcon->ptlHotspot, Hotspot, sizeof(POINT));
-        if (!NT_SUCCESS(Status))
+        Status = MmCopyFromCaller(&SafeHotspot, Hotspot, sizeof(POINT));
+        if (NT_SUCCESS(Status))
         {
-            SetLastNtError(Status);
-            goto done;
+            CurIcon->IconInfo.xHotspot = SafeHotspot.x;
+            CurIcon->IconInfo.yHotspot = SafeHotspot.y;
+
+            Ret = TRUE;
         }
+        else
+            SetLastNtError(Status);
     }
 
     if (!fIcon && !Hotspot)
@@ -1126,14 +1018,10 @@ done:
        if(Ret)
        {
                /* This icon is shared now */
-               GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
-               if(CurIcon->aFrame[0].hbmColor)
-               {
-                       GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC);
-               }
-               if(CurIcon->aFrame[0].hbmAlpha)
+               GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+               if(CurIcon->IconInfo.hbmColor)
                {
-                       GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
+                       GreSetObjectOwner(CurIcon->IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
                }
        }
     UserDereferenceObject(CurIcon);
@@ -1170,12 +1058,12 @@ UserDrawIconEx(
     PSURFACE psurfDest, psurfMask, psurfColor, psurfOffScreen;
     PDC pdc = NULL;
     BOOL Ret = FALSE;
-    HBITMAP hbmMask, hbmColor, hbmAlpha;
-    BOOL bOffScreen;
+    HBITMAP hbmMask, hbmColor;
+    BOOL bOffScreen, bAlpha = FALSE;
     RECTL rcDest, rcSrc;
     CLIPOBJ* pdcClipObj = NULL;
     EXLATEOBJ exlo;
-    
+
     /* Stupid case */
     if((diFlags & DI_NORMAL) == 0)
     {
@@ -1183,15 +1071,14 @@ UserDrawIconEx(
         return FALSE;
     }
 
-    hbmMask = pIcon->aFrame[0].hbmMask;
-    hbmColor = pIcon->aFrame[0].hbmColor;
-    hbmAlpha = pIcon->aFrame[0].hbmAlpha;
-    
+    hbmMask = pIcon->IconInfo.hbmMask;
+    hbmColor = pIcon->IconInfo.hbmColor;
+
     if (istepIfAniCur)
         ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
-    
+
     /*
-     * Get our objects. 
+     * Get our objects.
      * Shared locks are enough, we are only reading those bitmaps
      */
     psurfMask = SURFACE_ShareLockSurface(hbmMask);
@@ -1200,7 +1087,7 @@ UserDrawIconEx(
         ERR("Unable to lock the mask surface.\n");
         return FALSE;
     }
-    
+
     /* Color bitmap is not mandatory */
     if(hbmColor == NULL)
     {
@@ -1214,25 +1101,49 @@ UserDrawIconEx(
         SURFACE_ShareUnlockSurface(psurfMask);
         return FALSE;
     }
-    
+
     /* Set source rect */
     RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy);
 
+    /* Check for alpha */
+    if (psurfColor &&
+       (psurfColor->SurfObj.iBitmapFormat == BMF_32BPP) &&
+       (diFlags & DI_IMAGE))
+    {
+        PFN_DIB_GetPixel fnSource_GetPixel = NULL;
+        INT i, j;
+
+        /* In order to correctly display 32 bit icons Windows first scans the image,
+           because information about transparency is not stored in any image's headers */
+        fnSource_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel;
+        for (i = 0; i < psurfColor->SurfObj.sizlBitmap.cx; i++)
+        {
+            for (j = 0; j < psurfColor->SurfObj.sizlBitmap.cy; j++)
+            {
+                bAlpha = ((BYTE)(fnSource_GetPixel(&psurfColor->SurfObj, i, j) >> 24) & 0xff);
+                if (bAlpha)
+                    break;
+            }
+            if (bAlpha)
+                break;
+        }
+    }
+
     /* Fix width parameter, if needed */
     if (!cxWidth)
     {
         if(diFlags & DI_DEFAULTSIZE)
-            cxWidth = pIcon->bIcon ? 
+            cxWidth = pIcon->IconInfo.fIcon ?
                 UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
         else
             cxWidth = pIcon->Size.cx;
     }
-    
+
     /* Fix height parameter, if needed */
     if (!cyHeight)
     {
         if(diFlags & DI_DEFAULTSIZE)
-            cyHeight = pIcon->bIcon ? 
+            cyHeight = pIcon->IconInfo.fIcon ?
                 UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
         else
             cyHeight = pIcon->Size.cy;
@@ -1246,9 +1157,9 @@ UserDrawIconEx(
         /* Yes: Allocate and paint the offscreen surface */
         EBRUSHOBJ eboFill;
         PBRUSH pbrush = BRUSH_ShareLockBrush(hbrFlickerFreeDraw);
-        
+
         TRACE("Performing off-screen rendering.\n");
-        
+
         if(!pbrush)
         {
             ERR("Failed to get brush object.\n");
@@ -1257,6 +1168,12 @@ UserDrawIconEx(
             return FALSE;
         }
 
+        if (!psurfColor)
+        {
+           ERR("Attention HAX FIX API DrawIconEx TEST Line 37: psurfColor is NULL going with Mask!\n");
+           psurfColor = SURFACE_ShareLockSurface(hbmMask);
+        }
+
         psurfOffScreen = SURFACE_AllocSurface(STYPE_BITMAP,
             cxWidth, cyHeight, psurfColor->SurfObj.iBitmapFormat,
             0, 0, NULL);
@@ -1268,11 +1185,11 @@ UserDrawIconEx(
             BRUSH_ShareUnlockBrush(pbrush);
             return FALSE;
         }
-        
+
         /* Paint the brush */
         EBRUSHOBJ_vInit(&eboFill, pbrush, psurfOffScreen, 0x00FFFFFF, 0, NULL);
         RECTL_vSetRect(&rcDest, 0, 0, cxWidth, cyHeight);
-        
+
         Ret = IntEngBitBlt(&psurfOffScreen->SurfObj,
             NULL,
             NULL,
@@ -1288,7 +1205,7 @@ UserDrawIconEx(
         /* Clean up everything */
         EBRUSHOBJ_vCleanup(&eboFill);
         BRUSH_ShareUnlockBrush(pbrush);
-            
+
         if(!Ret)
         {
             ERR("Failed to paint the off-screen surface.\n");
@@ -1297,7 +1214,7 @@ UserDrawIconEx(
             GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
             return FALSE;
         }
-        
+
         /* We now have our destination surface */
         psurfDest = psurfOffScreen;
     }
@@ -1305,7 +1222,7 @@ UserDrawIconEx(
     {
         /* We directly draw to the DC */
         TRACE("Performing on screen rendering.\n");
-        
+
         psurfOffScreen = NULL;
         pdc = DC_LockDc(hDc);
         if(!pdc)
@@ -1319,16 +1236,16 @@ UserDrawIconEx(
         RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
         IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
         RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
-        
+
         /* Prepare the underlying surface */
         DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
-        
+
         /* Get the clip object */
         pdcClipObj = pdc->rosdc.CombinedClip;
-        
+
         /* We now have our destination surface and rectangle */
         psurfDest = pdc->dclevel.pSurface;
-        
+
         if(psurfDest == NULL)
         {
             /* Empty DC */
@@ -1341,21 +1258,47 @@ UserDrawIconEx(
     }
 
     /* Now do the rendering */
-       if(hbmAlpha && (diFlags & DI_IMAGE))
+       if(bAlpha && (diFlags & DI_IMAGE))
        {
            BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
+        BYTE Alpha;
+        INT i, j;
         PSURFACE psurf = NULL;
+        PBYTE ptr ;
+        HBITMAP hsurfCopy = NULL;
+
+        hsurfCopy = BITMAP_CopyBitmap(hbmColor);
+        if(!hsurfCopy)
+        {
+            ERR("BITMAP_CopyBitmap failed!");
+            goto CleanupAlpha;
+        }
 
-        psurf = SURFACE_ShareLockSurface(hbmAlpha);
+        psurf = SURFACE_ShareLockSurface(hsurfCopy);
         if(!psurf)
         {
             ERR("SURFACE_LockSurface failed!\n");
-            goto NoAlpha;
+            goto CleanupAlpha;
         }
-        
+
+        /* Premultiply with the alpha channel value */
+        for (i = 0; i < psurf->SurfObj.sizlBitmap.cy; i++)
+        {
+                       ptr = (PBYTE)psurf->SurfObj.pvScan0 + i*psurf->SurfObj.lDelta;
+            for (j = 0; j < psurf->SurfObj.sizlBitmap.cx; j++)
+            {
+                Alpha = ptr[3];
+                ptr[0] = (ptr[0] * Alpha) / 0xff;
+                ptr[1] = (ptr[1] * Alpha) / 0xff;
+                ptr[2] = (ptr[2] * Alpha) / 0xff;
+
+                               ptr += 4;
+            }
+        }
+
         /* Initialize color translation object */
         EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xFFFFFFFF, 0xFFFFFFFF, 0);
-        
+
         /* Now do it */
         Ret = IntEngAlphaBlend(&psurfDest->SurfObj,
                                &psurf->SurfObj,
@@ -1364,19 +1307,22 @@ UserDrawIconEx(
                                &rcDest,
                                &rcSrc,
                                &blendobj);
-        
+
         EXLATEOBJ_vCleanup(&exlo);
-        SURFACE_ShareUnlockSurface(psurf);
-        if(Ret) goto done;
+
+    CleanupAlpha:
+        if(psurf) SURFACE_ShareUnlockSurface(psurf);
+        if(hsurfCopy) NtGdiDeleteObjectApp(hsurfCopy);
+               if(Ret) goto done;
                ERR("NtGdiAlphaBlend failed!\n");
     }
-NoAlpha:
+
     if (diFlags & DI_MASK)
     {
         DWORD rop4 = (diFlags & DI_IMAGE) ? ROP4_SRCAND : ROP4_SRCCOPY;
-        
+
         EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
-        
+
         Ret = IntEngStretchBlt(&psurfDest->SurfObj,
                                &psurfMask->SurfObj,
                                NULL,
@@ -1389,7 +1335,7 @@ NoAlpha:
                                NULL,
                                NULL,
                                rop4);
-        
+
         EXLATEOBJ_vCleanup(&exlo);
 
         if(!Ret)
@@ -1404,9 +1350,9 @@ NoAlpha:
                if (psurfColor)
         {
             DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY ;
-            
+
             EXLATEOBJ_vInitialize(&exlo, psurfColor->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
-            
+
             Ret = IntEngStretchBlt(&psurfDest->SurfObj,
                                    &psurfColor->SurfObj,
                                    NULL,
@@ -1419,7 +1365,7 @@ NoAlpha:
                                    NULL,
                                    NULL,
                                    rop4);
-        
+
             EXLATEOBJ_vCleanup(&exlo);
 
             if(!Ret)
@@ -1433,9 +1379,9 @@ NoAlpha:
             /* Mask bitmap holds the information in its bottom half */
             DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY;
             RECTL_vOffsetRect(&rcSrc, 0, pIcon->Size.cy);
-            
+
             EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
-        
+
             Ret = IntEngStretchBlt(&psurfDest->SurfObj,
                                    &psurfMask->SurfObj,
                                    NULL,
@@ -1448,7 +1394,7 @@ NoAlpha:
                                    NULL,
                                    NULL,
                                    rop4);
-            
+
             EXLATEOBJ_vCleanup(&exlo);
 
             if(!Ret)
@@ -1475,13 +1421,13 @@ done:
         RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
         IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
         RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
-        
+
         /* Prepare the underlying surface */
         DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
-        
+
         /* Get the clip object */
         pdcClipObj = pdc->rosdc.CombinedClip;
-        
+
         /* We now have our destination surface and rectangle */
         psurfDest = pdc->dclevel.pSurface;
         if(!psurfDest)
@@ -1490,10 +1436,10 @@ done:
             DC_UnlockDc(pdc);
             goto Cleanup2;
         }
-        
+
         /* Color translation */
         EXLATEOBJ_vInitialize(&exlo, psurfOffScreen->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
-        
+
         /* Blt it! */
         Ret = IntEngBitBlt(&psurfDest->SurfObj,
                            &psurfOffScreen->SurfObj,
@@ -1506,7 +1452,7 @@ done:
                            NULL,
                            NULL,
                            ROP4_SRCCOPY);
-                           
+
         EXLATEOBJ_vCleanup(&exlo);
     }
 Cleanup:
@@ -1515,12 +1461,12 @@ Cleanup:
         DC_vFinishBlit(pdc, NULL);
         DC_UnlockDc(pdc);
     }
-    
+
 Cleanup2:
     /* Delete off screen rendering surface */
     if(psurfOffScreen)
         GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
-    
+
     /* Unlock other surfaces */
     SURFACE_ShareUnlockSurface(psurfMask);
     if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
@@ -1575,4 +1521,20 @@ NtUserDrawIconEx(
     return Ret;
 }
 
+/*
+ * @unimplemented
+ */
+HCURSOR
+NTAPI
+NtUserGetCursorFrameInfo(
+    HCURSOR hCursor,
+    DWORD istep,
+    INT* rate_jiffies,
+    DWORD* num_steps)
+{
+    STUB
+
+    return 0;
+}
+
 /* EOF */