| /* |
| * Copyright (c) 2003, 2013, 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"); |
| FID_pIShellIcon = env->GetFieldID(cls, "pIShellIcon", "J"); |
| MID_relativePIDL = env->GetMethodID(cls, "setRelativePIDL", "(J)V"); |
| FID_displayName = env->GetFieldID(cls, "displayName", "Ljava/lang/String;"); |
| FID_folderType = env->GetFieldID(cls, "folderType", "Ljava/lang/String;"); |
| } |
| |
| |
| /* |
| * 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; |
| } |
| |
| 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); |
| jchar* wszPath = new jchar[nLength + 1]; |
| const jchar* strPath = env->GetStringChars(jname, NULL); |
| 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); |
| 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); |
| // 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); |
| 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) |
| { |
| return pEnv->NewObject(*pClass, *pConstructor, |
| jstringFromSTRRET(pEnv, NULL, &(psd->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); |
| 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); |
| 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" |