From 22c0bb27236a62caf60a770a908aea7a7284176f Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Wed, 10 Aug 2016 18:56:48 +0000 Subject: [PATCH] [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 --- reactos/dll/win32/shell32/CMakeLists.txt | 3 +- .../shell32/folders/CControlPanelFolder.cpp | 33 ++- .../shell32/folders/CControlPanelFolder.h | 1 + .../win32/shell32/folders/CDesktopFolder.cpp | 37 ++- .../win32/shell32/folders/CDesktopFolder.h | 1 + .../win32/shell32/folders/CDrivesFolder.cpp | 128 +++++---- .../dll/win32/shell32/folders/CDrivesFolder.h | 2 + .../dll/win32/shell32/folders/CRegFolder.cpp | 256 ++++++++++++++++++ reactos/dll/win32/shell32/precomp.h | 1 + reactos/dll/win32/shell32/shfldr.h | 2 + 10 files changed, 364 insertions(+), 100 deletions(-) create mode 100644 reactos/dll/win32/shell32/folders/CRegFolder.cpp diff --git a/reactos/dll/win32/shell32/CMakeLists.txt b/reactos/dll/win32/shell32/CMakeLists.txt index 57a30f80f51..ef67633fbd7 100644 --- a/reactos/dll/win32/shell32/CMakeLists.txt +++ b/reactos/dll/win32/shell32/CMakeLists.txt @@ -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 diff --git a/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp b/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp index 664184569d8..cadf7c3e336 100644 --- a/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp @@ -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 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; } diff --git a/reactos/dll/win32/shell32/folders/CControlPanelFolder.h b/reactos/dll/win32/shell32/folders/CControlPanelFolder.h index ff31db51e6a..dbef5473b3a 100644 --- a/reactos/dll/win32/shell32/folders/CControlPanelFolder.h +++ b/reactos/dll/win32/shell32/folders/CControlPanelFolder.h @@ -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 m_regFolder; HRESULT WINAPI ExecuteFromIdList(LPCITEMIDLIST pidl); diff --git a/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp b/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp index 02dd05e32ac..b5f1b1f5b40 100644 --- a/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CDesktopFolder.cpp @@ -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 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 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 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 psf; HRESULT hr = _GetSFFromPidl(pidl, &psf); diff --git a/reactos/dll/win32/shell32/folders/CDesktopFolder.h b/reactos/dll/win32/shell32/folders/CDesktopFolder.h index 3f318e1c912..e8a685fbada 100644 --- a/reactos/dll/win32/shell32/folders/CDesktopFolder.h +++ b/reactos/dll/win32/shell32/folders/CDesktopFolder.h @@ -33,6 +33,7 @@ class CDesktopFolder : /* both paths are parsible from the desktop */ CComPtr m_DesktopFSFolder; CComPtr m_SharedDesktopFSFolder; + CComPtr m_regFolder; LPWSTR sPathTarget; /* complete path to target used for enumeration and ChangeNotify */ LPITEMIDLIST pidlRoot; /* absolute pidl */ diff --git a/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp b/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp index 5622a2fff7f..baa8eaeca1e 100644 --- a/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp +++ b/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp @@ -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 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 { diff --git a/reactos/dll/win32/shell32/folders/CDrivesFolder.h b/reactos/dll/win32/shell32/folders/CDrivesFolder.h index 769de23c1f8..f0adc4960aa 100644 --- a/reactos/dll/win32/shell32/folders/CDrivesFolder.h +++ b/reactos/dll/win32/shell32/folders/CDrivesFolder.h @@ -32,6 +32,8 @@ class CDrivesFolder : private: /* both paths are parsible from the desktop */ LPITEMIDLIST pidlRoot; /* absolute pidl */ + CComPtr m_regFolder; + public: CDrivesFolder(); ~CDrivesFolder(); diff --git a/reactos/dll/win32/shell32/folders/CRegFolder.cpp b/reactos/dll/win32/shell32/folders/CRegFolder.cpp new file mode 100644 index 00000000000..3f431225b1b --- /dev/null +++ b/reactos/dll/win32/shell32/folders/CRegFolder.cpp @@ -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 + +WINE_DEFAULT_DEBUG_CHANNEL (shell); + +class CRegFolder : + public CComObjectRootEx, + public IShellFolder2 +{ + private: + GUID m_guid; + CAtlStringW m_rootPath; + CComHeapPtr 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(pGuid, pidlRoot, lpszPath, riid, ppv); +} diff --git a/reactos/dll/win32/shell32/precomp.h b/reactos/dll/win32/shell32/precomp.h index 450c3b844e4..3ac688d6834 100644 --- a/reactos/dll/win32/shell32/precomp.h +++ b/reactos/dll/win32/shell32/precomp.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/win32/shell32/shfldr.h b/reactos/dll/win32/shell32/shfldr.h index 61759c6e016..17953b34591 100644 --- a/reactos/dll/win32/shell32/shfldr.h +++ b/reactos/dll/win32/shell32/shfldr.h @@ -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)