[SHDOCVW][SHELL32] Rename RegItem to empty name must reset the name to the default (#7794)

CORE-18839
This commit is contained in:
Whindmar Saksit 2025-03-21 13:51:45 +01:00 committed by GitHub
parent 27bb510282
commit 56e7afe56c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 201 additions and 84 deletions

View file

@ -235,7 +235,7 @@ CExplorerBand::_NavigateToPIDL(
HTREEITEM hParent = NULL, tmp;
while (TRUE)
{
CItemData *pItemData = GetItemData(hItem);
CItemData *pItemData = _GetItemData(hItem);
if (!pItemData)
{
ERR("Something has gone wrong, no data associated to node\n");

View file

@ -146,7 +146,7 @@ STDMETHODIMP CFavBand::OnSelectionChanged(_In_ PCIDLIST_ABSOLUTE pidl)
if (attrs & SFGAO_FOLDER)
{
HTREEITEM hItem = TreeView_GetSelection(m_hwndTreeView);
CItemData *pItemData = GetItemData(hItem);
CItemData *pItemData = _GetItemData(hItem);
if (pItemData && !pItemData->expanded)
{
_InsertSubitems(hItem, pItemData->absolutePidl);

View file

@ -99,7 +99,7 @@ VOID CNSCBand::OnFinalMessage(HWND)
// *** helper methods ***
CNSCBand::CItemData* CNSCBand::GetItemData(_In_ HTREEITEM hItem)
CNSCBand::CItemData* CNSCBand::_GetItemData(_In_ HTREEITEM hItem)
{
if (hItem == TVI_ROOT)
return NULL;
@ -111,6 +111,39 @@ CNSCBand::CItemData* CNSCBand::GetItemData(_In_ HTREEITEM hItem)
return reinterpret_cast<CItemData*>(tvItem.lParam);
}
CNSCBand::CItemData* CNSCBand::_GetItemData(_In_ UINT ItemSpec)
{
HTREEITEM hItem = m_hwndTreeView.GetNextItem(NULL, ItemSpec);
return hItem ? _GetItemData(hItem) : NULL;
}
SFGAOF CNSCBand::_GetAttributesOfItem(_In_ CItemData *pData, _In_ SFGAOF Query)
{
if (!pData)
return 0;
CComPtr<IShellFolder> pFolder;
LPCITEMIDLIST pidlChild;
HRESULT hr = SHBindToParent(pData->absolutePidl, IID_PPV_ARG(IShellFolder, &pFolder), &pidlChild);
if (FAILED_UNEXPECTEDLY(hr))
return 0;
SFGAOF Attributes = Query;
if (FAILED_UNEXPECTEDLY(hr = pFolder->GetAttributesOf(1, &pidlChild, &Attributes)))
return 0;
return Attributes & Query;
}
HRESULT CNSCBand::_GetNameOfItem(IShellFolder *pSF, PCUITEMID_CHILD pidl, PWSTR Name)
{
STRRET strret;
HRESULT hr = pSF->GetDisplayNameOf(pidl, SHGDN_INFOLDER, &strret);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = StrRetToBufW(&strret, pidl, Name, MAX_PATH);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
return hr;
}
static HRESULT
SHDOCVW_GetCurrentLocationFromView(_In_ IShellView& View, _In_ PIDLIST_ABSOLUTE *ppidl)
{
@ -260,7 +293,7 @@ CNSCBand::_IsTreeItemInEnum(
_In_ HTREEITEM hItem,
_In_ IEnumIDList *pEnum)
{
CItemData* pItemData = GetItemData(hItem);
CItemData* pItemData = _GetItemData(hItem);
if (!pItemData)
return FALSE;
@ -286,7 +319,7 @@ CNSCBand::_TreeItemHasThisChild(
for (hItem = TreeView_GetChild(m_hwndTreeView, hItem); hItem;
hItem = TreeView_GetNextSibling(m_hwndTreeView, hItem))
{
CItemData* pItemData = GetItemData(hItem);
CItemData* pItemData = _GetItemData(hItem);
if (ILIsEqual(pItemData->relativePidl, pidlChild))
return TRUE;
}
@ -316,7 +349,7 @@ CNSCBand::_GetItemEnum(
}
else
{
CItemData* pItemData = GetItemData(hItem);
CItemData* pItemData = _GetItemData(hItem);
if (!pItemData && hItem == TVI_ROOT && !_WantsRootItem())
hr = psfDesktop->BindToObject(m_pidlRoot, NULL, IID_PPV_ARG(IShellFolder, ppFolder));
else
@ -358,7 +391,7 @@ void CNSCBand::_RefreshRecurse(_In_ HTREEITEM hTarget)
pEnum = NULL;
hrEnum = _GetItemEnum(pEnum, hTarget);
CItemData* pItemData = ((hTarget == TVI_ROOT) ? NULL : GetItemData(hTarget));
CItemData* pItemData = ((hTarget == TVI_ROOT) ? NULL : _GetItemData(hTarget));
// Insert new items and update items
if (SUCCEEDED(hrEnum))
@ -461,19 +494,12 @@ CNSCBand::_InsertItem(
if (FAILED_UNEXPECTEDLY(hr))
return NULL;
/* Get the name of the node */
WCHAR wszDisplayName[MAX_PATH];
STRRET strret;
hr = psfParent->GetDisplayNameOf(pEltRelative, SHGDN_INFOLDER, &strret);
if (FAILED_UNEXPECTEDLY(hr))
if (FAILED_UNEXPECTEDLY(hr = _GetNameOfItem(psfParent, pEltRelative, wszDisplayName)))
return NULL;
hr = StrRetToBufW(&strret, pEltRelative, wszDisplayName, MAX_PATH);
if (FAILED_UNEXPECTEDLY(hr))
return NULL;
/* Get the icon of the node */
INT iIcon = SHMapPIDLToSystemImageListIndex(psfParent, pEltRelative, NULL);
INT iSelIcon = -1;
INT iIcon = SHMapPIDLToSystemImageListIndex(psfParent, pEltRelative, &iSelIcon);
CItemData* pChildInfo = new CItemData;
if (!pChildInfo)
@ -489,7 +515,8 @@ CNSCBand::_InsertItem(
tvInsert.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;
tvInsert.item.cchTextMax = MAX_PATH;
tvInsert.item.pszText = wszDisplayName;
tvInsert.item.iImage = tvInsert.item.iSelectedImage = iIcon;
tvInsert.item.iImage = iIcon;
tvInsert.item.iSelectedImage = iSelIcon >= 0 ? iSelIcon : iIcon;
tvInsert.item.lParam = (LPARAM)pChildInfo;
if (!(attrs & SFGAO_STREAM) && (attrs & SFGAO_HASSUBFOLDER))
@ -684,7 +711,7 @@ BOOL CNSCBand::OnTreeItemExpanding(_In_ LPNMTREEVIEW pnmtv)
if (pnmtv->action == TVE_EXPAND)
{
// Grab our directory PIDL
pItemData = GetItemData(pnmtv->itemNew.hItem);
pItemData = _GetItemData(pnmtv->itemNew.hItem);
// We have it, let's try
if (pItemData && !pItemData->expanded)
{
@ -713,7 +740,7 @@ BOOL CNSCBand::OnTreeItemDeleted(_In_ LPNMTREEVIEW pnmtv)
TreeView_SelectItem(m_hwndTreeView, hParent);
/* Destroy memory associated to our node */
CItemData* pItemData = GetItemData(hItem);
CItemData* pItemData = _GetItemData(hItem);
if (!pItemData)
return FALSE;
@ -727,14 +754,14 @@ void CNSCBand::_OnSelectionChanged(_In_ LPNMTREEVIEW pnmtv)
HTREEITEM hItem = pnmtv->itemNew.hItem;
if (!hItem)
return;
CItemData* pItemData = GetItemData(hItem);
CItemData* pItemData = _GetItemData(hItem);
if (pItemData)
OnSelectionChanged(pItemData->absolutePidl);
}
void CNSCBand::OnTreeItemDragging(_In_ LPNMTREEVIEW pnmtv, _In_ BOOL isRightClick)
{
CItemData* pItemData = GetItemData(pnmtv->itemNew.hItem);
CItemData* pItemData = _GetItemData(pnmtv->itemNew.hItem);
if (!pItemData)
return;
@ -772,7 +799,7 @@ LRESULT CNSCBand::OnBeginLabelEdit(_In_ LPNMTVDISPINFO dispInfo)
LPCITEMIDLIST pChild;
HRESULT hr;
CItemData *info = GetItemData(dispInfo->item.hItem);
CItemData *info = _GetItemData(dispInfo->item.hItem);
if (!info)
return FALSE;
@ -791,7 +818,7 @@ LRESULT CNSCBand::OnBeginLabelEdit(_In_ LPNMTVDISPINFO dispInfo)
return TRUE;
}
HRESULT CNSCBand::_UpdateBrowser(LPCITEMIDLIST pidlGoto)
HRESULT CNSCBand::_UpdateBrowser(LPCITEMIDLIST pidlGoto, BOOL IgnoreSelfNavigation)
{
CComPtr<IShellBrowser> pBrowserService;
HRESULT hr = IUnknown_QueryService(m_pSite, SID_STopLevelBrowser,
@ -799,6 +826,17 @@ HRESULT CNSCBand::_UpdateBrowser(LPCITEMIDLIST pidlGoto)
if (FAILED_UNEXPECTEDLY(hr))
return hr;
if (_IsCurrentLocation(pidlGoto) == S_OK) // Don't add duplicates to the travel log
{
if (IgnoreSelfNavigation)
return S_FALSE;
CComPtr<IShellView> psv;
if (SUCCEEDED(hr = pBrowserService->QueryActiveShellView(&psv)))
hr = psv->Refresh();
if (SUCCEEDED(hr))
return hr;
}
hr = pBrowserService->BrowseObject(pidlGoto, SBSP_SAMEBROWSER | SBSP_ABSOLUTE);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@ -808,8 +846,9 @@ HRESULT CNSCBand::_UpdateBrowser(LPCITEMIDLIST pidlGoto)
LRESULT CNSCBand::OnEndLabelEdit(_In_ LPNMTVDISPINFO dispInfo)
{
CItemData *info = GetItemData(dispInfo->item.hItem);
CItemData *info = _GetItemData(dispInfo->item.hItem);
HRESULT hr;
BOOL AllowTreeSetNewName = TRUE;
m_isEditing = FALSE;
if (m_oldSelected)
@ -847,7 +886,19 @@ LRESULT CNSCBand::OnEndLabelEdit(_In_ LPNMTVDISPINFO dispInfo)
CComHeapPtr<ITEMIDLIST> pidlNewAbs(ILCombine(pidlParent, pidlNew));
if (RenamedCurrent)
{
_UpdateBrowser(pidlNewAbs);
// Get the new item name from the folder because RegItems can be renamed to their
// default name by the folder (which is not the string we have in NMTVDISPINFO).
WCHAR wszDisplayName[MAX_PATH];
if (SUCCEEDED(_GetNameOfItem(pParent, pidlNew, wszDisplayName)))
{
TVITEMW tvi;
tvi.mask = TVIF_TEXT;
tvi.hItem = dispInfo->item.hItem;
tvi.pszText = wszDisplayName;
AllowTreeSetNewName = !m_hwndTreeView.SetItem(&tvi);
}
_UpdateBrowser(pidlNewAbs, TRUE);
}
else
{
@ -855,7 +906,7 @@ LRESULT CNSCBand::OnEndLabelEdit(_In_ LPNMTVDISPINFO dispInfo)
SHChangeNotify(SHCNE_RENAMEFOLDER, SHCNF_IDLIST, info->absolutePidl, pidlNewAbs);
}
return TRUE;
return AllowTreeSetNewName;
}
return FALSE;
@ -961,7 +1012,7 @@ LRESULT CNSCBand::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b
ClientToScreen(&pt);
}
CItemData *info = GetItemData(hItem);
CItemData *info = _GetItemData(hItem);
if (!info)
{
ERR("No node data, something has gone wrong\n");
@ -1246,14 +1297,45 @@ STDMETHODIMP CNSCBand::HasFocusIO()
STDMETHODIMP CNSCBand::TranslateAcceleratorIO(LPMSG lpMsg)
{
if (lpMsg->message == WM_KEYDOWN && lpMsg->wParam == VK_F2 && !m_isEditing)
{
if (HTREEITEM hItem = m_hwndTreeView.GetNextItem(NULL, TVGN_CARET))
{
if (_GetAttributesOfItem(_GetItemData(hItem), SFGAO_CANRENAME))
{
m_hwndTreeView.SetFocus();
m_hwndTreeView.EditLabel(hItem);
return S_OK;
}
}
}
if (lpMsg->message == WM_SYSKEYDOWN && lpMsg->wParam == VK_RETURN && !m_isEditing)
{
CItemData *pItem = _GetItemData(TVGN_CARET);
if (pItem && _GetAttributesOfItem(pItem, SFGAO_HASPROPSHEET))
{
SHELLEXECUTEINFOW sei = { sizeof(sei), SEE_MASK_INVOKEIDLIST, m_hwndTreeView };
sei.lpVerb = L"properties";
sei.lpIDList = pItem->absolutePidl;
sei.nShow = SW_SHOW;
ShellExecuteExW(&sei);
return S_OK;
}
else
{
MessageBeep(0xFFFFFFFF);
}
}
if (lpMsg->hwnd == m_hWnd ||
(m_isEditing && IsChild(lpMsg->hwnd)))
{
// TODO: Why is it doing this for m_hWnd for all messages?!
TranslateMessage(lpMsg);
DispatchMessage(lpMsg);
return S_OK;
}
return S_FALSE;
}
@ -1413,7 +1495,7 @@ STDMETHODIMP CNSCBand::DragOver(DWORD glfKeyState, POINTL pt, DWORD *pdwEffect)
if (info.hItem != m_childTargetNode)
{
CItemData *pItemData = GetItemData(info.hItem);
CItemData *pItemData = _GetItemData(info.hItem);
if (!pItemData)
return E_FAIL;

View file

@ -41,7 +41,10 @@ public:
CComHeapPtr<ITEMIDLIST> relativePidl;
BOOL expanded = FALSE;
};
CItemData* GetItemData(_In_ HTREEITEM hItem);
CItemData* _GetItemData(_In_ HTREEITEM hItem);
CItemData* _GetItemData(_In_ UINT ItemSpec = TVGN_CARET);
SFGAOF _GetAttributesOfItem(_In_ CItemData *pData, _In_ SFGAOF Query);
HRESULT _GetNameOfItem(IShellFolder *pSF, PCUITEMID_CHILD pidl, PWSTR Name);
// *** IOleWindow methods ***
STDMETHODIMP GetWindow(HWND *lphwnd) override;
@ -189,7 +192,7 @@ protected:
_In_ LPCITEMIDLIST pEltRelative,
_In_ BOOL bSort);
BOOL _InsertSubitems(HTREEITEM hItem, LPCITEMIDLIST entry);
HRESULT _UpdateBrowser(LPCITEMIDLIST pidlGoto);
HRESULT _UpdateBrowser(LPCITEMIDLIST pidlGoto, BOOL IgnoreSelfNavigation = FALSE);
HRESULT _GetCurrentLocation(_Out_ PIDLIST_ABSOLUTE *ppidl);
HRESULT _IsCurrentLocation(_In_ PCIDLIST_ABSOLUTE pidl);
void _Refresh();

View file

@ -324,7 +324,8 @@ public:
int LV_AddItem(PCUITEMID_CHILD pidl);
BOOLEAN LV_DeleteItem(PCUITEMID_CHILD pidl);
BOOLEAN LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew);
BOOLEAN LV_UpdateItem(PCUITEMID_CHILD pidl);
BOOL LV_UpdateItem(INT nItem, PCUITEMID_CHILD pidl);
BOOL LV_UpdateItem(PCUITEMID_CHILD pidl);
void LV_RefreshIcon(INT iItem);
void LV_RefreshIcons();
static INT CALLBACK fill_list(LPVOID ptr, LPVOID arg);
@ -1434,18 +1435,11 @@ BOOLEAN CDefView::LV_RenameItem(PCUITEMID_CHILD pidlOld, PCUITEMID_CHILD pidlNew
return FALSE;
}
BOOLEAN CDefView::LV_UpdateItem(PCUITEMID_CHILD pidl)
BOOL CDefView::LV_UpdateItem(INT nItem, PCUITEMID_CHILD pidl)
{
int nItem;
BOOL bResult = FALSE;
LVITEMW lvItem;
TRACE("(%p)(pidl=%p)\n", this, pidl);
ASSERT(m_ListView);
nItem = LV_FindItemByPidl(pidl);
if (-1 != nItem)
if (nItem >= 0)
{
_DoFolderViewCB(SFVM_UPDATINGOBJECT, nItem, (LPARAM)pidl);
@ -1459,13 +1453,20 @@ BOOLEAN CDefView::LV_UpdateItem(PCUITEMID_CHILD pidl)
PCUITEMID_CHILD pidlOld = _PidlByItem(nItem);
if (pidlOld && (lvItem.lParam = reinterpret_cast<LPARAM>(ILClone(pidl))) != NULL)
lvItem.mask |= LVIF_PARAM;
if (m_ListView.SetItem(&lvItem) && lvItem.lParam && pidlOld)
bResult = m_ListView.SetItem(&lvItem);
if (bResult && lvItem.lParam && pidlOld)
ILFree(const_cast<PUITEMID_CHILD>(pidlOld));
for (UINT i = 0; m_ListView.SetItemText(nItem, i, LPSTR_TEXTCALLBACK); ++i) {} // Update all columns
return TRUE;
}
return bResult;
}
return FALSE;
BOOL CDefView::LV_UpdateItem(PCUITEMID_CHILD pidl)
{
TRACE("(%p)(pidl=%p)\n", this, pidl);
ASSERT(m_ListView);
INT nItem = LV_FindItemByPidl(pidl);
return nItem >= 0 ? LV_UpdateItem(nItem, pidl) : FALSE;
}
void CDefView::LV_RefreshIcon(INT iItem)
@ -2824,29 +2825,32 @@ LRESULT CDefView::OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandl
{
TRACE("-- LVN_ENDLABELEDITW %p\n", this);
m_isEditing = FALSE;
if (!lpdi->item.pszText)
return TRUE;
if (lpdi->item.pszText)
pidl = _PidlByItem(lpdi->item);
// We have to copy the old PIDL because SetNameOf might generate a SHCNE_UPDATEITEM
// and that notification can cause us to call LV_UpdateItem and free the old PIDL too soon.
CComHeapPtr<ITEMIDLIST_ABSOLUTE> pidlOld(ILClone(pidl));
if (!pidlOld)
{
HRESULT hr;
LVITEMW lvItem;
pidl = _PidlByItem(lpdi->item);
PITEMID_CHILD pidlNew = NULL;
hr = m_pSFParent->SetNameOf(0, pidl, lpdi->item.pszText, SHGDN_INFOLDER, &pidlNew);
if (SUCCEEDED(hr) && pidlNew)
{
lvItem.mask = LVIF_PARAM|LVIF_IMAGE;
lvItem.iItem = lpdi->item.iItem;
lvItem.iSubItem = 0;
lvItem.lParam = reinterpret_cast<LPARAM>(pidlNew);
lvItem.iImage = SHMapPIDLToSystemImageListIndex(m_pSFParent, pidlNew, 0);
m_ListView.SetItem(&lvItem);
m_ListView.Update(lpdi->item.iItem);
return TRUE;
}
SHELL_ErrorBox(lpdi->hdr.hwndFrom, E_OUTOFMEMORY);
return FALSE;
}
PITEMID_CHILD pidlNew = NULL;
HRESULT hr = m_pSFParent->SetNameOf(0, pidlOld, lpdi->item.pszText, SHGDN_INFOLDER, &pidlNew);
if (SUCCEEDED(hr) && pidlNew)
{
int iNew = LV_FindItemByPidl(pidlNew);
if (iNew != lpdi->item.iItem && iNew >= 0)
ILFree(pidlNew);// A SHCNE has updated the item already
else if (!LV_UpdateItem(lpdi->item.iItem, pidlNew))
ILFree(pidlNew);
}
else
{
::PostMessageW(m_ListView, LVM_EDITLABEL, lpdi->item.iItem, 0); // Renaming failed, let the user try again
}
return FALSE;
}
default:

View file

@ -125,7 +125,7 @@ class CDesktopFolder :
}
if (ppwszInvalidChars)
{
SHStrDupW(INVALID_FILETITLE_CHARACTERSW, ppwszInvalidChars);
return SHStrDupW(INVALID_FILETITLE_CHARACTERSW, ppwszInvalidChars);
}
return S_OK;
}

View file

@ -755,33 +755,35 @@ HRESULT WINAPI CRegFolder::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags,
HRESULT WINAPI CRegFolder::SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, /* simple pidl */
LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut)
{
GUID const *clsid = _ILGetGUIDPointer (pidl);
LPOLESTR pStr;
HRESULT hr;
GUID const *clsid = IsRegItem(pidl);
WCHAR szName[100];
if (!lpName || (*lpName && IsIllegalFsFileName(lpName))) // Note: Must allow empty name
return E_INVALIDARG;
if (!clsid)
{
ERR("Pidl is not reg item!\n");
return E_FAIL;
}
FormatGUIDKey(szName, _countof(szName), L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%s", clsid);
hr = StringFromCLSID(*clsid, &pStr);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
swprintf(szName, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%s", pStr);
BOOL bEmpty = StrIsNullOrEmpty(lpName); // Empty resets to the default name
DWORD cbData = (wcslen(lpName) + 1) * sizeof(WCHAR);
LONG res = SHSetValueW(HKEY_CURRENT_USER, szName, NULL, RRF_RT_REG_SZ, lpName, cbData);
CoTaskMemFree(pStr);
LONG res = bEmpty ? SHDeleteValueW(HKEY_CURRENT_USER, szName, NULL)
: SHSetValueW(HKEY_CURRENT_USER, szName, NULL, RRF_RT_REG_SZ, lpName, cbData);
if (res == ERROR_SUCCESS)
{
return pPidlOut ? SHILClone(pidl, pPidlOut) : S_OK;
HRESULT hr = pPidlOut ? SHILClone(pidl, pPidlOut) : S_OK; // Copy the PIDL before SHChangeNotify
PIDLIST_ABSOLUTE pidlAbs;
if (SUCCEEDED(SHELL_CreateAbsolutePidl(m_pOuterFolder, pidl, &pidlAbs)))
{
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_IDLIST, pidlAbs, NULL);
ILFree(pidlAbs);
}
return hr;
}
return E_FAIL;
}

View file

@ -307,6 +307,7 @@
307 stdcall SHGetFolderPathW(long long long long ptr)
308 stdcall SHGetIconOverlayIndexA(str long)
309 stdcall SHGetIconOverlayIndexW(wstr long)
@ stdcall -version=0x600+ SHGetIDListFromObject(ptr ptr)
310 stdcall SHGetInstanceExplorer(long)
311 stdcall SHGetMalloc(ptr)
312 stdcall SHGetNewLinkInfo(str str ptr long long) SHGetNewLinkInfoA

View file

@ -94,6 +94,9 @@ SHELL_GetDefaultFolderEnumSHCONTF();
BOOL
SHELL_IncludeItemInFolderEnum(IShellFolder *pSF, PCUITEMID_CHILD pidl, SFGAOF Query, SHCONTF Flags);
HRESULT
SHELL_CreateAbsolutePidl(IShellFolder *pSF, PCUIDLIST_RELATIVE pidlChild, PIDLIST_ABSOLUTE *ppPidl);
HRESULT
Shell_NextElement(
_Inout_ LPWSTR *ppch,
@ -154,6 +157,11 @@ static __inline int SHELL32_GUIDToStringW (REFGUID guid, LPWSTR str)
void SHELL_FS_ProcessDisplayFilename(LPWSTR szPath, DWORD dwFlags);
BOOL SHELL_FS_HideExtension(LPCWSTR pwszPath);
static inline BOOL IsIllegalFsFileName(PCWSTR Name)
{
return StrIsNullOrEmpty(Name) || StrPBrkW(Name, INVALID_FILETITLE_CHARACTERSW);
}
void CloseRegKeyArray(HKEY* array, UINT cKeys);
LSTATUS AddClassKeyToArray(const WCHAR* szClass, HKEY* array, UINT* cKeys);
LSTATUS AddClsidKeyToArray(REFCLSID clsid, HKEY* array, UINT* cKeys);

View file

@ -54,6 +54,18 @@ BOOL SHELL_IncludeItemInFolderEnum(IShellFolder *pSF, PCUITEMID_CHILD pidl, SFGA
return TRUE;
}
HRESULT SHELL_CreateAbsolutePidl(IShellFolder *pSF, PCUIDLIST_RELATIVE pidlChild, PIDLIST_ABSOLUTE *ppPidl)
{
PIDLIST_ABSOLUTE pidlFolder;
HRESULT hr = SHGetIDListFromObject(pSF, &pidlFolder);
if (SUCCEEDED(hr))
{
hr = SHILCombine(pidlFolder, pidlChild, ppPidl);
ILFree(pidlFolder);
}
return hr;
}
HRESULT
Shell_NextElement(
_Inout_ LPWSTR *ppch,

View file

@ -1623,7 +1623,14 @@ HRESULT WINAPI SHGetNameFromIDList(PCIDLIST_ABSOLUTE pidl, SIGDN sigdnName, PWST
return ret;
}
#ifndef __REACTOS__
/*************************************************************************
* SHGetItemFromDataObject [SHELL32.@]
*/
HRESULT WINAPI SHGetItemFromDataObject(IDataObject *pdtobj, DATAOBJ_GET_ITEM_FLAGS dwFlags,
REFIID riid, void **ppv)
{
return E_NOTIMPL; // FIXME
}
/*************************************************************************
* SHGetIDListFromObject [SHELL32.@]
@ -1701,8 +1708,6 @@ HRESULT WINAPI SHGetIDListFromObject(IUnknown *punk, PIDLIST_ABSOLUTE *ppidl)
return ret;
}
#endif /* !__REACTOS__ */
/**************************************************************************
*
* internal functions