--- old/src/windows/native/sun/windows/ShellFolder2.cpp 2016-03-07 16:28:42.000000000 +0100 +++ new/src/windows/native/sun/windows/ShellFolder2.cpp 2016-03-07 16:28:42.000000000 +0100 @@ -912,19 +912,43 @@ /* * Class: sun_awt_shell_Win32ShellFolder2 * Method: getIconBits - * Signature: (JI)[I + * Signature: (J)[I */ JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconBits - (JNIEnv* env, jclass cls, jlong hicon, jint iconSize) + (JNIEnv* env, jclass cls, jlong hicon) { + const int MAX_ICON_SIZE = 128; + int iconSize = 0; jintArray iconBits = NULL; + BITMAP bmp; + memset(&bmp, 0, sizeof(BITMAP)); + // Get the icon info ICONINFO iconInfo; if (fn_GetIconInfo((HICON)hicon, &iconInfo)) { // Get the screen DC HDC dc = GetDC(NULL); if (dc != NULL) { + // find out the icon size in order to deal with different sizes + // delivered depending on HiDPI mode or SD DPI mode. + if (iconInfo.hbmColor) { + const int nWrittenBytes = GetObject(iconInfo.hbmColor, sizeof(bmp), &bmp); + if(nWrittenBytes > 0) { + iconSize = bmp.bmWidth; + } + } else if (iconInfo.hbmMask) { + // Icon has no color plane, image data stored in mask + const int nWrittenBytes = GetObject(iconInfo.hbmMask, sizeof(bmp), &bmp); + if (nWrittenBytes > 0) { + iconSize = bmp.bmWidth; + } + } + // limit iconSize to MAX_ICON_SIZE, so that the colorBits and maskBits + // arrays are big enough. + // (logic: rather show bad icons than overrun the array size) + iconSize = iconSize > MAX_ICON_SIZE ? MAX_ICON_SIZE : iconSize; + // Set up BITMAPINFO BITMAPINFO bmi; memset(&bmi, 0, sizeof(BITMAPINFO)); @@ -936,7 +960,7 @@ bmi.bmiHeader.biCompression = BI_RGB; // Extract the color bitmap int nBits = iconSize * iconSize; - long colorBits[1024]; + long colorBits[MAX_ICON_SIZE * MAX_ICON_SIZE]; GetDIBits(dc, iconInfo.hbmColor, 0, iconSize, colorBits, &bmi, DIB_RGB_COLORS); // XP supports alpha in some icons, and depending on device. // This should take precedence over the icon mask bits. @@ -951,7 +975,7 @@ } if (!hasAlpha) { // Extract the mask bitmap - long maskBits[1024]; + long maskBits[MAX_ICON_SIZE * MAX_ICON_SIZE]; GetDIBits(dc, iconInfo.hbmMask, 0, iconSize, maskBits, &bmi, DIB_RGB_COLORS); // Copy the mask alphas into the color bits for (int i = 0; i < nBits; i++) { @@ -965,9 +989,9 @@ // Create java array iconBits = env->NewIntArray(nBits); if (!(env->ExceptionCheck())) { - // Copy values to java array - env->SetIntArrayRegion(iconBits, 0, nBits, colorBits); - } + // Copy values to java array + env->SetIntArrayRegion(iconBits, 0, nBits, colorBits); + } } // Fix 4745575 GDI Resource Leak // MSDN @@ -1004,7 +1028,7 @@ HICON hIcon = ImageList_GetIcon(hImageList, iconIndex, ILD_TRANSPARENT); if (hIcon != NULL) { - result = Java_sun_awt_shell_Win32ShellFolder2_getIconBits(env, cls, ptr_to_jlong(hIcon), 16); + result = Java_sun_awt_shell_Win32ShellFolder2_getIconBits(env, cls, ptr_to_jlong(hIcon)); DestroyIcon(hIcon); }