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; }
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; }
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; }
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(); }
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; }