/* * 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; } }