⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shelllink.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -