reactos/dll/win32/browseui/aclmulti.cpp
Amine Khaldi c424146e2c Create a branch for cmake bringup.
svn path=/branches/cmake-bringup/; revision=48236
2010-07-24 18:52:44 +00:00

159 lines
4.2 KiB
C++

/*
* Multisource AutoComplete list
*
* Copyright 2007 Mikolaj Zalewski
* Copyright 2009 Andrew Hill
*
* 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 St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <windows.h>
#include <shlobj.h>
#include <shlobj_undoc.h>
#include <shlguid.h>
#include <shlguid_undoc.h>
#include <tchar.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include "resource.h"
#include "wine/debug.h"
#include "aclmulti.h"
WINE_DEFAULT_DEBUG_CHANNEL(browseui);
void CACLMulti::release_obj(struct ACLMultiSublist *obj)
{
obj->punk->Release();
if (obj->pEnum)
obj->pEnum->Release();
if (obj->pACL)
obj->pACL->Release();
}
CACLMulti::CACLMulti()
{
fObjectCount = 0;
fCurrentObject = 0;
fObjects = NULL;
}
CACLMulti::~CACLMulti()
{
int i;
TRACE("destroying %p\n", this);
for (i = 0; i < fObjectCount; i++)
release_obj(&fObjects[i]);
CoTaskMemFree(fObjects);
}
HRESULT STDMETHODCALLTYPE CACLMulti::Append(IUnknown *punk)
{
TRACE("(%p, %p)\n", this, punk);
if (punk == NULL)
return E_FAIL;
fObjects = reinterpret_cast<struct ACLMultiSublist *>(CoTaskMemRealloc(fObjects, sizeof(fObjects[0]) * (fObjectCount + 1)));
fObjects[fObjectCount].punk = punk;
punk->AddRef();
if (FAILED(punk->QueryInterface(IID_IEnumString, (void **)&fObjects[fObjectCount].pEnum)))
fObjects[fObjectCount].pEnum = NULL;
if (FAILED(punk->QueryInterface(IID_IACList, (void **)&fObjects[fObjectCount].pACL)))
fObjects[fObjectCount].pACL = NULL;
fObjectCount++;
return S_OK;
}
HRESULT STDMETHODCALLTYPE CACLMulti::Remove(IUnknown *punk)
{
int i;
TRACE("(%p, %p)\n", this, punk);
for (i = 0; i < fObjectCount; i++)
if (fObjects[i].punk == punk)
{
release_obj(&fObjects[i]);
memmove(&fObjects[i], &fObjects[i + 1], (fObjectCount - i - 1) * sizeof(struct ACLMultiSublist));
fObjectCount--;
fObjects = reinterpret_cast<struct ACLMultiSublist *>(CoTaskMemRealloc(fObjects, sizeof(fObjects[0]) * fObjectCount));
return S_OK;
}
return E_FAIL;
}
HRESULT STDMETHODCALLTYPE CACLMulti::Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched)
{
TRACE("(%p, %d, %p, %p)\n", this, celt, rgelt, pceltFetched);
while (fCurrentObject < fObjectCount)
{
if (fObjects[fCurrentObject].pEnum)
{
/* native browseui 6.0 also returns only one element */
HRESULT ret = fObjects[fCurrentObject].pEnum->Next(1, rgelt, pceltFetched);
if (ret != S_FALSE)
return ret;
}
fCurrentObject++;
}
if (pceltFetched)
*pceltFetched = 0;
*rgelt = NULL;
return S_FALSE;
}
HRESULT STDMETHODCALLTYPE CACLMulti::Reset()
{
int i;
fCurrentObject = 0;
for (i = 0; i < fObjectCount; i++)
{
if (fObjects[i].pEnum)
fObjects[i].pEnum->Reset();
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE CACLMulti::Skip(ULONG celt)
{
/* native browseui 6.0 returns this: */
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CACLMulti::Clone(IEnumString **ppOut)
{
*ppOut = NULL;
/* native browseui 6.0 returns this: */
return E_OUTOFMEMORY;
}
HRESULT STDMETHODCALLTYPE CACLMulti::Expand(LPCWSTR wstr)
{
HRESULT res = S_OK;
int i;
for (i = 0; i < fObjectCount; i++)
{
if (!fObjects[i].pACL)
continue;
res = fObjects[i].pACL->Expand(wstr);
if (res == S_OK)
break;
}
return res;
}