/*
 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#define OEMRESOURCE

#ifdef DEBUG
// Warning : do not depend on anything in <awt.h>.  Including this file
// is a fix for 4507525 to use the same operator new and delete as AWT.
// This file should stand independent of AWT and should ultimately be
// put into its own DLL.
#include <awt.h>
#else
// Include jni_util.h first, so JNU_* macros can be redefined
#include "jni_util.h"
// Borrow some macros from awt.h
#define JNU_NewStringPlatform(env, x) env->NewString(reinterpret_cast<jchar*>(x), static_cast<jsize>(_tcslen(x)))
#define JNU_GetStringPlatformChars(env, x, y) reinterpret_cast<LPCWSTR>(env->GetStringChars(x, y))
#define JNU_ReleaseStringPlatformChars(env, x, y) env->ReleaseStringChars(x, reinterpret_cast<const jchar*>(y))
#endif // DEBUG

#include <windows.h>
#include <shlobj.h>
#include <shellapi.h>
#include "jlong.h"
#include "alloc.h"

#include "stdhdrs.h"

// Copy from shlguid.h which is no longer in PlatformSDK
#ifndef DEFINE_SHLGUID
#define DEFINE_SHLGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0, 0, 0, 0, 0, 0, 0, 0x46)
#endif

// {93F2F68C-1D1B-11d3-A30E-00C04F79ABD1}
DEFINE_GUID(IID_IShellFolder2, 0x93f2f68c, 0x1d1b, 0x11d3, 0xa3, 0xe, 0x0, 0xc0, 0x4f, 0x79, 0xab, 0xd1);

#undef IID_IShellLinkW
#undef IID_IExtractIconW
// copied from shlguid.h
DEFINE_SHLGUID(IID_IShellLinkW,         0x000214F9L, 0, 0);
DEFINE_SHLGUID(IID_IExtractIconW,       0x000214FAL, 0, 0);

//#include <sun_awt_shell_Win32ShellFolder2.h>

// Shell Functions
typedef BOOL (WINAPI *DestroyIconType)(HICON);
typedef HINSTANCE (WINAPI *FindExecutableType)(LPCTSTR,LPCTSTR,LPTSTR);
typedef HICON (WINAPI *ImageList_GetIconType)(HIMAGELIST,int,UINT);
typedef BOOL (WINAPI *GetIconInfoType)(HICON,PICONINFO);
typedef HRESULT (WINAPI *SHGetDesktopFolderType)(IShellFolder**);
typedef DWORD* (WINAPI *SHGetFileInfoType)(LPCTSTR,DWORD,SHFILEINFO*,UINT,UINT);
typedef HRESULT (WINAPI *SHGetMallocType)(IMalloc**);
typedef BOOL (WINAPI *SHGetPathFromIDListType)(LPCITEMIDLIST,LPTSTR);
typedef HRESULT (WINAPI *SHGetSpecialFolderLocationType)(HWND,int,LPITEMIDLIST*);

static DestroyIconType fn_DestroyIcon;
static FindExecutableType fn_FindExecutable;
static GetIconInfoType fn_GetIconInfo;
static ImageList_GetIconType fn_ImageList_GetIcon;
static SHGetDesktopFolderType fn_SHGetDesktopFolder;
static SHGetFileInfoType fn_SHGetFileInfo;
static SHGetMallocType fn_SHGetMalloc;
static SHGetPathFromIDListType fn_SHGetPathFromIDList;
static SHGetSpecialFolderLocationType fn_SHGetSpecialFolderLocation;

// Field IDs
static jmethodID MID_pIShellFolder;
static jfieldID FID_pIShellIcon;
static jmethodID MID_relativePIDL;
static jfieldID FID_displayName;
static jfieldID FID_folderType;

// Other statics
static IMalloc* pMalloc;
static IShellFolder* pDesktop;

// Some macros from awt.h, because it is not included in release
#ifndef IS_WIN2000
#define IS_WIN2000 (LOBYTE(LOWORD(::GetVersion())) >= 5)
#endif
#ifndef IS_WINXP
#define IS_WINXP ((IS_WIN2000 && HIBYTE(LOWORD(::GetVersion())) >= 1) || LOBYTE(LOWORD(::GetVersion())) > 5)
#endif
#ifndef IS_WINVISTA
#define IS_WINVISTA (!(::GetVersion() & 0x80000000) && LOBYTE(LOWORD(::GetVersion())) >= 6)
#endif


extern "C" {

static BOOL initShellProcs()
{
    static HMODULE libShell32 = NULL;
    static HMODULE libUser32 = NULL;
    static HMODULE libComCtl32 = NULL;
    // If already initialized, return TRUE
    if (libShell32 != NULL && libUser32 != NULL) {
        return TRUE;
    }
    // Load libraries
    libShell32 = JDK_LoadSystemLibrary("shell32.dll");
    if (libShell32 == NULL) {
        return FALSE;
    }
    libUser32 = JDK_LoadSystemLibrary("user32.dll");
    if (libUser32 == NULL) {
        return FALSE;
    }
    libComCtl32 = JDK_LoadSystemLibrary("comctl32.dll");
    if (libComCtl32 == NULL) {
        return FALSE;
    }

    // Set up procs - libComCtl32
    fn_ImageList_GetIcon = (ImageList_GetIconType)GetProcAddress(libComCtl32, "ImageList_GetIcon");
    if (fn_ImageList_GetIcon == NULL) {
        return FALSE;
    }

    // Set up procs - libShell32
        fn_FindExecutable = (FindExecutableType)GetProcAddress(
                libShell32, "FindExecutableW");
    if (fn_FindExecutable == NULL) {
        return FALSE;
    }
        fn_SHGetDesktopFolder = (SHGetDesktopFolderType)GetProcAddress(libShell32,
                "SHGetDesktopFolder");
    if (fn_SHGetDesktopFolder == NULL) {
        return FALSE;
    }
        fn_SHGetFileInfo = (SHGetFileInfoType)GetProcAddress(
                libShell32, "SHGetFileInfoW");
    if (fn_SHGetFileInfo == NULL) {
        return FALSE;
    }
        fn_SHGetMalloc = (SHGetMallocType)GetProcAddress(libShell32,
        "SHGetMalloc");
    if (fn_SHGetMalloc == NULL) {
        return FALSE;
    }
    // Set up IMalloc
    if (fn_SHGetMalloc(&pMalloc) != S_OK) {
        return FALSE;
    }
        fn_SHGetPathFromIDList = (SHGetPathFromIDListType)GetProcAddress(
                libShell32, "SHGetPathFromIDListW");
    if (fn_SHGetPathFromIDList == NULL) {
        return FALSE;
    }
        fn_SHGetSpecialFolderLocation = (SHGetSpecialFolderLocationType)
        GetProcAddress(libShell32, "SHGetSpecialFolderLocation");
    if (fn_SHGetSpecialFolderLocation == NULL) {
        return FALSE;
    }

    // Set up procs - libUser32
    fn_GetIconInfo = (GetIconInfoType)GetProcAddress(libUser32, "GetIconInfo");
    if (fn_GetIconInfo == NULL) {
        return FALSE;
    }
    fn_DestroyIcon = (DestroyIconType)GetProcAddress(libUser32, "DestroyIcon");
    if (fn_DestroyIcon == NULL) {
        return FALSE;
    }
    return TRUE;
}

// To call real JNU_NewStringPlatform
#undef JNU_NewStringPlatform
static jstring jstringFromSTRRET(JNIEnv* env, LPITEMIDLIST pidl, STRRET* pStrret) {
    switch (pStrret->uType) {
        case STRRET_CSTR :
            return JNU_NewStringPlatform(env, reinterpret_cast<const char*>(pStrret->cStr));
        case STRRET_OFFSET :
            // Note : this may need to be WCHAR instead
            return JNU_NewStringPlatform(env,
                                         (CHAR*)pidl + pStrret->uOffset);
        case STRRET_WSTR :
            return env->NewString(reinterpret_cast<const jchar*>(pStrret->pOleStr),
                static_cast<jsize>(wcslen(pStrret->pOleStr)));
    }
    return NULL;
}
// restoring the original definition
#define JNU_NewStringPlatform(env, x) env->NewString(reinterpret_cast<jchar*>(x), static_cast<jsize>(_tcslen(x)))

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    initIDs
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_initIDs
    (JNIEnv* env, jclass cls)
{
    if (!initShellProcs()) {
        JNU_ThrowInternalError(env, "Could not initialize shell library");
        return;
    }
    MID_pIShellFolder = env->GetMethodID(cls, "setIShellFolder", "(J)V");
    CHECK_NULL(MID_pIShellFolder);
    FID_pIShellIcon = env->GetFieldID(cls, "pIShellIcon", "J");
    CHECK_NULL(FID_pIShellIcon);
    MID_relativePIDL = env->GetMethodID(cls, "setRelativePIDL", "(J)V");
    CHECK_NULL(MID_relativePIDL);
    FID_displayName = env->GetFieldID(cls, "displayName", "Ljava/lang/String;");
    CHECK_NULL(FID_displayName);
    FID_folderType = env->GetFieldID(cls, "folderType", "Ljava/lang/String;");
    CHECK_NULL(FID_folderType);
}


/*
* Class:     sun_awt_shell_Win32ShellFolderManager2
* Method:    initializeCom
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolderManager2_initializeCom
        (JNIEnv* env, jclass cls)
{
    HRESULT hr = ::CoInitialize(NULL);
    if (FAILED(hr)) {
        char c[64];
        sprintf(c, "Could not initialize COM: HRESULT=0x%08X", hr);
        JNU_ThrowInternalError(env, c);
    }
}

/*
* Class:     sun_awt_shell_Win32ShellFolderManager2
* Method:    uninitializeCom
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolderManager2_uninitializeCom
        (JNIEnv* env, jclass cls)
{
    ::CoUninitialize();
}

static IShellIcon* getIShellIcon(IShellFolder* pIShellFolder) {
    // http://msdn.microsoft.com/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/std_ifaces.asp
    HRESULT hres;
    IShellIcon* pIShellIcon;
    if (pIShellFolder != NULL) {
        hres = pIShellFolder->QueryInterface(IID_IShellIcon, (void**)&pIShellIcon);
        if (SUCCEEDED(hres)) {
            return pIShellIcon;
        }
    }
    return (IShellIcon*)NULL;
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getIShellIcon
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIShellIcon
    (JNIEnv* env, jclass cls, jlong parentIShellFolder)
{
    return (jlong)getIShellIcon((IShellFolder*)parentIShellFolder);
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    initDesktop
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_initDesktop
    (JNIEnv* env, jobject desktop)
{
    // Get desktop IShellFolder
    HRESULT res = fn_SHGetDesktopFolder(&pDesktop);
    if (res != S_OK) {
        JNU_ThrowInternalError(env, "Could not get desktop shell folder");
        return;
    }
    // Set field ID for pIShellFolder
    env->CallVoidMethod(desktop, MID_pIShellFolder, (jlong)pDesktop);
    // Get desktop relative PIDL
    LPITEMIDLIST relPIDL;
    res = fn_SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &relPIDL);
    if (res != S_OK) {
        JNU_ThrowInternalError(env,
            "Could not get desktop shell folder ID list");
        return;
    }
    // Set field ID for relative PIDL
    env->CallVoidMethod(desktop, MID_relativePIDL, (jlong)relPIDL);
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    initSpecial
 * Signature: (JI)V
 */
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_initSpecial
    (JNIEnv* env, jobject folder, jlong desktopIShellFolder, jint folderType)
{
    // Get desktop IShellFolder interface
    IShellFolder* pDesktop = (IShellFolder*)desktopIShellFolder;
    if (pDesktop == NULL) {
        JNU_ThrowInternalError(env, "Desktop shell folder missing");
        return;
    }
    // Get special folder relative PIDL
    LPITEMIDLIST relPIDL;
    HRESULT res = fn_SHGetSpecialFolderLocation(NULL, folderType,
        &relPIDL);
    if (res != S_OK) {
        JNU_ThrowIOException(env, "Could not get shell folder ID list");
        return;
    }
    // Set field ID for relative PIDL
    env->CallVoidMethod(folder, MID_relativePIDL, (jlong)relPIDL);
    // Get special folder IShellFolder interface
    IShellFolder* pFolder;
    res = pDesktop->BindToObject(relPIDL, NULL, IID_IShellFolder,
        (void**)&pFolder);
    if (res != S_OK) {
        JNU_ThrowInternalError(env,
            "Could not bind shell folder to interface");
        return;
    }
    // Set field ID for pIShellFolder
    env->CallVoidMethod(folder, MID_pIShellFolder, (jlong)pFolder);
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getNextPIDLEntry
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getNextPIDLEntry
    (JNIEnv* env, jclass cls, jlong jpIDL)
{
    LPITEMIDLIST pIDL = (LPITEMIDLIST)jpIDL;

    // Check for valid pIDL.
    if(pIDL == NULL)
        return NULL;

    // Get the size of the specified item identifier.
    int cb = pIDL->mkid.cb;

    // If the size is zero, it is the end of the list.
    if (cb == 0)
        return NULL;

    // Add cb to pidl (casting to increment by bytes).
    pIDL = (LPITEMIDLIST)(((LPBYTE)pIDL) + cb);

    // Return NULL if it is null-terminating, or a pidl otherwise.
    return (pIDL->mkid.cb == 0) ? 0 : (jlong)pIDL;
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    copyFirstPIDLEntry
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_copyFirstPIDLEntry
    (JNIEnv* env, jclass cls, jlong jpIDL)
{
    LPITEMIDLIST pIDL = (LPITEMIDLIST)jpIDL;
    if (pIDL == NULL) {
        return 0;
    }
    // Get the size of the specified item identifier.
    int cb = pIDL->mkid.cb;

    // If the size is zero, it is the end of the list.
    if (cb == 0)
        return 0;

    if (!IS_SAFE_SIZE_ADD(cb, sizeof(SHITEMID))) {
        return 0;
    }
    // Allocate space for this as well as null-terminating entry.
    LPITEMIDLIST newPIDL = (LPITEMIDLIST)pMalloc->Alloc(cb + sizeof(SHITEMID));

    // Copy data.
    memcpy(newPIDL, pIDL, cb);

    // Set null terminator for next entry.
    LPITEMIDLIST nextPIDL = (LPITEMIDLIST)(((LPBYTE)newPIDL) + cb);
    nextPIDL->mkid.cb = 0;

    return (jlong)newPIDL;
}

static int pidlLength(LPITEMIDLIST pIDL) {
    int len = 0;
    while (pIDL->mkid.cb != 0) {
        int cb = pIDL->mkid.cb;
        len += cb;
        pIDL = (LPITEMIDLIST)(((LPBYTE)pIDL) + cb);
    }
    return len;
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    combinePIDLs
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_combinePIDLs
    (JNIEnv* env, jclass cls, jlong jppIDL, jlong jpIDL)
{
    // Combine an absolute (fully qualified) pidl in a parent with the relative
    // pidl of a child object to create a new absolute pidl for the child.

    LPITEMIDLIST parentPIDL   = (LPITEMIDLIST)jppIDL;
    LPITEMIDLIST relativePIDL = (LPITEMIDLIST)jpIDL;

    int len1 = pidlLength(parentPIDL);
    int len2 = pidlLength(relativePIDL);

    if (!IS_SAFE_SIZE_ADD(len1, len2) || !IS_SAFE_SIZE_ADD(len1 + len2, sizeof(SHITEMID))) {
        return 0;
    }
    LPITEMIDLIST newPIDL = (LPITEMIDLIST)pMalloc->Alloc(len1 + len2 + sizeof(SHITEMID));
    memcpy(newPIDL, parentPIDL, len1);
    memcpy(((LPBYTE) newPIDL) + len1, relativePIDL, len2);
    LPITEMIDLIST nullTerminator = (LPITEMIDLIST)(((LPBYTE) newPIDL) + len1 + len2);
    nullTerminator->mkid.cb = 0;

    return (jlong) newPIDL;
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    releasePIDL
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_releasePIDL
    (JNIEnv* env, jclass cls, jlong pIDL)
{
    if (pIDL != 0L) {
        pMalloc->Free((LPITEMIDLIST)pIDL);
    }
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    releaseIShellFolder
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_releaseIShellFolder
    (JNIEnv* env, jclass cls, jlong pIShellFolder)
{
    if (pIShellFolder != 0L) {
        ((IShellFolder*)pIShellFolder)->Release();
    }
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    compareIDs
 * Signature: (JJJ)I
 */
JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_compareIDs
    (JNIEnv* env, jclass cls, jlong jpParentIShellFolder, jlong pIDL1, jlong pIDL2)
{
    IShellFolder* pParentIShellFolder = (IShellFolder*)jpParentIShellFolder;
    if (pParentIShellFolder == NULL) {
        return 0;
    }
    return pParentIShellFolder->CompareIDs(0, (LPCITEMIDLIST) pIDL1, (LPCITEMIDLIST) pIDL2);
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getAttributes0
 * Signature: (JJI)J
 */
JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getAttributes0
    (JNIEnv* env, jclass cls, jlong jpParentIShellFolder, jlong jpIDL, jint attrsMask)
{
    IShellFolder* pParentIShellFolder = (IShellFolder*)jpParentIShellFolder;
    if (pParentIShellFolder == NULL) {
        return 0;
    }
    LPCITEMIDLIST pIDL = (LPCITEMIDLIST)jpIDL;
    if (pIDL == NULL) {
        return 0;
    }
    ULONG attrs = attrsMask;
    HRESULT res = pParentIShellFolder->GetAttributesOf(1, &pIDL, &attrs);
    return attrs;
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getFileSystemPath0
 * Signature: (I)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder2_getFileSystemPath0
    (JNIEnv* env, jclass cls, jint csidl)
{
    LPITEMIDLIST relPIDL;
    TCHAR szBuf[MAX_PATH];
    HRESULT res = fn_SHGetSpecialFolderLocation(NULL, csidl, &relPIDL);
    if (res != S_OK) {
        JNU_ThrowIOException(env, "Could not get shell folder ID list");
        return NULL;
    }
    if (fn_SHGetPathFromIDList(relPIDL, szBuf)) {
        return JNU_NewStringPlatform(env, szBuf);
    } else {
        return NULL;
    }
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getEnumObjects
 * Signature: (JZ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getEnumObjects
    (JNIEnv* env, jobject folder, jlong pIShellFolder,
     jboolean isDesktop, jboolean includeHiddenFiles)
{
    IShellFolder* pFolder = (IShellFolder*)pIShellFolder;
    if (pFolder == NULL) {
        return 0;
    }
    DWORD dwFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
    if (includeHiddenFiles) {
        dwFlags |= SHCONTF_INCLUDEHIDDEN;
    }
        /*
    if (!isDesktop) {
        dwFlags = dwFlags | SHCONTF_NONFOLDERS;
    }
        */
    IEnumIDList* pEnum;
    if (pFolder->EnumObjects(NULL, dwFlags, &pEnum) != S_OK) {
        return 0;
    }
    return (jlong)pEnum;
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getNextChild
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getNextChild
    (JNIEnv* env, jobject folder, jlong pEnumObjects)
{
    IEnumIDList* pEnum = (IEnumIDList*)pEnumObjects;
    if (pEnum == NULL) {
        return 0;
    }
    LPITEMIDLIST pidl;
    if (pEnum->Next(1, &pidl, NULL) != S_OK) {
        return 0;
    }
    return (jlong)pidl;
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    releaseEnumObjects
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_releaseEnumObjects
    (JNIEnv* env, jobject folder, jlong pEnumObjects)
{
    IEnumIDList* pEnum = (IEnumIDList*)pEnumObjects;
    if (pEnum == NULL) {
        return;
    }
    pEnum->Release();
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    bindToObject
 * Signature: (JJ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_bindToObject
    (JNIEnv* env, jclass cls, jlong parentIShellFolder, jlong relativePIDL)
{
    IShellFolder* pParent = (IShellFolder*)parentIShellFolder;
    if (pParent == NULL) {
        return 0;
    }
    LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL;
    if (pidl == NULL) {
        return 0;
    }
    IShellFolder* pFolder;
    HRESULT hr = pParent->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&pFolder);
    if (SUCCEEDED (hr)) {
        return (jlong)pFolder;
    }
    return 0;
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getLinkLocation
 * Signature: (JJZ)J;
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation
    (JNIEnv* env, jclass cls, jlong parentIShellFolder, jlong relativePIDL, jboolean resolve)
{
    HRESULT hres;
    STRRET strret;
    OLECHAR olePath[MAX_PATH]; // wide-char version of path name
    LPWSTR wstr;

    IShellFolder* pParent = (IShellFolder*)parentIShellFolder;
    if (pParent == NULL) {
        return NULL;
    }

    LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL;
    if (pidl == NULL) {
        return NULL;
    }

    hres = pParent->GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_FORPARSING, &strret);
    if (FAILED(hres)) {
        return NULL;
    }

    switch (strret.uType) {
      case STRRET_CSTR :
        // IShellFolder::ParseDisplayName requires the path name in Unicode.
        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, strret.cStr, -1, olePath, MAX_PATH);
        wstr = olePath;
        break;

      case STRRET_OFFSET :
        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (CHAR *)pidl + strret.uOffset, -1, olePath, MAX_PATH);
        wstr = olePath;
        break;

      case STRRET_WSTR :
        wstr = strret.pOleStr;
        break;

      default:
        return NULL;
    }

    IShellLinkW* psl;
    hres = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID *)&psl);
    if (SUCCEEDED(hres)) {
        IPersistFile* ppf;
        hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
        if (SUCCEEDED(hres)) {
            hres = ppf->Load(wstr, STGM_READ);
            if (SUCCEEDED(hres)) {
                if (resolve) {
                    hres = psl->Resolve(NULL, 0);
                    // Ignore failure
                }
                pidl = (LPITEMIDLIST)NULL;
                hres = psl->GetIDList(&pidl);
            }
            ppf->Release();
        }
        psl->Release();
    }

    if (strret.uType == STRRET_WSTR) {
        CoTaskMemFree(strret.pOleStr);
    }
    if (SUCCEEDED(hres)) {
        return (jlong)pidl;
    } else {
        return 0;
    }
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    parseDisplayName0
 * Signature: (JLjava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_parseDisplayName0
    (JNIEnv* env, jclass cls, jlong jpIShellFolder, jstring jname)
{

    // Get desktop IShellFolder interface
    IShellFolder* pIShellFolder = (IShellFolder*)jpIShellFolder;
    if (pIShellFolder == NULL) {
        JNU_ThrowInternalError(env, "Desktop shell folder missing");
        return 0;
    }
    // Get relative PIDL for name
    LPITEMIDLIST pIDL;
    int nLength = env->GetStringLength(jname);
    const jchar* strPath = env->GetStringChars(jname, NULL);
    JNU_CHECK_EXCEPTION_RETURN(env, 0);
    jchar* wszPath = new jchar[nLength + 1];
    wcsncpy(reinterpret_cast<LPWSTR>(wszPath), reinterpret_cast<LPCWSTR>(strPath), nLength);
    wszPath[nLength] = 0;
    HRESULT res = pIShellFolder->ParseDisplayName(NULL, NULL,
                        reinterpret_cast<LPWSTR>(wszPath), NULL, &pIDL, NULL);
    if (res != S_OK) {
        JNU_ThrowIOException(env, "Could not parse name");
        pIDL = 0;
    }
    delete[] wszPath;
    env->ReleaseStringChars(jname, strPath);
    return (jlong)pIDL;
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getDisplayNameOf
 * Signature: (JJI)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder2_getDisplayNameOf
    (JNIEnv* env, jclass cls, jlong parentIShellFolder, jlong relativePIDL, jint attrs)
{
    IShellFolder* pParent = (IShellFolder*)parentIShellFolder;
    if (pParent == NULL) {
        return NULL;
    }
    LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL;
    if (pidl == NULL) {
        return NULL;
    }
    STRRET strret;
    if (pParent->GetDisplayNameOf(pidl, attrs, &strret) != S_OK) {
        return NULL;
    }
    jstring result = jstringFromSTRRET(env, pidl, &strret);
    if (strret.uType == STRRET_WSTR) {
        CoTaskMemFree(strret.pOleStr);
    }
    return result;
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getFolderType
 * Signature: (J)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder2_getFolderType
    (JNIEnv* env, jclass cls, jlong pIDL)
{
    SHFILEINFO fileInfo;
    if (fn_SHGetFileInfo((LPCTSTR)pIDL, 0L, &fileInfo, sizeof(fileInfo),
        SHGFI_TYPENAME | SHGFI_PIDL) == 0) {
        return NULL;
    }
    return JNU_NewStringPlatform(env, fileInfo.szTypeName);
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getExecutableType
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder2_getExecutableType
    (JNIEnv* env, jobject folder, jstring path)
{
    TCHAR szBuf[MAX_PATH];
    LPCTSTR szPath = JNU_GetStringPlatformChars(env, path, NULL);
    if (szPath == NULL) {
        return NULL;
    }
    HINSTANCE res = fn_FindExecutable(szPath, szPath, szBuf);
    JNU_ReleaseStringPlatformChars(env, path, szPath);
    if ((UINT_PTR)res < 32) {
        return NULL;
    }
    return JNU_NewStringPlatform(env, szBuf);
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getIcon
 * Signature: (Ljava/lang/String;Z)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIcon
    (JNIEnv* env, jclass cls, jstring absolutePath, jboolean getLargeIcon)
{
    HICON hIcon = NULL;
    SHFILEINFO fileInfo;
    LPCTSTR pathStr = JNU_GetStringPlatformChars(env, absolutePath, NULL);
    JNU_CHECK_EXCEPTION_RETURN(env, 0);
    if (fn_SHGetFileInfo(pathStr, 0L, &fileInfo, sizeof(fileInfo),
                         SHGFI_ICON | (getLargeIcon ? 0 : SHGFI_SMALLICON)) != 0) {
        hIcon = fileInfo.hIcon;
    }
    JNU_ReleaseStringPlatformChars(env, absolutePath, pathStr);
    return (jlong)hIcon;
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getIconIndex
 * Signature: (JJ)I
 */
JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconIndex
    (JNIEnv* env, jclass cls, jlong pIShellIconL, jlong relativePIDL)
{
    IShellIcon* pIShellIcon = (IShellIcon*)pIShellIconL;
    LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL;
    if (pIShellIcon == NULL && pidl == NULL) {
        return 0;
    }

    INT index = -1;

    HRESULT hres;
    // http://msdn.microsoft.com/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/std_ifaces.asp
    if (pIShellIcon != NULL) {
        hres = pIShellIcon->GetIconOf(pidl, GIL_FORSHELL, &index);
    }

    return (jint)index;
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    extractIcon
 * Signature: (JJZ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_extractIcon
    (JNIEnv* env, jclass cls, jlong pIShellFolderL, jlong relativePIDL, jboolean getLargeIcon)
{
    IShellFolder* pIShellFolder = (IShellFolder*)pIShellFolderL;
    LPITEMIDLIST pidl = (LPITEMIDLIST)relativePIDL;
    if (pIShellFolder == NULL || pidl == NULL) {
        return 0;
    }

    HICON hIcon = NULL;

    HRESULT hres;
    IExtractIconW* pIcon;
    hres = pIShellFolder->GetUIObjectOf(NULL, 1, const_cast<LPCITEMIDLIST*>(&pidl),
                                        IID_IExtractIconW, NULL, (void**)&pIcon);
    if (SUCCEEDED(hres)) {
        WCHAR szBuf[MAX_PATH];
        INT index;
        UINT flags;
        hres = pIcon->GetIconLocation(GIL_FORSHELL, szBuf, MAX_PATH, &index, &flags);
        if (SUCCEEDED(hres)) {
            HICON hIconLarge;
            hres = pIcon->Extract(szBuf, index, &hIconLarge, &hIcon, (16 << 16) + 32);
            if (SUCCEEDED(hres)) {
                if (getLargeIcon) {
                    fn_DestroyIcon((HICON)hIcon);
                    hIcon = hIconLarge;
                } else {
                    fn_DestroyIcon((HICON)hIconLarge);
                }
            }
        }
        pIcon->Release();
    }
    return (jlong)hIcon;
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    disposeIcon
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_disposeIcon
    (JNIEnv* env, jclass cls, jlong hicon)
{
    fn_DestroyIcon((HICON)hicon);
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getIconBits
 * Signature: (JI)[I
 */
JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconBits
    (JNIEnv* env, jclass cls, jlong hicon, jint iconSize)
{
    jintArray iconBits = NULL;

    // Get the icon info
    ICONINFO iconInfo;
    if (fn_GetIconInfo((HICON)hicon, &iconInfo)) {
        // Get the screen DC
        HDC dc = GetDC(NULL);
        if (dc != NULL) {
            // Set up BITMAPINFO
            BITMAPINFO bmi;
            memset(&bmi, 0, sizeof(BITMAPINFO));
            bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            bmi.bmiHeader.biWidth = iconSize;
            bmi.bmiHeader.biHeight = -iconSize;
            bmi.bmiHeader.biPlanes = 1;
            bmi.bmiHeader.biBitCount = 32;
            bmi.bmiHeader.biCompression = BI_RGB;
            // Extract the color bitmap
            int nBits = iconSize * iconSize;
            long colorBits[1024];
            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.
            BOOL hasAlpha = FALSE;
            if (IS_WINXP) {
                for (int i = 0; i < nBits; i++) {
                    if ((colorBits[i] & 0xff000000) != 0) {
                        hasAlpha = TRUE;
                        break;
                    }
                }
            }
            if (!hasAlpha) {
                // Extract the mask bitmap
                long maskBits[1024];
                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++) {
                    if (maskBits[i] == 0) {
                        colorBits[i] |= 0xff000000;
                    }
                }
            }
            // Release DC
            ReleaseDC(NULL, dc);
            // Create java array
            iconBits = env->NewIntArray(nBits);
            if (!(env->ExceptionCheck())) {
            // Copy values to java array
            env->SetIntArrayRegion(iconBits, 0, nBits, colorBits);
        }
        }
        // Fix 4745575 GDI Resource Leak
        // MSDN
        // GetIconInfo creates bitmaps for the hbmMask and hbmColor members of ICONINFO.
        // The calling application must manage these bitmaps and delete them when they
        // are no longer necessary.
        ::DeleteObject(iconInfo.hbmColor);
        ::DeleteObject(iconInfo.hbmMask);
    }
    return iconBits;
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getStandardViewButton0
 * Signature: (I)[I
 */
JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getStandardViewButton0
    (JNIEnv* env, jclass cls, jint iconIndex)
{
    jintArray result = NULL;

    // Create a toolbar
    HWND hWndToolbar = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
        0, 0, 0, 0, 0,
        NULL, NULL, NULL, NULL);

    if (hWndToolbar != NULL) {
        SendMessage(hWndToolbar, TB_LOADIMAGES, (WPARAM)IDB_VIEW_SMALL_COLOR, (LPARAM)HINST_COMMCTRL);

        HIMAGELIST hImageList = (HIMAGELIST) SendMessage(hWndToolbar, TB_GETIMAGELIST, 0, 0);

        if (hImageList != NULL) {
            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);

                DestroyIcon(hIcon);
            }

            ImageList_Destroy(hImageList);
        }

        DestroyWindow(hWndToolbar);
    }

    return result;
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getSystemIcon
 * Signature: (I)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getSystemIcon
    (JNIEnv* env, jclass cls, jint iconID)
{
    return (jlong)LoadIcon(NULL, MAKEINTRESOURCE(iconID));
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getIconResource
 * Signature: (Ljava/lang/String;IIIZ)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconResource
    (JNIEnv* env, jclass cls, jstring libName, jint iconID,
     jint cxDesired, jint cyDesired, jboolean useVGAColors)
{
    const char *pLibName = env->GetStringUTFChars(libName, NULL);
    JNU_CHECK_EXCEPTION_RETURN(env, 0);
    HINSTANCE libHandle = (HINSTANCE)JDK_LoadSystemLibrary(pLibName);
    if (libHandle != NULL) {
        UINT fuLoad = (useVGAColors && !IS_WINXP) ? LR_VGACOLOR : 0;
        return ptr_to_jlong(LoadImage(libHandle, MAKEINTRESOURCE(iconID),
                                      IMAGE_ICON, cxDesired, cyDesired,
                                      fuLoad));
    }
    return 0;
}


/*
 * Helper function for creating Java column info object
 */
static jobject CreateColumnInfo(JNIEnv *pEnv,
                                jclass *pClass, jmethodID *pConstructor,
                                SHELLDETAILS *psd, ULONG visible)
{
    jstring str = jstringFromSTRRET(pEnv, NULL, &(psd->str));
    JNU_CHECK_EXCEPTION_RETURN(pEnv, NULL);

    return pEnv->NewObject(*pClass, *pConstructor,
                    str,
                    (jint)(psd->cxChar * 6), // TODO: is 6 OK for converting chars to pixels?
                    (jint)psd->fmt, (jboolean) visible);
}


/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    doGetColumnInfo
 * Signature: (J)[Lsun/awt/shell/ShellFolderColumnInfo;
 */
JNIEXPORT jobjectArray JNICALL
    Java_sun_awt_shell_Win32ShellFolder2_doGetColumnInfo
            (JNIEnv *env, jobject obj, jlong iShellFolder)
{

    HRESULT hr;
    IShellFolder *pIShellFolder = (IShellFolder*) iShellFolder;
    IUnknown *pIUnknown = NULL;

    jclass columnClass = env->FindClass("sun/awt/shell/ShellFolderColumnInfo");
    if(NULL == columnClass) {
        return NULL;
    }

    jmethodID columnConstructor =
        env->GetMethodID(columnClass, "<init>", "(Ljava/lang/String;IIZ)V");
    if(NULL == columnConstructor) {
        return NULL;
    }

    // We'are asking the object the list of available columns
    SHELLDETAILS sd;

    hr = pIShellFolder->QueryInterface(IID_IShellFolder2, (void**)&pIUnknown);
    if(SUCCEEDED (hr)) {

        // The folder exposes IShellFolder2 interface
        IShellFolder2 *pIShellFolder2 = (IShellFolder2*) pIUnknown;

        // Count columns
        int colNum = -1;
        hr = S_OK;
        do{
            hr = pIShellFolder2->GetDetailsOf(NULL, ++colNum, &sd);
        } while (SUCCEEDED (hr));

        jobjectArray columns =
            env->NewObjectArray((jsize) colNum, columnClass, NULL);
        if(NULL == columns) {
            pIShellFolder2->Release();
            return NULL;
        }

        // Fill column details list
        SHCOLSTATEF csFlags;
        colNum = 0;
        hr = S_OK;
        while (SUCCEEDED (hr)) {
            hr = pIShellFolder2->GetDetailsOf(NULL, colNum, &sd);

            if (SUCCEEDED (hr)) {
                hr = pIShellFolder2->GetDefaultColumnState(colNum, &csFlags);
                if (SUCCEEDED (hr)) {
                    if(!(csFlags & SHCOLSTATE_HIDDEN)) {
                        jobject column = CreateColumnInfo(env,
                                            &columnClass, &columnConstructor,
                                            &sd, csFlags & SHCOLSTATE_ONBYDEFAULT);
                        if(!column){
                            pIShellFolder2->Release();
                            return NULL;
                        }
                        env->SetObjectArrayElement(columns, (jsize) colNum, column);
                    }
                }
                colNum++;
            }
        }

        pIShellFolder2->Release();

        return columns;
    }

    hr = pIShellFolder->CreateViewObject(NULL, IID_IShellDetails, (void**)&pIUnknown);
    if(SUCCEEDED (hr)) {
        // The folder exposes IShellDetails interface
        IShellDetails *pIShellDetails = (IShellDetails*) pIUnknown;

        // Count columns
        int colNum = -1;
        hr = S_OK;
        do{
            hr = pIShellDetails->GetDetailsOf(NULL, ++colNum, &sd);
        } while (SUCCEEDED (hr));

        jobjectArray columns =
            env->NewObjectArray((jsize) colNum, columnClass, NULL);
        if(NULL == columns) {
            pIShellDetails->Release();
            return NULL;
        }

        // Fill column details list
        colNum = 0;
        hr = S_OK;
        while (SUCCEEDED (hr)) {
            hr = pIShellDetails->GetDetailsOf(NULL, colNum, &sd);
            if (SUCCEEDED (hr)) {
                jobject column = CreateColumnInfo(env,
                                    &columnClass, &columnConstructor,
                                    &sd, 1);
                if(!column){
                    pIShellDetails->Release();
                    return NULL;
                }
                env->SetObjectArrayElement(columns, (jsize) colNum++, column);
            }
        }

        pIShellDetails->Release();

        return columns;
    }

    // The folder exposes neither IShellFolder2 nor IShelDetails
    return NULL;

}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    doGetColumnValue
 * Signature: (JJI)Ljava/lang/Object;
 */
JNIEXPORT jobject JNICALL
    Java_sun_awt_shell_Win32ShellFolder2_doGetColumnValue
            (JNIEnv *env, jobject obj, jlong iShellFolder,
            jlong jpidl, jint columnIdx)
{

    HRESULT hr;
    IShellFolder *pIShellFolder = (IShellFolder*) iShellFolder;
    IUnknown *pIUnknown = NULL;


    LPITEMIDLIST pidl = (LPITEMIDLIST) jpidl;
    SHELLDETAILS sd;

    hr = pIShellFolder->QueryInterface(IID_IShellFolder2, (void**)&pIUnknown);
    if(SUCCEEDED (hr)) {
        // The folder exposes IShellFolder2 interface
        IShellFolder2 *pIShellFolder2 = (IShellFolder2*) pIUnknown;
        hr = pIShellFolder2->GetDetailsOf(pidl, (UINT)columnIdx, &sd);
        pIShellFolder2->Release();
        if (SUCCEEDED (hr)) {
            STRRET strRet = sd.str;
            return jstringFromSTRRET(env, pidl, &strRet);
        }
    }

    hr = pIShellFolder->CreateViewObject(NULL, IID_IShellDetails, (void**)&pIUnknown);
    if(SUCCEEDED (hr)) {
        // The folder exposes IShellDetails interface
        IShellDetails *pIShellDetails = (IShellDetails*) pIUnknown;
        hr = pIShellDetails->GetDetailsOf(pidl, (UINT)columnIdx, &sd);
        pIShellDetails->Release();
        if (SUCCEEDED (hr)) {
            STRRET strRet = sd.str;
            return jstringFromSTRRET(env, pidl, &strRet);
        }
    }

    // The folder exposes neither IShellFolder2 nor IShelDetails
    return NULL;
}

/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    compareIDsByColumn
 * Signature: (JJJI)I
 */
JNIEXPORT jint JNICALL
    Java_sun_awt_shell_Win32ShellFolder2_compareIDsByColumn
            (JNIEnv* env, jclass cls, jlong jpParentIShellFolder,
            jlong pIDL1, jlong pIDL2, jint columnIdx)
{
    IShellFolder* pParentIShellFolder = (IShellFolder*)jpParentIShellFolder;
    if (pParentIShellFolder == NULL) {
        return 0;
    }

    HRESULT hr = pParentIShellFolder->CompareIDs(
                                            (UINT) columnIdx,
                                            (LPCITEMIDLIST) pIDL1,
                                            (LPCITEMIDLIST) pIDL2);
    if (SUCCEEDED (hr)) {
        return (jint) (short) HRESULT_CODE(hr);
    }

    return 0;
}


} // extern "C"
