TEST_F(ShellTest, CreateAndResolveShortcut) { // FIXME i#12: Re-enable on XP when passes. if (GetWindowsVersion() < WIN_VISTA) { printf("WARNING: Disabling ShellTest.* on Pre-Vista, see i#12.\n"); return; } HRESULT hr; IShellLinkW *shell; IPersistFile *persist = NULL; // Create a shortcut. hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)(&shell)); EXPECT_TRUE(SUCCEEDED(hr)); hr = shell->QueryInterface(IID_IPersistFile, (void**)(&persist)); EXPECT_TRUE(SUCCEEDED(hr)); hr = shell->SetPath(file_path_.c_str()); EXPECT_TRUE(SUCCEEDED(hr)); hr = shell->SetDescription(kLinkDescription); EXPECT_TRUE(SUCCEEDED(hr)); hr = persist->Save(link_path_.c_str(), TRUE); EXPECT_TRUE(SUCCEEDED(hr)); if (persist) persist->Release(); if (shell) shell->Release(); // Resolve it. // Get pointer to the IShellLink interface hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&shell); EXPECT_TRUE(SUCCEEDED(hr)); // Query IShellLink for the IPersistFile interface hr = shell->QueryInterface(IID_IPersistFile, (void**)(&persist)); EXPECT_TRUE(SUCCEEDED(hr)); // Load the shell link hr = persist->Load(link_path_.c_str(), STGM_READ); EXPECT_TRUE(SUCCEEDED(hr)); // Try to find the target of a shortcut hr = shell->Resolve(0, SLR_NO_UI); EXPECT_TRUE(SUCCEEDED(hr)); wchar_t link_target[MAX_PATH]; hr = shell->GetPath(link_target, MAX_PATH, NULL, SLGP_UNCPRIORITY); EXPECT_TRUE(SUCCEEDED(hr)); EXPECT_EQ(file_path_, link_target); wchar_t description[MAX_PATH]; hr = shell->GetDescription(description, MAX_PATH); EXPECT_TRUE(SUCCEEDED(hr)); EXPECT_STREQ(kLinkDescription, description); if (persist) persist->Release(); if (shell) shell->Release(); }
/* * 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; } }
HRESULT ShellFunctions::ResolveShortcut(HWND hWnd,LPCWSTR pszShortcutFile,LPWSTR pszPath) { HRESULT hres; pszPath[0]='\0'; if (IsUnicodeSystem()) { IShellLinkW* psl; WIN32_FIND_DATAW wfd; hres=CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLinkW,(void**)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; hres=psl->QueryInterface(IID_IPersistFile,(void**)&ppf); if (SUCCEEDED(hres)) { hres=ppf->Load(pszShortcutFile,STGM_READ); if (SUCCEEDED(hres)) { hres=psl->Resolve(hWnd,SLR_ANY_MATCH); if (pszPath!=NULL && SUCCEEDED(hres)) hres=psl->GetPath(pszPath,MAX_PATH,(WIN32_FIND_DATAW*)&wfd,0); } ppf->Release(); } psl->Release(); } } else { IShellLink* psl; WIN32_FIND_DATA wfd; hres=CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void**)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; hres=psl->QueryInterface(IID_IPersistFile,(void**)&ppf); if (SUCCEEDED(hres)) { hres=ppf->Load(pszShortcutFile,STGM_READ); if (SUCCEEDED(hres)) { hres=psl->Resolve(hWnd,SLR_ANY_MATCH); if (pszPath!=NULL && SUCCEEDED(hres)) { char szPathA[MAX_PATH]; hres=psl->GetPath(szPathA,MAX_PATH,(WIN32_FIND_DATA*)&wfd,0); if (SUCCEEDED(hres)) MultiByteToWideChar(CP_ACP,0,szPathA,-1,pszPath,MAX_PATH); } } ppf->Release(); } psl->Release(); } } return hres; }