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

📄 shlfolder.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *	Shell Folder stuff
 *
 *	Copyright 1997			Marcus Meissner
 *	Copyright 1998, 1999, 2002	Juergen Schmied
 *
 *	IShellFolder2 and related interfaces
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>

#define COBJMACROS

#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "wingdi.h"
#include "winuser.h"

#include "ole2.h"
#include "shlguid.h"

#include "pidl.h"
#include "undocshell.h"
#include "shell32_main.h"
#include "shlwapi.h"
#include "wine/debug.h"
#include "shfldr.h"

WINE_DEFAULT_DEBUG_CHANNEL (shell);

static const WCHAR wszDotShellClassInfo[] = {
    '.','S','h','e','l','l','C','l','a','s','s','I','n','f','o',0};

/***************************************************************************
 *  SHELL32_GetCustomFolderAttribute (internal function)
 *
 * Gets a value from the folder's desktop.ini file, if one exists.
 *
 * PARAMETERS
 *  pidl          [I] Folder containing the desktop.ini file.
 *  pwszHeading   [I] Heading in .ini file.
 *  pwszAttribute [I] Attribute in .ini file.
 *  pwszValue     [O] Buffer to store value into.
 *  cchValue      [I] Size in characters including NULL of buffer pointed to
 *                    by pwszValue.
 *
 *  RETURNS
 *    TRUE if returned non-NULL value.
 *    FALSE otherwise.
 */
static inline BOOL SHELL32_GetCustomFolderAttributeFromPath(
    LPWSTR pwszFolderPath, LPCWSTR pwszHeading, LPCWSTR pwszAttribute,
    LPWSTR pwszValue, DWORD cchValue)
{
    static const WCHAR wszDesktopIni[] =
            {'d','e','s','k','t','o','p','.','i','n','i',0};
    static const WCHAR wszDefault[] = {0};

    PathAddBackslashW(pwszFolderPath);
    PathAppendW(pwszFolderPath, wszDesktopIni);
    return GetPrivateProfileStringW(pwszHeading, pwszAttribute, wszDefault, 
                                    pwszValue, cchValue, pwszFolderPath);
}

BOOL SHELL32_GetCustomFolderAttribute(
    LPCITEMIDLIST pidl, LPCWSTR pwszHeading, LPCWSTR pwszAttribute,
    LPWSTR pwszValue, DWORD cchValue)
{
    DWORD dwAttrib = FILE_ATTRIBUTE_SYSTEM;
    WCHAR wszFolderPath[MAX_PATH];

    /* Hack around not having system attribute on non-Windows file systems */
    if (0)
        dwAttrib = _ILGetFileAttributes(pidl, NULL, 0);

    if (dwAttrib & FILE_ATTRIBUTE_SYSTEM)
    {
        if (!SHGetPathFromIDListW(pidl, wszFolderPath))
            return FALSE;

        return SHELL32_GetCustomFolderAttributeFromPath(wszFolderPath, pwszHeading, 
                                                pwszAttribute, pwszValue, cchValue);
    }
    return FALSE;
}

/***************************************************************************
 *  GetNextElement (internal function)
 *
 * gets a part of a string till the first backslash
 *
 * PARAMETERS
 *  pszNext [IN] string to get the element from
 *  pszOut  [IN] pointer to buffer whitch receives string
 *  dwOut   [IN] length of pszOut
 *
 *  RETURNS
 *    LPSTR pointer to first, not yet parsed char
 */

LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut)
{
    LPCWSTR pszTail = pszNext;
    DWORD dwCopy;

    TRACE ("(%s %p 0x%08lx)\n", debugstr_w (pszNext), pszOut, dwOut);

    *pszOut = 0x0000;

    if (!pszNext || !*pszNext)
	return NULL;

    while (*pszTail && (*pszTail != (WCHAR) '\\'))
	pszTail++;

    dwCopy = (const WCHAR *) pszTail - (const WCHAR *) pszNext + 1;
    lstrcpynW (pszOut, pszNext, (dwOut < dwCopy) ? dwOut : dwCopy);

    if (*pszTail)
	pszTail++;
    else
	pszTail = NULL;

    TRACE ("--(%s %s 0x%08lx %p)\n", debugstr_w (pszNext), debugstr_w (pszOut), dwOut, pszTail);
    return pszTail;
}

HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc,
				  LPITEMIDLIST * pidlInOut, LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes)
{
    HRESULT hr = E_INVALIDARG;
    LPITEMIDLIST pidlOut = NULL,
      pidlTemp = NULL;
    IShellFolder *psfChild;

    TRACE ("(%p, %p, %p, %s)\n", psf, pbc, pidlInOut ? *pidlInOut : NULL, debugstr_w (szNext));

    /* get the shellfolder for the child pidl and let it analyse further */
    hr = IShellFolder_BindToObject (psf, *pidlInOut, pbc, &IID_IShellFolder, (LPVOID *) & psfChild);

    if (SUCCEEDED(hr)) {
	hr = IShellFolder_ParseDisplayName (psfChild, hwndOwner, pbc, szNext, pEaten, &pidlOut, pdwAttributes);
	IShellFolder_Release (psfChild);

	if (SUCCEEDED(hr)) {
	    pidlTemp = ILCombine (*pidlInOut, pidlOut);

	    if (!pidlTemp)
		hr = E_OUTOFMEMORY;
	}

	if (pidlOut)
	    ILFree (pidlOut);
    }

    ILFree (*pidlInOut);
    *pidlInOut = pidlTemp;

    TRACE ("-- pidl=%p ret=0x%08lx\n", pidlInOut ? *pidlInOut : NULL, hr);
    return hr;
}

/***********************************************************************
 *	SHELL32_CoCreateInitSF
 *
 * Creates a shell folder and initializes it with a pidl and a root folder
 * via IPersistFolder3 or IPersistFolder.
 *
 * NOTES
 *   pathRoot can be NULL for Folders beeing a drive.
 *   In this case the absolute path is build from pidlChild (eg. C:)
 */
static HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
    LPCITEMIDLIST pidlChild, REFCLSID clsid, REFIID riid, LPVOID * ppvOut)
{
    HRESULT hr;

    TRACE ("%p %s %p\n", pidlRoot, debugstr_w(pathRoot), pidlChild);

    if (SUCCEEDED ((hr = SHCoCreateInstance (NULL, clsid, NULL, riid, ppvOut)))) {
	LPITEMIDLIST pidlAbsolute = ILCombine (pidlRoot, pidlChild);
	IPersistFolder *pPF;
	IPersistFolder3 *ppf;

        if (_ILIsFolder(pidlChild) &&
            SUCCEEDED (IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder3, (LPVOID *) & ppf))) 
        {
	    PERSIST_FOLDER_TARGET_INFO ppfti;

	    ZeroMemory (&ppfti, sizeof (ppfti));

	    /* fill the PERSIST_FOLDER_TARGET_INFO */
	    ppfti.dwAttributes = -1;
	    ppfti.csidl = -1;

	    /* build path */
	    if (pathRoot) {
		lstrcpynW (ppfti.szTargetParsingName, pathRoot, MAX_PATH - 1);
		PathAddBackslashW(ppfti.szTargetParsingName); /* FIXME: why have drives a backslash here ? */
	    }

	    if (pidlChild) {
		LPCSTR pszChild = _ILGetTextPointer(pidlChild);
                int len = lstrlenW(ppfti.szTargetParsingName);

		if (pszChild)
		    MultiByteToWideChar (CP_ACP, 0, pszChild, -1, ppfti.szTargetParsingName + len, MAX_PATH - len);
		else
		    hr = E_INVALIDARG;
	    }

	    IPersistFolder3_InitializeEx (ppf, NULL, pidlAbsolute, &ppfti);
	    IPersistFolder3_Release (ppf);
	}
	else if (SUCCEEDED ((hr = IUnknown_QueryInterface ((IUnknown *) * ppvOut, &IID_IPersistFolder, (LPVOID *) & pPF)))) {
	    IPersistFolder_Initialize (pPF, pidlAbsolute);
	    IPersistFolder_Release (pPF);
	}
	ILFree (pidlAbsolute);
    }
    TRACE ("-- (%p) ret=0x%08lx\n", *ppvOut, hr);
    return hr;
}

/***********************************************************************
 *	SHELL32_BindToChild [Internal]
 *
 * Common code for IShellFolder_BindToObject.
 * 
 * PARAMS
 *  pidlRoot     [I] The parent shell folder's absolute pidl.
 *  pathRoot     [I] Absolute dos path of the parent shell folder.
 *  pidlComplete [I] PIDL of the child. Relative to pidlRoot.
 *  riid         [I] GUID of the interface, which ppvOut shall be bound to.
 *  ppvOut       [O] A reference to the child's interface (riid).
 *
 * NOTES
 *  pidlComplete has to contain at least one non empty SHITEMID.
 *  This function makes special assumptions on the shell namespace, which
 *  means you probably can't use it for your IShellFolder implementation.
 */
HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
                             LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut)
{
    GUID const *clsid;
    IShellFolder *pSF;
    HRESULT hr;
    LPITEMIDLIST pidlChild;

    if (!pidlRoot || !ppvOut || !pidlComplete || !pidlComplete->mkid.cb)
        return E_INVALIDARG;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -