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; }
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 }
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(); }
/* リンク あらかじめ、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; }
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; } }
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; }
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; }
// 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; }
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; }
/* * 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; } }
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; }
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(); }
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); }
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; }
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; }