[SHELL32] Simplify HIDA usage

This commit is contained in:
Mark Jansen 2021-07-25 01:10:24 +02:00
parent eb0c005c1b
commit fa0f5cc4be
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B
6 changed files with 26 additions and 104 deletions

View file

@ -9,38 +9,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
HRESULT _GetCidlFromDataObject(IDataObject *pDataObject, CIDA** ppcida)
{
static CLIPFORMAT s_cfHIDA = 0;
if (s_cfHIDA == 0)
{
s_cfHIDA = static_cast<CLIPFORMAT>(RegisterClipboardFormatW(CFSTR_SHELLIDLIST));
}
FORMATETC fmt = { s_cfHIDA, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM medium;
HRESULT hr = pDataObject->GetData(&fmt, &medium);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
LPVOID lpSrc = GlobalLock(medium.hGlobal);
SIZE_T cbSize = GlobalSize(medium.hGlobal);
*ppcida = reinterpret_cast<CIDA *>(::CoTaskMemAlloc(cbSize));
if (*ppcida)
{
memcpy(*ppcida, lpSrc, cbSize);
hr = S_OK;
}
else
{
ERR("Out of memory\n");
hr = E_FAIL;
}
ReleaseStgMedium(&medium);
return hr;
}
CCopyToMenu::CCopyToMenu() :
m_idCmdFirst(0),
@ -157,10 +125,9 @@ BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
HRESULT CCopyToMenu::DoRealCopy(LPCMINVOKECOMMANDINFO lpici, LPCITEMIDLIST pidl)
{
CComHeapPtr<CIDA> pCIDA;
HRESULT hr = _GetCidlFromDataObject(m_pDataObject, &pCIDA);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
CDataObjectHIDA pCIDA(m_pDataObject);
if (FAILED_UNEXPECTEDLY(pCIDA.hr()))
return pCIDA.hr();
PCUIDLIST_ABSOLUTE pidlParent = HIDA_GetPIDLFolder(pCIDA);
if (!pidlParent)
@ -224,9 +191,8 @@ CStringW CCopyToMenu::DoGetFileTitle()
{
CStringW ret = L"(file)";
CComHeapPtr<CIDA> pCIDA;
HRESULT hr = _GetCidlFromDataObject(m_pDataObject, &pCIDA);
if (FAILED_UNEXPECTEDLY(hr))
CDataObjectHIDA pCIDA(m_pDataObject);
if (FAILED_UNEXPECTEDLY(pCIDA.hr()))
return ret;
PCUIDLIST_ABSOLUTE pidlParent = HIDA_GetPIDLFolder(pCIDA);

View file

@ -6,7 +6,6 @@
*/
#pragma once
HRESULT _GetCidlFromDataObject(IDataObject *pDataObject, CIDA** ppcida);
class CCopyToMenu :
public CComCoClass<CCopyToMenu, &CLSID_CopyToMenu>,

View file

@ -124,10 +124,9 @@ BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
HRESULT CMoveToMenu::DoRealMove(LPCMINVOKECOMMANDINFO lpici, LPCITEMIDLIST pidl)
{
CComHeapPtr<CIDA> pCIDA;
HRESULT hr = _GetCidlFromDataObject(m_pDataObject, &pCIDA);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
CDataObjectHIDA pCIDA(m_pDataObject);
if (FAILED_UNEXPECTEDLY(pCIDA.hr()))
return pCIDA.hr();
PCUIDLIST_ABSOLUTE pidlParent = HIDA_GetPIDLFolder(pCIDA);
if (!pidlParent)
@ -191,9 +190,8 @@ CStringW CMoveToMenu::DoGetFileTitle()
{
CStringW ret = L"(file)";
CComHeapPtr<CIDA> pCIDA;
HRESULT hr = _GetCidlFromDataObject(m_pDataObject, &pCIDA);
if (FAILED_UNEXPECTEDLY(hr))
CDataObjectHIDA pCIDA(m_pDataObject);
if (FAILED_UNEXPECTEDLY(pCIDA.hr()))
return ret;
PCUIDLIST_ABSOLUTE pidlParent = HIDA_GetPIDLFolder(pCIDA);

View file

@ -1352,53 +1352,33 @@ COpenWithMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder,
IDataObject *pdtobj,
HKEY hkeyProgID)
{
STGMEDIUM medium;
FORMATETC fmt;
HRESULT hr;
LPIDA pida;
LPCITEMIDLIST pidlFolder2;
LPCITEMIDLIST pidlChild;
LPCITEMIDLIST pidl;
LPCWSTR pwszExt;
TRACE("This %p\n", this);
if (pdtobj == NULL)
return E_INVALIDARG;
fmt.cfFormat = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
fmt.ptd = NULL;
fmt.dwAspect = DVASPECT_CONTENT;
fmt.lindex = -1;
fmt.tymed = TYMED_HGLOBAL;
hr = pdtobj->GetData(&fmt, &medium);
if (FAILED(hr))
CDataObjectHIDA pida(pdtobj);
if (FAILED(pida.hr()))
{
ERR("pdtobj->GetData failed with 0x%x\n", hr);
return hr;
ERR("pdtobj->GetData failed with 0x%x\n", pida.hr());
return pida.hr();
}
pida = (LPIDA)GlobalLock(medium.hGlobal);
ASSERT(pida->cidl >= 1);
pidlFolder2 = (LPCITEMIDLIST) ((LPBYTE)pida + pida->aoffset[0]);
pidlChild = (LPCITEMIDLIST) ((LPBYTE)pida + pida->aoffset[1]);
pidlFolder2 = HIDA_GetPIDLFolder(pida);
pidlChild = HIDA_GetPIDLItem(pida, 0);
if (!_ILIsValue(pidlChild))
{
TRACE("pidl is not a file\n");
GlobalUnlock(medium.hGlobal);
ReleaseStgMedium(&medium);
return E_FAIL;
}
pidl = ILCombine(pidlFolder2, pidlChild);
GlobalUnlock(medium.hGlobal);
ReleaseStgMedium(&medium);
CComHeapPtr<ITEMIDLIST> pidl(ILCombine(pidlFolder2, pidlChild));
if (!pidl)
{
ERR("no mem\n");
@ -1407,15 +1387,13 @@ COpenWithMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder,
if (!SHGetPathFromIDListW(pidl, m_wszPath))
{
SHFree((void*)pidl);
ERR("SHGetPathFromIDListW failed\n");
return E_FAIL;
}
SHFree((void*)pidl);
TRACE("szPath %s\n", debugstr_w(m_wszPath));
pwszExt = PathFindExtensionW(m_wszPath);
LPCWSTR pwszExt = PathFindExtensionW(m_wszPath);
if (PathIsExeW(pwszExt) || !_wcsicmp(pwszExt, L".lnk"))
{
TRACE("file is a executable or shortcut\n");

View file

@ -55,6 +55,8 @@ static WCHAR* BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls
* CFSDropTarget::_CopyItems
*
* copies items to this folder
* FIXME: We should not ask the parent folder: 'What is your path', and then manually build paths assuming everything is a simple pidl!
* We should be asking the parent folder: Give me a full name for this pidl (for each child!)
*/
HRESULT CFSDropTarget::_CopyItems(IShellFolder * pSFFrom, UINT cidl,
LPCITEMIDLIST * apidl, BOOL bCopy)
@ -732,4 +734,4 @@ DWORD WINAPI CFSDropTarget::_DoDropThreadProc(LPVOID lpParameter)
HRESULT CFSDropTarget_CreateInstance(LPWSTR sPathTarget, REFIID riid, LPVOID * ppvOut)
{
return ShellObjectCreatorInit<CFSDropTarget>(sPathTarget, riid, ppvOut);
}
}

View file

@ -326,44 +326,23 @@ void AddFSClassKeysToArray(PCUITEMID_CHILD pidl, HKEY* array, UINT* cKeys)
HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE* ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl)
{
UINT cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
if (!cfShellIDList)
return E_FAIL;
CDataObjectHIDA cida(pDataObject);
FORMATETC fmt;
InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL);
HRESULT hr = pDataObject->QueryGetData(&fmt);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
STGMEDIUM medium;
hr = pDataObject->GetData(&fmt, &medium);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
/* lock the handle */
LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
if (!lpcida)
{
ReleaseStgMedium(&medium);
return E_FAIL;
}
if (FAILED_UNEXPECTEDLY(cida.hr()))
return cida.hr();
/* convert the data into pidl */
LPITEMIDLIST pidl;
LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, cida);
if (!apidl)
{
ReleaseStgMedium(&medium);
return E_OUTOFMEMORY;
}
*ppidlfolder = pidl;
*apidlItems = apidl;
*pcidl = lpcida->cidl;
*pcidl = cida->cidl;
ReleaseStgMedium(&medium);
return S_OK;
}