BOOL NetPlaceConvertW(WCHAR *src, WCHAR *dst) { IShellLinkW *shellLink; IPersistFile *persistFile; WCHAR wDstBuf[MAX_PATH]; WCHAR *wSrc = src; WCHAR *wDst = wDstBuf; BOOL ret = FALSE; DWORD attr, attr_mask = FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_READONLY; if ((attr = ::GetFileAttributesW(src)) == 0xffffffff || (attr & attr_mask) != attr_mask) return FALSE; // ディレクトリかつronly でないものは関係ない if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&shellLink))) { if (SUCCEEDED(shellLink->QueryInterface(IID_IPersistFile, (void **)&persistFile))) { if (SUCCEEDED(persistFile->Load(wSrc, STGM_READ))) { if (SUCCEEDED(shellLink->GetPath(wDst, MAX_PATH, 0, SLGP_UNCPRIORITY))) { MakePathW(dst, wDstBuf, L""); ret = TRUE; } } persistFile->Release(); } shellLink->Release(); } return ret; }
TEST_F(ShellTest, CreateShortcut) { // 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(); }
// (static) Creates a ShellLink that encapsulate a separator. nsresult JumpListSeparator::GetSeparator(nsRefPtr<IShellLinkW>& aShellLink) { HRESULT hr; IShellLinkW* psl; // Create a IShellLink. hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; IPropertyStore* pPropStore = nullptr; hr = psl->QueryInterface(IID_IPropertyStore, (LPVOID*)&pPropStore); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; PROPVARIANT pv; InitPropVariantFromBoolean(TRUE, &pv); pPropStore->SetValue(PKEY_AppUserModel_IsDestListSeparator, pv); pPropStore->Commit(); pPropStore->Release(); PropVariantClear(&pv); aShellLink = dont_AddRef(psl); return NS_OK; }
HRESULT ShellFunctions::GetShortcutTarget(LPCWSTR pszShortcutFile,LPWSTR pszTarget,DWORD nBufSize) { HRESULT hres; 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->GetPath(pszTarget,nBufSize,(WIN32_FIND_DATAW*)&wfd,0); ppf->Release(); } psl->Release(); } } else { IShellLinkA* psl; WIN32_FIND_DATA wfd; hres=CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLinkA,(void**)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; hres=psl->QueryInterface(IID_IPersistFile,(void**)&ppf); if (SUCCEEDED(hres)) { char* pTargetTmp=new char[nBufSize+2]; hres=ppf->Load(pszShortcutFile,STGM_READ); if (SUCCEEDED(hres)) hres=psl->GetPath(pTargetTmp,nBufSize,(WIN32_FIND_DATA*)&wfd,0); MultiByteToWideChar(CP_ACP,0,pTargetTmp,-1,pszTarget,nBufSize); delete[] pTargetTmp; ppf->Release(); } psl->Release(); } } return hres; }
HRESULT CTaskbar7::AddRecent(BSTR name, BSTR path, BSTR arguments, BSTR icon) { USES_CONVERSION; // ANSI version doesn't seem to work correctly with Win7 jump lists, so explicitly use Unicode interface. IShellLinkW *pShellLink = NULL; IPropertyStore *pPropertyStore = NULL; PROPVARIANT propVariant; HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pShellLink)); EXIT_ON_ERROR(hr); // Path hr = pShellLink->SetPath(path); EXIT_ON_ERROR(hr); // Arguments hr = pShellLink->SetArguments(arguments); EXIT_ON_ERROR(hr); // Icon Location hr = pShellLink->SetIconLocation(wstring(icon).empty() ? path : icon, 0); EXIT_ON_ERROR(hr); hr = pShellLink->QueryInterface(IID_PPV_ARGS(&pPropertyStore)); EXIT_ON_ERROR(hr); // Name hr = InitPropVariantFromString(name, &propVariant); EXIT_ON_ERROR(hr); hr = pPropertyStore->SetValue(PKEY_Title, propVariant); EXIT_ON_ERROR(hr); hr = pPropertyStore->Commit(); EXIT_ON_ERROR(hr); // SHAddToRecentDocs will cause the link to be added to the Recent list, allowing the user to pin them. SHAddToRecentDocs(SHARD_LINK, pShellLink); Exit: PropVariantClear(&propVariant); SAFE_RELEASE(pPropertyStore); SAFE_RELEASE(pShellLink); return hr; }
NTSTATUS GetPathFromLinkFile(PCWSTR LinkFilePath, PWCHAR FullPath, ULONG BufferCount) { HRESULT hResult; IShellLinkW *ShellLink; IPersistFile *PersistFile; CoInitialize(NULL); hResult = S_OK; ShellLink = NULL; PersistFile = NULL; LOOP_ONCE { hResult = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (PVOID *)&ShellLink ); if (FAILED(hResult)) break; hResult = ShellLink->QueryInterface(IID_IPersistFile, (PVOID *)&PersistFile); if (FAILED(hResult)) break; hResult = PersistFile->Load(LinkFilePath, 0); if (FAILED(hResult)) break; hResult = ShellLink->GetPath(FullPath, BufferCount, NULL, SLGP_UNCPRIORITY); } if (PersistFile != NULL) PersistFile->Release(); if (ShellLink != NULL) ShellLink->Release(); CoUninitialize(); return hResult; }
void MusicRegeditManager::setFileLink(const QString &src, const QString &des, const QString &ico, const QString &args, const QString &description) { #ifdef Q_OS_WIN HRESULT hres = CoInitialize(nullptr); if(SUCCEEDED(hres)) { IShellLinkW *psl = nullptr; hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); if(SUCCEEDED(hres)) { IPersistFile *ppf; if(!src.isEmpty()) { psl->SetPath(src.toStdWString().c_str()); } if(!ico.isEmpty()) { psl->SetIconLocation(ico.toStdWString().c_str(), 0); } if(!args.isEmpty()) { psl->SetArguments(args.toStdWString().c_str()); } if(!description.isEmpty()) { psl->SetDescription(description.toStdWString().c_str()); } hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); if(SUCCEEDED(hres)) { ppf->Save(des.toStdWString().c_str(), FALSE); ppf->Release(); } psl->Release(); } } #else QFile file(":/ext/desktop"); if(file.open(QFile::ReadOnly)) { QByteArray data(file.readAll()); file.close(); data.append(QString("Icon=%1\n").arg(ico)); data.append(QString("Exec=%1\n").arg(ico + src)); data.append(QString("Path=%1\n").arg(args)); file.setFileName(des + "/" + description + ".desktop"); if(file.open(QFile::WriteOnly)) { file.write(data); file.close(); QProcess::execute("chmod", QStringList() << "+x" << file.fileName()); } } #endif }
// TransferIObjectArrayToIMutableArray - used in converting removed items // to our objects. nsresult JumpListBuilder::TransferIObjectArrayToIMutableArray(IObjectArray *objArray, nsIMutableArray *removedItems) { NS_ENSURE_ARG_POINTER(objArray); NS_ENSURE_ARG_POINTER(removedItems); nsresult rv; uint32_t count = 0; objArray->GetCount(&count); nsCOMPtr<nsIJumpListItem> item; for (uint32_t idx = 0; idx < count; idx++) { IShellLinkW * pLink = nullptr; IShellItem * pItem = nullptr; if (SUCCEEDED(objArray->GetAt(idx, IID_IShellLinkW, (LPVOID*)&pLink))) { nsCOMPtr<nsIJumpListShortcut> shortcut = do_CreateInstance(kJumpListShortcutCID, &rv); if (NS_FAILED(rv)) return NS_ERROR_UNEXPECTED; rv = JumpListShortcut::GetJumpListShortcut(pLink, shortcut); item = do_QueryInterface(shortcut); } else if (SUCCEEDED(objArray->GetAt(idx, IID_IShellItem, (LPVOID*)&pItem))) { nsCOMPtr<nsIJumpListLink> link = do_CreateInstance(kJumpListLinkCID, &rv); if (NS_FAILED(rv)) return NS_ERROR_UNEXPECTED; rv = JumpListLink::GetJumpListLink(pItem, link); item = do_QueryInterface(link); } if (pLink) pLink->Release(); if (pItem) pItem->Release(); if (NS_SUCCEEDED(rv)) { removedItems->AppendElement(item, false); } } return NS_OK; }
void Win32TaskbarManager::addRecent(const Common::String &name, const Common::String &description) { //warning("[Win32TaskbarManager::addRecent] Adding recent list entry: %s (%s)", name.c_str(), description.c_str()); if (_taskbar == NULL) return; // ANSI version doesn't seem to work correctly with Win7 jump lists, so explicitly use Unicode interface. IShellLinkW *link; // Get the ScummVM executable path. WCHAR path[MAX_PATH]; GetModuleFileNameW(NULL, path, MAX_PATH); // Create a shell link. if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC, IID_IShellLinkW, reinterpret_cast<void **> (&link)))) { // Convert game name and description to Unicode. LPWSTR game = ansiToUnicode(name.c_str()); LPWSTR desc = ansiToUnicode(description.c_str()); // Set link properties. link->SetPath(path); link->SetArguments(game); Common::String iconPath = getIconPath(name); if (iconPath.empty()) { link->SetIconLocation(path, 0); // No game-specific icon available } else { LPWSTR icon = ansiToUnicode(iconPath.c_str()); link->SetIconLocation(icon, 0); delete[] icon; } // The link's display name must be set via property store. IPropertyStore* propStore; HRESULT hr = link->QueryInterface(IID_IPropertyStore, reinterpret_cast<void **> (&(propStore))); if (SUCCEEDED(hr)) { PROPVARIANT pv; pv.vt = VT_LPWSTR; pv.pwszVal = desc; hr = propStore->SetValue(PKEY_Title, pv); propStore->Commit(); propStore->Release(); } // SHAddToRecentDocs will cause the games to be added to the Recent list, allowing the user to pin them. SHAddToRecentDocs(SHARD_LINK, link); link->Release(); delete[] game; delete[] desc; } }
/* リンク あらかじめ、CoInitialize(NULL); を実行しておくこと src ... old_path dest ... new_path */ BOOL SymLinkW(WCHAR *src, WCHAR *dest, WCHAR *arg) { IShellLinkW *shellLink; IPersistFile *persistFile; WCHAR *ps_dest = dest; BOOL ret = FALSE; WCHAR buf[MAX_PATH]; if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&shellLink))) { shellLink->SetPath(src); shellLink->SetArguments(arg); GetParentDirW(src, buf); shellLink->SetWorkingDirectory(buf); if (SUCCEEDED(shellLink->QueryInterface(IID_IPersistFile, (void **)&persistFile))) { if (SUCCEEDED(persistFile->Save(ps_dest, TRUE))) { ret = TRUE; GetParentDirW(dest, buf); ::SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATHW|SHCNF_FLUSH, buf, NULL); } persistFile->Release(); } shellLink->Release(); } return ret; }
/****************************************************************** CreateLink - Creates a shortcut via IShellLinkW *******************************************************************/ static HRESULT CreateLink( __in_z LPCWSTR wzTarget, __in_z LPCWSTR wzShortcutPath, __in_z_opt LPCWSTR wzIconPath, __in int iconIndex ) { HRESULT hr = S_OK; IShellLinkW* piShellLink = NULL; IPersistFile* piPersistFile = NULL; // create an internet shortcut object WcaLog(LOGMSG_STANDARD, "Creating IShellLinkW shortcut '%ls' target '%ls'", wzShortcutPath, wzTarget); hr = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLinkW, (void**)&piShellLink); ExitOnFailure(hr, "failed to create an instance of IShellLinkW"); // set shortcut target hr = piShellLink->SetPath(wzTarget); ExitOnFailure2(hr, "failed to set shortcut '%ls' target '%ls'", wzShortcutPath, wzTarget); if (wzIconPath) { hr = piShellLink->SetIconLocation(wzIconPath, iconIndex); ExitOnFailure2(hr, "failed to set icon for shortcut '%ls'", wzShortcutPath); } // get an IPersistFile and save the shortcut hr = piShellLink->QueryInterface(IID_IPersistFile, (void**)&piPersistFile); ExitOnFailure1(hr, "failed to get IPersistFile for shortcut '%ls'", wzShortcutPath); hr = piPersistFile->Save(wzShortcutPath, TRUE); ExitOnFailure1(hr, "failed to save shortcut '%ls'", wzShortcutPath); LExit: ReleaseObject(piPersistFile); ReleaseObject(piShellLink); return hr; }
BOOL ReadLinkW(WCHAR *src, WCHAR *dest, WCHAR *arg) { IShellLinkW *shellLink; // 実際は IShellLinkA or IShellLinkW IPersistFile *persistFile; BOOL ret = FALSE; if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&shellLink))) { if (SUCCEEDED(shellLink->QueryInterface(IID_IPersistFile, (void **)&persistFile))) { if (SUCCEEDED(persistFile->Load((WCHAR *)src, STGM_READ))) { if (SUCCEEDED(shellLink->GetPath(dest, MAX_PATH, NULL, 0))) { if (arg) { shellLink->GetArguments(arg, MAX_PATH); } ret = TRUE; } } persistFile->Release(); } shellLink->Release(); } return ret; }
// (static) Creates a ShellLink that encapsulate a shortcut to local apps. nsresult JumpListShortcut::GetShellLink(nsCOMPtr<nsIJumpListItem>& item, nsRefPtr<IShellLinkW>& aShellLink) { HRESULT hr; IShellLinkW* psl; nsresult rv; // Shell links: // http://msdn.microsoft.com/en-us/library/bb776891(VS.85).aspx // http://msdn.microsoft.com/en-us/library/bb774950(VS.85).aspx PRInt16 type; if (NS_FAILED(item->GetType(&type))) return NS_ERROR_INVALID_ARG; if (type != nsIJumpListItem::JUMPLIST_ITEM_SHORTCUT) return NS_ERROR_INVALID_ARG; nsCOMPtr<nsIJumpListShortcut> shortcut = do_QueryInterface(item, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsILocalHandlerApp> handlerApp; rv = shortcut->GetApp(getter_AddRefs(handlerApp)); NS_ENSURE_SUCCESS(rv, rv); // Create a IShellLink hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; // Retrieve the app path, title, description and optional command line args. nsAutoString appPath, appTitle, appDescription, appArgs; PRInt32 appIconIndex = 0; // Path nsCOMPtr<nsIFile> executable; handlerApp->GetExecutable(getter_AddRefs(executable)); nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(executable, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = localFile->GetPath(appPath); NS_ENSURE_SUCCESS(rv, rv); // Command line parameters PRUint32 count = 0; handlerApp->GetParameterCount(&count); for (PRUint32 idx = 0; idx < count; idx++) { if (idx > 0) appArgs.Append(NS_LITERAL_STRING(" ")); nsAutoString param; rv = handlerApp->GetParameter(idx, param); if (NS_FAILED(rv)) return rv; appArgs.Append(param); } handlerApp->GetName(appTitle); handlerApp->GetDetailedDescription(appDescription); shortcut->GetIconIndex(&appIconIndex); // Store the title of the app if (appTitle.Length() > 0) { IPropertyStore* pPropStore = nsnull; hr = psl->QueryInterface(IID_IPropertyStore, (LPVOID*)&pPropStore); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; PROPVARIANT pv; InitPropVariantFromString(appTitle.get(), &pv); pPropStore->SetValue(PKEY_Title, pv); pPropStore->Commit(); pPropStore->Release(); PropVariantClear(&pv); } // Store the rest of the params psl->SetPath(appPath.get()); psl->SetDescription(appDescription.get()); psl->SetArguments(appArgs.get()); psl->SetIconLocation(appPath.get(), appIconIndex); aShellLink = dont_AddRef(psl); return NS_OK; }
/* * 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::CreateShortcut(LPCWSTR pszShortcutFile,LPCWSTR pszLink,LPCWSTR pszDesc,LPCWSTR pszParams) { HRESULT hres; if (IsUnicodeSystem()) { IShellLinkW* psl; 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=psl->SetPath(pszLink); if (SUCCEEDED(hres)) { int nIndex=LastCharIndex(pszLink,L'\\'); if (nIndex>=0) { WCHAR szWDir[MAX_PATH]; MemCopyW(szWDir,pszLink,nIndex); szWDir[nIndex]='\0'; psl->SetWorkingDirectory(szWDir); } if (pszDesc!=NULL) psl->SetDescription(pszDesc); if (pszParams!=NULL) psl->SetArguments(pszParams); hres=ppf->Save(pszShortcutFile,TRUE); } ppf->Release(); } psl->Release(); } } else { IShellLink* psl; 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=psl->SetPath(W2A(pszLink)); if (SUCCEEDED(hres)) { LONG_PTR nIndex=LastCharIndex(pszLink,L'\\'); if (nIndex>=0) { char szWDir[MAX_PATH]; WideCharToMultiByte(CP_ACP,0,pszLink,(int)nIndex,szWDir,MAX_PATH,0,0); szWDir[nIndex]='\0'; psl->SetWorkingDirectory(szWDir); } if (pszDesc!=NULL) psl->SetDescription(W2A(pszDesc)); if (pszParams!=NULL) psl->SetArguments(W2A(pszParams)); hres=ppf->Save(pszShortcutFile,TRUE); } ppf->Release(); } psl->Release(); } } return hres; }
bool CreateLinkInner(wchar_t *filename, wchar_t *target, wchar_t *workdir, wchar_t *args, wchar_t *comment, wchar_t *icon, UINT icon_index) { HRESULT r; bool ret; IShellLinkW* pShellLink; IPersistFile* pPersistFile; if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType)) { char *a1, *a2, *a3, *a4, *a5, *a6; a1 = CopyUniToStr(filename); a2 = CopyUniToStr(target); a3 = CopyUniToStr(workdir); a4 = CopyUniToStr(args); a5 = CopyUniToStr(icon); a6 = CopyUniToStr(comment); ret = CreateLinkInnerA(a1, a2, a3, a4, a6, a5, icon_index); Free(a1); Free(a2); Free(a3); Free(a4); Free(a5); Free(a6); return ret; } r = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&pShellLink); if (FAILED(r)) { return false; } r = pShellLink->QueryInterface(IID_IPersistFile,(void **)&pPersistFile); if (FAILED(r)) { pShellLink->Release(); return false; } r = pShellLink->SetPath(target); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } if (workdir != NULL) { r = pShellLink->SetWorkingDirectory(workdir); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } } if (comment != NULL) { r = pShellLink->SetDescription(comment); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } } if (args != NULL) { r = pShellLink->SetArguments(args); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } } if (icon != NULL) { r = pShellLink->SetIconLocation(icon, icon_index); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } } r = pPersistFile->Save(filename, true); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } pShellLink->Release(); pPersistFile->Release(); return true; }
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; }
// (static) Creates a ShellLink that encapsulate a shortcut to local apps. nsresult JumpListShortcut::GetShellLink(nsCOMPtr<nsIJumpListItem>& item, nsRefPtr<IShellLinkW>& aShellLink, nsCOMPtr<nsIThread> &aIOThread) { HRESULT hr; IShellLinkW* psl; nsresult rv; // Shell links: // http://msdn.microsoft.com/en-us/library/bb776891(VS.85).aspx // http://msdn.microsoft.com/en-us/library/bb774950(VS.85).aspx int16_t type; if (NS_FAILED(item->GetType(&type))) return NS_ERROR_INVALID_ARG; if (type != nsIJumpListItem::JUMPLIST_ITEM_SHORTCUT) return NS_ERROR_INVALID_ARG; nsCOMPtr<nsIJumpListShortcut> shortcut = do_QueryInterface(item, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsILocalHandlerApp> handlerApp; rv = shortcut->GetApp(getter_AddRefs(handlerApp)); NS_ENSURE_SUCCESS(rv, rv); // Create a IShellLink hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; // Retrieve the app path, title, description and optional command line args. nsAutoString appPath, appTitle, appDescription, appArgs; int32_t appIconIndex = 0; // Path nsCOMPtr<nsIFile> executable; handlerApp->GetExecutable(getter_AddRefs(executable)); rv = executable->GetPath(appPath); NS_ENSURE_SUCCESS(rv, rv); // Command line parameters uint32_t count = 0; handlerApp->GetParameterCount(&count); for (uint32_t idx = 0; idx < count; idx++) { if (idx > 0) appArgs.Append(NS_LITERAL_STRING(" ")); nsAutoString param; rv = handlerApp->GetParameter(idx, param); if (NS_FAILED(rv)) return rv; appArgs.Append(param); } handlerApp->GetName(appTitle); handlerApp->GetDetailedDescription(appDescription); bool useUriIcon = false; // if we want to use the URI icon bool usedUriIcon = false; // if we did use the URI icon shortcut->GetIconIndex(&appIconIndex); nsCOMPtr<nsIURI> iconUri; rv = shortcut->GetFaviconPageUri(getter_AddRefs(iconUri)); if (NS_SUCCEEDED(rv) && iconUri) { useUriIcon = true; } // Store the title of the app if (appTitle.Length() > 0) { IPropertyStore* pPropStore = nullptr; hr = psl->QueryInterface(IID_IPropertyStore, (LPVOID*)&pPropStore); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; PROPVARIANT pv; InitPropVariantFromString(appTitle.get(), &pv); pPropStore->SetValue(PKEY_Title, pv); pPropStore->Commit(); pPropStore->Release(); PropVariantClear(&pv); } // Store the rest of the params psl->SetPath(appPath.get()); psl->SetDescription(appDescription.get()); psl->SetArguments(appArgs.get()); if (useUriIcon) { nsString icoFilePath; rv = mozilla::widget::FaviconHelper::ObtainCachedIconFile(iconUri, icoFilePath, aIOThread, false); if (NS_SUCCEEDED(rv)) { // Always use the first icon in the ICO file // our encoded icon only has 1 resource psl->SetIconLocation(icoFilePath.get(), 0); usedUriIcon = true; } } // We didn't use an ICO via URI so fall back to the app icon if (!usedUriIcon) { psl->SetIconLocation(appPath.get(), appIconIndex); } aShellLink = dont_AddRef(psl); return NS_OK; }
BOOL MetaLauncher::createMenuItem(ULONG id, const char *path, size_t pathlen) { vnclog.Print(1, _T("%s: id=0x%X\n"), __FUNCTION__, id); wchar_t *p; // setup link path : m_baseMenuFolder + path (+ @desktopname) + ".lnk" size_t linkPathLen = wcslen(m_baseMenuFolder) + pathlen + wcslen(m_clientconn->m_desktopNameW) + 6; wchar_t *linkPath = new wchar_t[linkPathLen]; wcscpy(linkPath, m_baseMenuFolder); // append path with converting UTF-8 to UCS-2LE int pos = wcslen(linkPath); int wlen = MultiByteToWideChar(CP_UTF8, 0, path, (int)pathlen, &linkPath[pos], linkPathLen - pos); if (wlen <= 0) { vnclog.Print(0, _T("MultiByteToWideChar failed. (error %d)\n"), GetLastError()); delete[] linkPath; return FALSE; } linkPath[pos + wlen] = L'\0'; // convert '/' to '\\' while ((p = wcschr(linkPath, L'/')) != NULL) *p = L'\\'; // setup description text wchar_t *appName = wcsrchr(linkPath, '\\'); if (appName != NULL) appName++; // remove first '\\' else appName = linkPath; wchar_t *description = new wchar_t[wcslen(appName) + 1 + wcslen(m_clientconn->m_desktopNameW) + 1]; wcscpy(description, appName); wcscat(description, L"@"); wcscat(description, m_clientconn->m_desktopNameW); // add remote desktop name to linkpath if menu directory is not separated // XXX: maybe another option is needed if (m_clientconn->m_opts.m_menuLoc != MENULOC_SEPARATE) { wcscat(linkPath, L"@"); wcscat(linkPath, m_clientconn->m_desktopNameW); } wcscat(linkPath, L".lnk"); // add extension // check if linkPath already exists struct _stat st; if (_wstat(linkPath, &st) == 0) { vnclog.Print(0, _T("Failed to create identical link path (id=0x%X).\n"), id); delete[] description; delete[] linkPath; return FALSE; } // create sub directories createMenuDirs(linkPath); // remember link path if (m_fpMenuList) { fputws(linkPath, m_fpMenuList); fputws(L"\n", m_fpMenuList); } // setup target command arguments wchar_t targetArgs[30]; _snwprintf(targetArgs, 30, L"-launch %08X:%08X", m_clientconn->m_hwnd1, id); // setup icon path wchar_t *iconPath = createIconPath(id); // create shortcut HRESULT hr; IShellLinkW *pShellLink; IPersistFile *pPersistFile; CoInitialize(NULL); hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void**)&pShellLink); if (hr == S_OK) hr = pShellLink->SetPath(m_programName); if (hr == S_OK) hr = pShellLink->SetArguments(targetArgs); if (hr == S_OK) hr = pShellLink->SetIconLocation(iconPath, 0); if (hr == S_OK) hr = pShellLink->SetDescription(description); if (hr == S_OK) hr = pShellLink->QueryInterface(IID_IPersistFile, (void **)&pPersistFile); if (hr == S_OK) hr = pPersistFile->Save(linkPath, TRUE); // clean up pPersistFile->Release(); pShellLink->Release(); CoUninitialize(); delete[] iconPath; delete[] description; delete[] linkPath; return (hr == S_OK); }
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(); }