📄 shelllink.c
字号:
IShellLinkImpl *This = impl_from_IShellLinkW(iface);
TRACE("(%p)->(%p len=%u)\n", This, pszArgs, cchMaxPath);
if( cchMaxPath )
pszArgs[0] = 0;
if( This->sArgs )
lstrcpynW( pszArgs, This->sArgs, cchMaxPath );
return NOERROR;
}
static HRESULT WINAPI IShellLinkW_fnSetArguments(IShellLinkW * iface, LPCWSTR pszArgs)
{
IShellLinkImpl *This = impl_from_IShellLinkW(iface);
TRACE("(%p)->(args=%s)\n",This, debugstr_w(pszArgs));
HeapFree(GetProcessHeap(), 0, This->sArgs);
This->sArgs = HeapAlloc( GetProcessHeap(), 0,
(lstrlenW( pszArgs )+1)*sizeof (WCHAR) );
if ( !This->sArgs )
return E_OUTOFMEMORY;
lstrcpyW( This->sArgs, pszArgs );
This->bDirty = TRUE;
return S_OK;
}
static HRESULT WINAPI IShellLinkW_fnGetHotkey(IShellLinkW * iface, WORD *pwHotkey)
{
IShellLinkImpl *This = impl_from_IShellLinkW(iface);
TRACE("(%p)->(%p)\n",This, pwHotkey);
*pwHotkey=This->wHotKey;
return S_OK;
}
static HRESULT WINAPI IShellLinkW_fnSetHotkey(IShellLinkW * iface, WORD wHotkey)
{
IShellLinkImpl *This = impl_from_IShellLinkW(iface);
TRACE("(%p)->(hotkey=%x)\n",This, wHotkey);
This->wHotKey = wHotkey;
This->bDirty = TRUE;
return S_OK;
}
static HRESULT WINAPI IShellLinkW_fnGetShowCmd(IShellLinkW * iface, INT *piShowCmd)
{
IShellLinkImpl *This = impl_from_IShellLinkW(iface);
TRACE("(%p)->(%p)\n",This, piShowCmd);
*piShowCmd = This->iShowCmd;
return S_OK;
}
static HRESULT WINAPI IShellLinkW_fnSetShowCmd(IShellLinkW * iface, INT iShowCmd)
{
IShellLinkImpl *This = impl_from_IShellLinkW(iface);
This->iShowCmd = iShowCmd;
This->bDirty = TRUE;
return S_OK;
}
static HRESULT SHELL_PidlGeticonLocationW(IShellFolder* psf, LPITEMIDLIST pidl, LPWSTR pszIconPath, int cchIconPath, int* piIcon)
{
LPCITEMIDLIST pidlLast;
HRESULT hr = SHBindToParent(pidl, &IID_IShellFolder, (LPVOID*)&psf, &pidlLast);
if (SUCCEEDED(hr)) {
IExtractIconW* pei;
hr = IShellFolder_GetUIObjectOf(psf, 0, 1, (LPCITEMIDLIST*)&pidlLast, &IID_IExtractIconW, NULL, (LPVOID*)&pei);
if (SUCCEEDED(hr)) {
hr = IExtractIconW_GetIconLocation(pei, 0, pszIconPath, MAX_PATH, piIcon, NULL);
IExtractIconW_Release(pei);
}
IShellFolder_Release(psf);
}
return hr;
}
static HRESULT WINAPI IShellLinkW_fnGetIconLocation(IShellLinkW * iface, LPWSTR pszIconPath,INT cchIconPath,INT *piIcon)
{
IShellLinkImpl *This = impl_from_IShellLinkW(iface);
TRACE("(%p)->(%p len=%u iicon=%p)\n", This, pszIconPath, cchIconPath, piIcon);
pszIconPath[0] = 0;
*piIcon = This->iIcoNdx;
if (This->sIcoPath)
{
lstrcpynW(pszIconPath, This->sIcoPath, cchIconPath);
return S_OK;
}
if (This->pPidl || This->sPath)
{
IShellFolder* pdsk;
HRESULT hr = SHGetDesktopFolder(&pdsk);
if (SUCCEEDED(hr))
{
/* first look for an icon using the PIDL (if present) */
if (This->pPidl)
hr = SHELL_PidlGeticonLocationW(pdsk, This->pPidl, pszIconPath, cchIconPath, piIcon);
else
hr = E_FAIL;
/* if we couldn't find an icon yet, look for it using the file system path */
if (FAILED(hr) && This->sPath)
{
LPITEMIDLIST pidl;
hr = IShellFolder_ParseDisplayName(pdsk, 0, NULL, This->sPath, NULL, &pidl, NULL);
if (SUCCEEDED(hr))
{
hr = SHELL_PidlGeticonLocationW(pdsk, pidl, pszIconPath, cchIconPath, piIcon);
SHFree(pidl);
}
}
IShellFolder_Release(pdsk);
}
return hr;
}
return S_OK;
}
static HRESULT WINAPI IShellLinkW_fnSetIconLocation(IShellLinkW * iface, LPCWSTR pszIconPath,INT iIcon)
{
IShellLinkImpl *This = impl_from_IShellLinkW(iface);
TRACE("(%p)->(path=%s iicon=%u)\n",This, debugstr_w(pszIconPath), iIcon);
HeapFree(GetProcessHeap(), 0, This->sIcoPath);
This->sIcoPath = HeapAlloc( GetProcessHeap(), 0,
(lstrlenW( pszIconPath )+1)*sizeof (WCHAR) );
if ( !This->sIcoPath )
return E_OUTOFMEMORY;
lstrcpyW( This->sIcoPath, pszIconPath );
This->iIcoNdx = iIcon;
This->bDirty = TRUE;
return S_OK;
}
static HRESULT WINAPI IShellLinkW_fnSetRelativePath(IShellLinkW * iface, LPCWSTR pszPathRel, DWORD dwReserved)
{
IShellLinkImpl *This = impl_from_IShellLinkW(iface);
TRACE("(%p)->(path=%s %lx)\n",This, debugstr_w(pszPathRel), dwReserved);
HeapFree(GetProcessHeap(), 0, This->sPathRel);
This->sPathRel = HeapAlloc( GetProcessHeap(), 0,
(lstrlenW( pszPathRel )+1) * sizeof (WCHAR) );
if ( !This->sPathRel )
return E_OUTOFMEMORY;
lstrcpyW( This->sPathRel, pszPathRel );
This->bDirty = TRUE;
return ShellLink_UpdatePath(This->sPathRel, This->sPath, This->sWorkDir, &This->sPath);
}
static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWORD fFlags)
{
HRESULT hr = S_OK;
BOOL bSuccess;
IShellLinkImpl *This = impl_from_IShellLinkW(iface);
TRACE("(%p)->(hwnd=%p flags=%lx)\n",This, hwnd, fFlags);
/*FIXME: use IResolveShellLink interface */
if (!This->sPath && This->pPidl) {
WCHAR buffer[MAX_PATH];
bSuccess = SHGetPathFromIDListW(This->pPidl, buffer);
if (bSuccess && *buffer) {
This->sPath = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(buffer)+1)*sizeof(WCHAR));
if (!This->sPath)
return E_OUTOFMEMORY;
lstrcpyW(This->sPath, buffer);
This->bDirty = TRUE;
} else
hr = S_OK; /* don't report an error occurred while just caching information */
}
if (!This->sIcoPath && This->sPath) {
This->sIcoPath = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(This->sPath)+1)*sizeof(WCHAR));
if (!This->sIcoPath)
return E_OUTOFMEMORY;
lstrcpyW(This->sIcoPath, This->sPath);
This->iIcoNdx = 0;
This->bDirty = TRUE;
}
return hr;
}
static LPWSTR ShellLink_GetAdvertisedArg(LPCWSTR str)
{
LPWSTR ret;
LPCWSTR p;
DWORD len;
if( !str )
return NULL;
p = strchrW( str, ':' );
if( !p )
return NULL;
len = p - str;
ret = HeapAlloc( GetProcessHeap(), 0, sizeof(WCHAR)*(len+1));
if( !ret )
return ret;
memcpy( ret, str, sizeof(WCHAR)*len );
ret[len] = 0;
return ret;
}
static HRESULT ShellLink_SetAdvertiseInfo(IShellLinkImpl *This, LPCWSTR str)
{
LPCWSTR szComponent = NULL, szProduct = NULL, p;
WCHAR szGuid[39];
HRESULT r;
GUID guid;
int len;
while( str[0] )
{
/* each segment must start with two colons */
if( str[0] != ':' || str[1] != ':' )
return E_FAIL;
/* the last segment is just two colons */
if( !str[2] )
break;
str += 2;
/* there must be a colon straight after a guid */
p = strchrW( str, ':' );
if( !p )
return E_FAIL;
len = p - str;
if( len != 38 )
return E_FAIL;
/* get the guid, and check it's validly formatted */
memcpy( szGuid, str, sizeof(WCHAR)*len );
szGuid[len] = 0;
r = CLSIDFromString( szGuid, &guid );
if( r != S_OK )
return r;
str = p + 1;
/* match it up to a guid that we care about */
if( IsEqualGUID( &guid, &SHELL32_AdvtShortcutComponent ) && !szComponent )
szComponent = str;
else if( IsEqualGUID( &guid, &SHELL32_AdvtShortcutProduct ) && !szProduct )
szProduct = str;
else
return E_FAIL;
/* skip to the next field */
str = strchrW( str, ':' );
if( !str )
return E_FAIL;
}
/* we have to have a component for an advertised shortcut */
if( !szComponent )
return E_FAIL;
This->sComponent = ShellLink_GetAdvertisedArg( szComponent );
This->sProduct = ShellLink_GetAdvertisedArg( szProduct );
TRACE("Component = %s\n", debugstr_w(This->sComponent));
TRACE("Product = %s\n", debugstr_w(This->sProduct));
return S_OK;
}
static BOOL ShellLink_GetVolumeInfo(LPWSTR path, volume_info *volume)
{
const int label_sz = sizeof volume->label/sizeof volume->label[0];
WCHAR drive[4] = { path[0], ':', '\\', 0 };
BOOL r;
volume->type = GetDriveTypeW(drive);
r = GetVolumeInformationW(drive, volume->label, label_sz,
&volume->serial, NULL, NULL, NULL, 0);
TRACE("r = %d type %ld serial %08lx name %s\n", r,
volume->type, volume->serial, debugstr_w(volume->label));
return r;
}
static HRESULT WINAPI IShellLinkW_fnSetPath(IShellLinkW * iface, LPCWSTR pszFile)
{
IShellLinkImpl *This = impl_from_IShellLinkW(iface);
WCHAR buffer[MAX_PATH];
LPWSTR fname;
HRESULT hr = S_OK;
TRACE("(%p)->(path=%s)\n",This, debugstr_w(pszFile));
HeapFree(GetProcessHeap(), 0, This->sPath);
This->sPath = NULL;
HeapFree(GetProcessHeap(), 0, This->sComponent);
This->sComponent = NULL;
if (This->pPidl)
ILFree(This->pPidl);
This->pPidl = NULL;
if (S_OK != ShellLink_SetAdvertiseInfo( This, pszFile ))
{
if (*pszFile == '\0')
*buffer = '\0';
else if (!GetFullPathNameW(pszFile, MAX_PATH, buffer, &fname))
return E_FAIL;
else if(!PathFileExistsW(buffer))
hr = S_FALSE;
This->pPidl = SHSimpleIDListFromPathW(pszFile);
ShellLink_GetVolumeInfo(buffer, &This->volume);
This->sPath = HeapAlloc( GetProcessHeap(), 0,
(lstrlenW( buffer )+1) * sizeof (WCHAR) );
if (!This->sPath)
return E_OUTOFMEMORY;
lstrcpyW(This->sPath, buffer);
}
This->bDirty = TRUE;
return hr;
}
/**************************************************************************
* IShellLinkW Implementation
*/
static const IShellLinkWVtbl slvtw =
{
IShellLinkW_fnQueryInterface,
IShellLinkW_fnAddRef,
IShellLinkW_fnRelease,
IShellLinkW_fnGetPath,
IShellLinkW_fnGetIDList,
IShellLinkW_fnSetIDList,
IShellLinkW_fnGetDescription,
IShellLinkW_fnSetDescription,
IShellLinkW_fnGetWorkingDirectory,
IShellLinkW_fnSetWorkingDirectory,
IShellLinkW_fnGetArguments,
IShellLinkW_fnSetArguments,
IShellLinkW_fnGetHotkey,
IShellLinkW_fnSetHotkey,
IShellLinkW_fnGetShowCmd,
IShellLinkW_fnSetShowCmd,
IShellLinkW_fnGetIconLocation,
IShellLinkW_fnSetIconLocation,
IShellLinkW_fnSetRelativePath,
IShellLinkW_fnResolve,
IShellLinkW_fnSetPath
};
static HRESULT WINAPI
ShellLink_DataList_QueryInterface( IShellLinkDataList* iface, REFIID riid, void** ppvObject)
{
IShellLinkImpl *This = impl_from_IShellLinkDataList(iface);
return IShellLinkA_QueryInterface((IShellLinkA*)This, riid, ppvObject);
}
static ULONG WINAPI
ShellLink_DataList_AddRef( IShellLinkDataList* iface )
{
IShellLinkImpl *This = impl_from_IShellLinkDataList(iface);
return IShellLinkA_AddRef((IShellLinkA*)This);
}
static ULONG WINAPI
ShellLink_DataList_Release( IShellLinkDataList* iface )
{
IShellLinkImpl *This = impl_from_IShellLinkDataList(iface);
return ShellLink_Release( This );
}
static HRESULT WINAPI
ShellLink_AddDataBlock( IShellLinkDataList* iface, void* pDataBlock )
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT WINAPI
ShellLink_CopyDataBlock( IShellLinkDataList* iface, DWORD dwSig, void** ppDataBlock )
{
IShellLinkImpl *This = impl_from_IShellLinkDataList(iface);
LPVOID block = NULL;
HRESULT r = E_FAIL;
TRACE("%p %08lx %p\n", iface, dwSig, ppDataBlock );
switch (dwSig)
{
case EXP_DARWIN_ID_SIG:
if (!This->sComponent)
break;
block = shelllink_build_darwinid( This->sComponent, dwSig );
r = S_OK;
break;
case EXP_SZ_LINK_SIG:
case NT_CONSOLE_PROPS_SIG:
case NT_FE_CONSOLE_PROPS_SIG:
case EXP_SPECIAL_FOLDER_SIG:
case EXP_SZ_ICON_SIG:
FIXME("valid but unhandled datablock %08lx\n", dwSig);
break;
default:
ERR("unknown datablock %08lx\n", dwSig);
}
*ppDataBlock = block;
return r;
}
static HRESULT WINAPI
ShellLink_RemoveDataBlock( IShellLinkDataList* iface, DWORD dwSig )
{
FIXME("\n");
return E_NO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -