mirror of
https://github.com/reactos/reactos.git
synced 2024-08-20 10:23:22 +00:00
149 lines
4.1 KiB
C++
149 lines
4.1 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 "precomp.h"
|
|
|
|
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 = static_cast<ACLMultiSublist *>(
|
|
CoTaskMemRealloc(fObjects, sizeof(fObjects[0]) * (fObjectCount + 1)));
|
|
fObjects[fObjectCount].punk = punk;
|
|
punk->AddRef();
|
|
if (FAILED_UNEXPECTEDLY(punk->QueryInterface(IID_PPV_ARG(IEnumString, &fObjects[fObjectCount].pEnum))))
|
|
fObjects[fObjectCount].pEnum = NULL;
|
|
if (FAILED_UNEXPECTEDLY(punk->QueryInterface(IID_PPV_ARG(IACList, &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]);
|
|
MoveMemory(&fObjects[i], &fObjects[i + 1], (fObjectCount - i - 1) * sizeof(ACLMultiSublist));
|
|
fObjectCount--;
|
|
fObjects = static_cast<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;
|
|
}
|