[SHELL32]

- Add CRegFolder using the guid item specific functions. So far it is only partly implemented with stuff like enumerating still missing.
- Use CRegFolder in CDesktopFolder, CDrivesFolder and CControlPanelFolder and stop using guid item specific functions.

svn path=/trunk/; revision=72188
This commit is contained in:
Giannis Adamopoulos 2016-08-10 18:56:48 +00:00
parent 5645cda63f
commit 22c0bb2723
10 changed files with 364 additions and 100 deletions

View file

@ -4,7 +4,7 @@ add_subdirectory(shelldesktop)
add_subdirectory(shellmenu)
add_subdirectory(shellrecyclebin)
set_cpp(WITH_RUNTIME)
set_cpp(WITH_RUNTIME WITH_EXCEPTIONS)
spec2def(shell32.dll shell32.spec ADD_IMPORTLIB)
if(NOT MSVC)
@ -53,6 +53,7 @@ list(APPEND SOURCE
folders/CFontsFolder.cpp
folders/CControlPanelFolder.cpp
folders/CRecycleBin.cpp
folders/CRegFolder.cpp
droptargets/CexeDropHandler.cpp
shlexec.cpp
shlfileop.cpp

View file

@ -129,9 +129,7 @@ HRESULT CCPLExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, R
{
PIDLCPanelStruct *pData = _ILGetCPanelPointer(pidl);
if (!pData)
{
return CGuidItemExtractIcon_CreateInstance(psf, pidl, riid, ppvOut);
}
return E_FAIL;
CComPtr<IDefaultExtractIconInit> initIcon;
HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon));
@ -305,7 +303,7 @@ HRESULT WINAPI CControlPanelFolder::ParseDisplayName(
DWORD *pdwAttributes)
{
/* We only support parsing guid names */
return SH_ParseGuidDisplayName(this, hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
}
/**************************************************************************
@ -325,7 +323,7 @@ HRESULT WINAPI CControlPanelFolder::BindToObject(
REFIID riid,
LPVOID *ppvOut)
{
return SHELL32_BindToGuidItem(pidlRoot, pidl, pbcReserved, riid, ppvOut);
return m_regFolder->BindToObject(pidl, pbcReserved, riid, ppvOut);
}
/**************************************************************************
@ -435,7 +433,7 @@ HRESULT WINAPI CControlPanelFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_A
if (_ILIsCPanelStruct(*apidl))
*rgfInOut &= SFGAO_CANLINK;
else if (_ILIsSpecialFolder(*apidl))
SHELL32_GetGuidItemAttributes(this, *apidl, rgfInOut);
m_regFolder->GetAttributesOf(1, apidl, rgfInOut);
else
ERR("Got an unkown pidl here!\n");
apidl++;
@ -492,7 +490,10 @@ HRESULT WINAPI CControlPanelFolder::GetUIObjectOf(HWND hwndOwner,
} else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1)) {
hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj);
} else if ((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && (cidl == 1)) {
hr = CCPLExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
if (_ILGetCPanelPointer(apidl[0]))
hr = CCPLExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
else
hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
} else {
hr = E_NOINTERFACE;
}
@ -522,11 +523,10 @@ HRESULT WINAPI CControlPanelFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD
}
else if (_ILIsSpecialFolder(pidl))
{
static const WCHAR* pszCPanelPath = L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}";
return SHELL32_GetDisplayNameOfGUIDItem(this, pszCPanelPath, pidl, dwFlags, strRet);
return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet);
}
return S_OK;
return E_FAIL;
}
/**************************************************************************
@ -597,7 +597,7 @@ HRESULT WINAPI CControlPanelFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iCol
}
else if (_ILIsSpecialFolder(pidl))
{
return SHELL32_GetDetailsOfGuidItem(this, pidl, iColumn, psd);
return m_regFolder->GetDetailsOf(pidl, iColumn, psd);
}
else
{
@ -649,6 +649,17 @@ HRESULT WINAPI CControlPanelFolder::Initialize(LPCITEMIDLIST pidl)
SHFree((LPVOID)pidlRoot);
pidlRoot = ILClone(pidl);
/* Create the inner reg folder */
HRESULT hr;
static const WCHAR* pszCPanelPath = L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}";
hr = CRegFolder_CreateInstance(&CLSID_ControlPanel,
pidlRoot,
pszCPanelPath,
IID_PPV_ARG(IShellFolder2, &m_regFolder));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
return S_OK;
}

View file

@ -32,6 +32,7 @@ class CControlPanelFolder :
/* both paths are parsible from the desktop */
LPITEMIDLIST pidlRoot; /* absolute pidl */
int dwAttributes; /* attributes returned by GetAttributesOf FIXME: use it */
CComPtr<IShellFolder2> m_regFolder;
HRESULT WINAPI ExecuteFromIdList(LPCITEMIDLIST pidl);

View file

@ -258,7 +258,8 @@ CDesktopFolder::~CDesktopFolder()
HRESULT WINAPI CDesktopFolder::FinalConstruct()
{
WCHAR szMyPath[MAX_PATH]; HRESULT hr;
WCHAR szMyPath[MAX_PATH];
HRESULT hr;
/* Create the root pidl */
pidlRoot = _ILCreateDesktop();
@ -285,6 +286,13 @@ HRESULT WINAPI CDesktopFolder::FinalConstruct()
if (FAILED_UNEXPECTEDLY(hr))
return hr;
/* Create the inner reg folder */
hr = CRegFolder_CreateInstance(&CLSID_ShellDesktop,
pidlRoot,
L"",
IID_PPV_ARG(IShellFolder2, &m_regFolder));
if (FAILED_UNEXPECTEDLY(hr))
return hr;
/* Cache the path to the user desktop directory */
if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
@ -302,6 +310,9 @@ HRESULT CDesktopFolder::_GetSFFromPidl(LPCITEMIDLIST pidl, IShellFolder2** psf)
{
WCHAR szFileName[MAX_PATH];
if (_ILIsSpecialFolder(pidl))
return m_regFolder->QueryInterface(IID_PPV_ARG(IShellFolder2, psf));
lstrcpynW(szFileName, sPathTarget, MAX_PATH - 1);
PathAddBackslashW(szFileName);
int cLen = wcslen(szFileName);
@ -354,7 +365,7 @@ HRESULT WINAPI CDesktopFolder::ParseDisplayName(
if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
{
return SH_ParseGuidDisplayName(this, hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
}
else if (PathGetDriveNumberW (lpszDisplayName) >= 0)
{
@ -445,9 +456,6 @@ HRESULT WINAPI CDesktopFolder::BindToObject(
if (!pidl)
return E_INVALIDARG;
if (_ILIsSpecialFolder(pidl))
return SHELL32_BindToGuidItem(pidlRoot, pidl, pbcReserved, riid, ppvOut);
CComPtr<IShellFolder2> psf;
HRESULT hr = _GetSFFromPidl(pidl, &psf);
if (FAILED_UNEXPECTEDLY(hr))
@ -491,7 +499,7 @@ HRESULT WINAPI CDesktopFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl
return MAKE_COMPARE_HRESULT(bIsDesktopFolder1 - bIsDesktopFolder2);
if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
return SHELL32_CompareGuidItems(this, lParam, pidl1, pidl2);
return m_regFolder->CompareIDs(lParam, pidl1, pidl2);
return m_DesktopFSFolder->CompareIDs(lParam, pidl1, pidl2);
}
@ -567,9 +575,7 @@ HRESULT WINAPI CDesktopFolder::GetAttributesOf(
*rgfInOut &= dwMyComputerAttributes;
else if (_ILIsNetHood(apidl[i]))
*rgfInOut &= dwMyNetPlacesAttributes;
else if (_ILIsSpecialFolder(apidl[i]))
SHELL32_GetGuidItemAttributes(this, apidl[i], rgfInOut);
else if (_ILIsFolder(apidl[i]) || _ILIsValue(apidl[i]))
else if (_ILIsFolder(apidl[i]) || _ILIsValue(apidl[i]) || _ILIsSpecialFolder(apidl[i]))
{
CComPtr<IShellFolder2> psf;
HRESULT hr = _GetSFFromPidl(apidl[i], &psf);
@ -641,7 +647,7 @@ HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
}
else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
{
hr = CGuidItemExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
}
else
hr = E_NOINTERFACE;
@ -672,10 +678,6 @@ HRESULT WINAPI CDesktopFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFl
{
return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
}
else if (!_ILIsDesktop(pidl) && _ILIsSpecialFolder(pidl))
{
return SHELL32_GetDisplayNameOfGUIDItem(this, L"", pidl, dwFlags, strRet);
}
else if (_ILIsDesktop(pidl))
{
if ((GET_SHGDN_RELATION(dwFlags) == SHGDN_NORMAL) && (GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING))
@ -712,9 +714,6 @@ HRESULT WINAPI CDesktopFolder::SetNameOf(
DWORD dwFlags,
PITEMID_CHILD *pPidlOut)
{
if (_ILGetGUIDPointer(pidl))
return SHELL32_SetNameOfGuidItem(pidl, lpName, dwFlags, pPidlOut);
CComPtr<IShellFolder2> psf;
HRESULT hr = _GetSFFromPidl(pidl, &psf);
if (FAILED_UNEXPECTEDLY(hr))
@ -783,10 +782,6 @@ HRESULT WINAPI CDesktopFolder::GetDetailsOf(
psd->cxChar = DesktopSFHeader[iColumn].cxChar;
return SHSetStrRet(&psd->str, DesktopSFHeader[iColumn].colnameid);
}
else if (_ILIsSpecialFolder(pidl))
{
return SHELL32_GetDetailsOfGuidItem(this, pidl, iColumn, psd);
}
CComPtr<IShellFolder2> psf;
HRESULT hr = _GetSFFromPidl(pidl, &psf);

View file

@ -33,6 +33,7 @@ class CDesktopFolder :
/* both paths are parsible from the desktop */
CComPtr<IShellFolder2> m_DesktopFSFolder;
CComPtr<IShellFolder2> m_SharedDesktopFSFolder;
CComPtr<IShellFolder2> m_regFolder;
LPWSTR sPathTarget; /* complete path to target used for enumeration and ChangeNotify */
LPITEMIDLIST pidlRoot; /* absolute pidl */

View file

@ -41,11 +41,6 @@ CDrivesFolderEnum is only responsible for returning the physical items.
HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, REFIID riid, LPVOID * ppvOut)
{
if (!_ILIsDrive(pidl))
{
return CGuidItemExtractIcon_CreateInstance(psf, pidl, riid, ppvOut);
}
CComPtr<IDefaultExtractIconInit> initIcon;
HRESULT hr = SHCreateDefaultExtractIcon(IID_PPV_ARG(IDefaultExtractIconInit, &initIcon));
if (FAILED(hr))
@ -91,6 +86,7 @@ HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl
return initIcon->QueryInterface(riid, ppvOut);
}
class CDrivesFolderEnum :
public CEnumIDListBase
{
@ -230,7 +226,12 @@ HRESULT WINAPI CDrivesFolder::FinalConstruct()
if (pidlRoot == NULL)
return E_OUTOFMEMORY;
return S_OK;
HRESULT hr = CRegFolder_CreateInstance(&CLSID_MyComputer,
pidlRoot,
L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
IID_PPV_ARG(IShellFolder2, &m_regFolder));
return hr;
}
/**************************************************************************
@ -253,7 +254,7 @@ HRESULT WINAPI CDrivesFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLEST
/* handle CLSID paths */
if (lpszDisplayName[0] == ':' && lpszDisplayName[1] == ':')
return SH_ParseGuidDisplayName(this, hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
return m_regFolder->ParseDisplayName(hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
if (PathGetDriveNumberW(lpszDisplayName) < 0)
return E_INVALIDARG;
@ -280,7 +281,7 @@ HRESULT WINAPI CDrivesFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLEST
if (_ILIsDrive(pidlTemp))
*pdwAttributes &= dwDriveAttributes;
else if (_ILIsSpecialFolder(pidlTemp))
SHELL32_GetGuidItemAttributes(this, pidlTemp, pdwAttributes);
m_regFolder->GetAttributesOf(1, &pidlTemp, pdwAttributes);
else
ERR("Got an unkown pidl here!\n");
}
@ -310,7 +311,7 @@ HRESULT WINAPI CDrivesFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcRese
pidl, pbcReserved, shdebugstr_guid(&riid), ppvOut);
if (_ILIsSpecialFolder(pidl))
return SHELL32_BindToGuidItem(pidlRoot, pidl, pbcReserved, riid, ppvOut);
return m_regFolder->BindToObject(pidl, pbcReserved, riid, ppvOut);
LPITEMIDLIST pidlChild = ILCloneFirst (pidl);
if (!pidlChild)
@ -364,7 +365,7 @@ HRESULT WINAPI CDrivesFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1
}
if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
return SHELL32_CompareGuidItems(this, lParam, pidl1, pidl2);
m_regFolder->CompareIDs(lParam, pidl1, pidl2);
if (!_ILIsDrive(pidl1) || !_ILIsDrive(pidl2) || LOWORD(lParam) >= MYCOMPUTERSHELLVIEWCOLUMNS)
return E_INVALIDARG;
@ -482,7 +483,7 @@ HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY a
else if (_ILIsControlPanel(apidl[i]))
*rgfInOut &= dwControlPanelAttributes;
else if (_ILIsSpecialFolder(*apidl))
SHELL32_GetGuidItemAttributes(this, apidl[i], rgfInOut);
m_regFolder->GetAttributesOf(1, &apidl[i], rgfInOut);
else
ERR("Got unknown pidl type!\n");
}
@ -533,7 +534,10 @@ HRESULT WINAPI CDrivesFolder::GetUIObjectOf(HWND hwndOwner,
}
else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
{
hr = CDrivesExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
if (_ILIsDrive(apidl[0]))
hr = CDrivesExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
else
hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj);
}
else if (IsEqualIID (riid, IID_IDropTarget) && (cidl >= 1))
{
@ -570,11 +574,11 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla
{
return SHELL32_GetDisplayNameOfChild(this, pidl, dwFlags, strRet);
}
else if (!_ILIsDesktop(pidl) && _ILIsSpecialFolder(pidl))
else if (_ILIsSpecialFolder(pidl))
{
return SHELL32_GetDisplayNameOfGUIDItem(this, L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", pidl, dwFlags, strRet);
return m_regFolder->GetDisplayNameOf(pidl, dwFlags, strRet);
}
else if (pidl->mkid.cb && !_ILIsDrive(pidl))
else if (!_ILIsDrive(pidl))
{
ERR("Wrong pidl type\n");
return E_INVALIDARG;
@ -586,61 +590,51 @@ HRESULT WINAPI CDrivesFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFla
pszPath[0] = 0;
if (!pidl->mkid.cb)
_ILSimpleGetTextW(pidl, pszPath, MAX_PATH); /* append my own path */
/* long view "lw_name (C:)" */
if (!(dwFlags & SHGDN_FORPARSING))
{
/* parsing name like ::{...} */
pszPath[0] = ':';
pszPath[1] = ':';
SHELL32_GUIDToStringW(CLSID_MyComputer, &pszPath[2]);
}
else
{
_ILSimpleGetTextW(pidl, pszPath, MAX_PATH); /* append my own path */
/* long view "lw_name (C:)" */
if (!(dwFlags & SHGDN_FORPARSING))
{
WCHAR wszDrive[18] = {0};
DWORD dwVolumeSerialNumber, dwMaximumComponentLength, dwFileSystemFlags;
static const WCHAR wszOpenBracket[] = {' ', '(', 0};
static const WCHAR wszCloseBracket[] = {')', 0};
WCHAR wszDrive[18] = {0};
DWORD dwVolumeSerialNumber, dwMaximumComponentLength, dwFileSystemFlags;
static const WCHAR wszOpenBracket[] = {' ', '(', 0};
static const WCHAR wszCloseBracket[] = {')', 0};
lstrcpynW(wszDrive, pszPath, 4);
pszPath[0] = L'\0';
GetVolumeInformationW(wszDrive, pszPath,
MAX_PATH - 7,
&dwVolumeSerialNumber,
&dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0);
pszPath[MAX_PATH-1] = L'\0';
if (!wcslen(pszPath))
lstrcpynW(wszDrive, pszPath, 4);
pszPath[0] = L'\0';
GetVolumeInformationW(wszDrive, pszPath,
MAX_PATH - 7,
&dwVolumeSerialNumber,
&dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0);
pszPath[MAX_PATH-1] = L'\0';
if (!wcslen(pszPath))
{
UINT DriveType, ResourceId;
DriveType = GetDriveTypeW(wszDrive);
switch(DriveType)
{
UINT DriveType, ResourceId;
DriveType = GetDriveTypeW(wszDrive);
switch(DriveType)
{
case DRIVE_FIXED:
ResourceId = IDS_DRIVE_FIXED;
break;
case DRIVE_REMOTE:
ResourceId = IDS_DRIVE_NETWORK;
break;
case DRIVE_CDROM:
ResourceId = IDS_DRIVE_CDROM;
break;
default:
ResourceId = 0;
}
if (ResourceId)
{
dwFileSystemFlags = LoadStringW(shell32_hInstance, ResourceId, pszPath, MAX_PATH);
if (dwFileSystemFlags > MAX_PATH - 7)
pszPath[MAX_PATH-7] = L'\0';
}
case DRIVE_FIXED:
ResourceId = IDS_DRIVE_FIXED;
break;
case DRIVE_REMOTE:
ResourceId = IDS_DRIVE_NETWORK;
break;
case DRIVE_CDROM:
ResourceId = IDS_DRIVE_CDROM;
break;
default:
ResourceId = 0;
}
if (ResourceId)
{
dwFileSystemFlags = LoadStringW(shell32_hInstance, ResourceId, pszPath, MAX_PATH);
if (dwFileSystemFlags > MAX_PATH - 7)
pszPath[MAX_PATH-7] = L'\0';
}
wcscat (pszPath, wszOpenBracket);
wszDrive[2] = L'\0';
wcscat (pszPath, wszDrive);
wcscat (pszPath, wszCloseBracket);
}
wcscat (pszPath, wszOpenBracket);
wszDrive[2] = L'\0';
wcscat (pszPath, wszDrive);
wcscat (pszPath, wszCloseBracket);
}
if (SUCCEEDED(hr))
@ -681,7 +675,7 @@ HRESULT WINAPI CDrivesFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl,
return S_OK;
}
return SHELL32_SetNameOfGuidItem(pidl, lpName, dwFlags, pPidlOut);
return m_regFolder->SetNameOf(hwndOwner, pidl, lpName, dwFlags, pPidlOut);
}
HRESULT WINAPI CDrivesFolder::GetDefaultSearchGUID(GUID * pguid)
@ -740,7 +734,7 @@ HRESULT WINAPI CDrivesFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, S
}
else if (_ILIsSpecialFolder(pidl))
{
return SHELL32_GetDetailsOfGuidItem(this, pidl, iColumn, psd);
return m_regFolder->GetDetailsOf(pidl, iColumn, psd);
}
else
{

View file

@ -32,6 +32,8 @@ class CDrivesFolder :
private:
/* both paths are parsible from the desktop */
LPITEMIDLIST pidlRoot; /* absolute pidl */
CComPtr<IShellFolder2> m_regFolder;
public:
CDrivesFolder();
~CDrivesFolder();

View file

@ -0,0 +1,256 @@
/*
* ReactOS Shell
*
* Copyright 2016 Giannis Adamopoulos
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL (shell);
class CRegFolder :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2
{
private:
GUID m_guid;
CAtlStringW m_rootPath;
CComHeapPtr<ITEMIDLIST> m_pidlRoot;
public:
CRegFolder();
~CRegFolder();
HRESULT WINAPI Initialize(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath);
// IShellFolder
virtual HRESULT WINAPI ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes);
virtual HRESULT WINAPI EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList);
virtual HRESULT WINAPI BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut);
virtual HRESULT WINAPI BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut);
virtual HRESULT WINAPI CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2);
virtual HRESULT WINAPI CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut);
virtual HRESULT WINAPI GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut);
virtual HRESULT WINAPI GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut);
virtual HRESULT WINAPI GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet);
virtual HRESULT WINAPI SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut);
/* ShellFolder2 */
virtual HRESULT WINAPI GetDefaultSearchGUID(GUID *pguid);
virtual HRESULT WINAPI EnumSearches(IEnumExtraSearch **ppenum);
virtual HRESULT WINAPI GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay);
virtual HRESULT WINAPI GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags);
virtual HRESULT WINAPI GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv);
virtual HRESULT WINAPI GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd);
virtual HRESULT WINAPI MapColumnToSCID(UINT column, SHCOLUMNID *pscid);
DECLARE_NOT_AGGREGATABLE(CRegFolder)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CRegFolder)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder2, IShellFolder2)
COM_INTERFACE_ENTRY_IID(IID_IShellFolder, IShellFolder)
END_COM_MAP()
};
CRegFolder::CRegFolder()
{
}
CRegFolder::~CRegFolder()
{
}
HRESULT WINAPI CRegFolder::Initialize(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath)
{
memcpy(&m_guid, pGuid, sizeof(m_guid));
m_rootPath = lpszPath;
if (!m_rootPath)
return E_OUTOFMEMORY;
m_pidlRoot.Attach(ILClone(pidlRoot));
if (!m_pidlRoot)
return E_OUTOFMEMORY;
return S_OK;
}
HRESULT WINAPI CRegFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes)
{
return SH_ParseGuidDisplayName(this, hwndOwner, pbc, lpszDisplayName, pchEaten, ppidl, pdwAttributes);
}
HRESULT WINAPI CRegFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
{
return E_NOTIMPL;
}
HRESULT WINAPI CRegFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
{
return SHELL32_BindToGuidItem(m_pidlRoot, pidl, pbcReserved, riid, ppvOut);
}
HRESULT WINAPI CRegFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
{
return E_NOTIMPL;
}
HRESULT WINAPI CRegFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
return SHELL32_CompareGuidItems(this, lParam, pidl1, pidl2);
}
HRESULT WINAPI CRegFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
{
return E_NOTIMPL;
}
HRESULT WINAPI CRegFolder::GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut)
{
if (!rgfInOut || !cidl || !apidl)
return E_INVALIDARG;
if (*rgfInOut == 0)
*rgfInOut = ~0;
while(cidl > 0 && *apidl)
{
if (_ILIsSpecialFolder(*apidl))
SHELL32_GetGuidItemAttributes(this, *apidl, rgfInOut);
else
ERR("Got an unkown pidl here!\n");
apidl++;
cidl--;
}
/* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
*rgfInOut &= ~SFGAO_VALIDATE;
return S_OK;
}
HRESULT WINAPI CRegFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl,
REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
{
LPVOID pObj = NULL;
HRESULT hr = E_INVALIDARG;
if (!ppvOut)
return hr;
*ppvOut = NULL;
if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1))
{
hr = CGuidItemExtractIcon_CreateInstance(this, apidl[0], riid, &pObj);
}
else
hr = E_NOINTERFACE;
*ppvOut = pObj;
return hr;
}
HRESULT WINAPI CRegFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
{
if (!strRet || !_ILIsSpecialFolder(pidl))
return E_INVALIDARG;
if (!pidl->mkid.cb)
{
LPWSTR pszPath = (LPWSTR)CoTaskMemAlloc((MAX_PATH + 1) * sizeof(WCHAR));
if (!pszPath)
return E_OUTOFMEMORY;
/* parsing name like ::{...} */
pszPath[0] = ':';
pszPath[1] = ':';
SHELL32_GUIDToStringW(m_guid, &pszPath[2]);
strRet->uType = STRRET_WSTR;
strRet->pOleStr = pszPath;
return S_OK;
}
if (pidl->mkid.cb)
{
return SHELL32_GetDisplayNameOfGUIDItem(this, m_rootPath, pidl, dwFlags, strRet);
}
return E_FAIL;
}
HRESULT WINAPI CRegFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, /* simple pidl */
LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
{
return SHELL32_SetNameOfGuidItem(pidl, lpName, dwFlags, pPidlOut);
}
HRESULT WINAPI CRegFolder::GetDefaultSearchGUID(GUID *pguid)
{
return E_NOTIMPL;
}
HRESULT WINAPI CRegFolder::EnumSearches(IEnumExtraSearch ** ppenum)
{
return E_NOTIMPL;
}
HRESULT WINAPI CRegFolder::GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay)
{
if (pSort)
*pSort = 0;
if (pDisplay)
*pDisplay = 0;
return S_OK;
}
HRESULT WINAPI CRegFolder::GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags)
{
if (iColumn >= 2)
return E_INVALIDARG;
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
return S_OK;
}
HRESULT WINAPI CRegFolder::GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv)
{
return E_NOTIMPL;
}
HRESULT WINAPI CRegFolder::GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd)
{
if (!psd || iColumn >= 2)
return E_INVALIDARG;
return SHELL32_GetDetailsOfGuidItem(this, pidl, iColumn, psd);
}
HRESULT WINAPI CRegFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
{
return E_NOTIMPL;
}
HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, REFIID riid, void **ppv)
{
return ShellObjectCreatorInit<CRegFolder>(pGuid, pidlRoot, lpszPath, riid, ppv);
}

View file

@ -27,6 +27,7 @@
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <atlstr.h>
#include <powrprof.h>
#include <winnetwk.h>
#include <objsafe.h>

View file

@ -107,6 +107,8 @@ static __inline int SHELL32_GUIDToStringW (REFGUID guid, LPWSTR str)
void SHELL_FS_ProcessDisplayFilename(LPWSTR szPath, DWORD dwFlags);
BOOL SHELL_FS_HideExtension(LPWSTR pwszPath);
HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, REFIID riid, void **ppv);
#ifdef __cplusplus
HRESULT inline SHSetStrRet(LPSTRRET pStrRet, DWORD resId)