Reactos
at master 214 lines 4.8 kB view raw
1/* 2 * IEnumIDList 3 * 4 * Copyright 1998 Juergen Schmied <juergen.schmied@metronet.de> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21#include "precomp.h" 22 23WINE_DEFAULT_DEBUG_CHANNEL(shell); 24 25CEnumIDListBase::CEnumIDListBase() : 26 mpFirst(NULL), 27 mpLast(NULL), 28 mpCurrent(NULL) 29{ 30} 31 32CEnumIDListBase::~CEnumIDListBase() 33{ 34 DeleteList(); 35} 36 37/************************************************************************** 38 * AddToEnumList() 39 */ 40BOOL CEnumIDListBase::AddToEnumList(LPITEMIDLIST pidl) 41{ 42 ENUMLIST *pNew; 43 44 TRACE("(%p)->(pidl=%p)\n", this, pidl); 45 46 if (!pidl) 47 return FALSE; 48 49 pNew = static_cast<ENUMLIST *>(SHAlloc(sizeof(ENUMLIST))); 50 if (pNew) 51 { 52 /*set the next pointer */ 53 pNew->pNext = NULL; 54 pNew->pidl = pidl; 55 56 /*is This the first item in the list? */ 57 if (!mpFirst) 58 { 59 mpFirst = pNew; 60 mpCurrent = pNew; 61 } 62 63 if (mpLast) 64 { 65 /*add the new item to the end of the list */ 66 mpLast->pNext = pNew; 67 } 68 69 /*update the last item pointer */ 70 mpLast = pNew; 71 TRACE("-- (%p)->(first=%p, last=%p)\n", this, mpFirst, mpLast); 72 return TRUE; 73 } 74 return FALSE; 75} 76 77/************************************************************************** 78* DeleteList() 79*/ 80BOOL CEnumIDListBase::DeleteList() 81{ 82 ENUMLIST *pDelete; 83 84 TRACE("(%p)->()\n", this); 85 86 while (mpFirst) 87 { 88 pDelete = mpFirst; 89 mpFirst = pDelete->pNext; 90 SHFree(pDelete->pidl); 91 SHFree(pDelete); 92 } 93 mpFirst = NULL; 94 mpLast = NULL; 95 mpCurrent = NULL; 96 return TRUE; 97} 98 99HRESULT CEnumIDListBase::AppendItemsFromEnumerator(IEnumIDList* pEnum) 100{ 101 LPITEMIDLIST pidl; 102 DWORD dwFetched; 103 104 if (!pEnum) 105 return E_INVALIDARG; 106 107 pEnum->Reset(); 108 109 while((S_OK == pEnum->Next(1, &pidl, &dwFetched)) && dwFetched) 110 AddToEnumList(pidl); 111 112 return S_OK; 113} 114 115/************************************************************************** 116 * IEnumIDList_fnNext 117 */ 118 119HRESULT WINAPI CEnumIDListBase::Next( 120 ULONG celt, 121 LPITEMIDLIST * rgelt, 122 ULONG *pceltFetched) 123{ 124 ULONG i; 125 HRESULT hr = S_OK; 126 LPITEMIDLIST temp; 127 128 TRACE("(%p)->(%d,%p, %p)\n", this, celt, rgelt, pceltFetched); 129 130/* It is valid to leave pceltFetched NULL when celt is 1. Some of explorer's 131 * subsystems actually use it (and so may a third party browser) 132 */ 133 if(pceltFetched) 134 *pceltFetched = 0; 135 136 *rgelt=0; 137 138 if(celt > 1 && !pceltFetched) 139 { return E_INVALIDARG; 140 } 141 142 if(celt > 0 && !mpCurrent) 143 { return S_FALSE; 144 } 145 146 for(i = 0; i < celt; i++) 147 { if(!mpCurrent) 148 { hr = S_FALSE; 149 break; 150 } 151 152 temp = ILClone(mpCurrent->pidl); 153 if (!temp) 154 { hr = i ? S_FALSE : E_OUTOFMEMORY; 155 break; 156 } 157 rgelt[i] = temp; 158 mpCurrent = mpCurrent->pNext; 159 } 160 if(pceltFetched) 161 { *pceltFetched = i; 162 } 163 164 return hr; 165} 166 167/************************************************************************** 168* IEnumIDList_fnSkip 169*/ 170HRESULT WINAPI CEnumIDListBase::Skip( 171 ULONG celt) 172{ 173 DWORD dwIndex; 174 HRESULT hr = S_OK; 175 176 TRACE("(%p)->(%u)\n", this, celt); 177 178 for(dwIndex = 0; dwIndex < celt; dwIndex++) 179 { if(!mpCurrent) 180 { hr = S_FALSE; 181 break; 182 } 183 mpCurrent = mpCurrent->pNext; 184 } 185 return hr; 186} 187 188/************************************************************************** 189* IEnumIDList_fnReset 190*/ 191HRESULT WINAPI CEnumIDListBase::Reset() 192{ 193 TRACE("(%p)\n", this); 194 mpCurrent = mpFirst; 195 return S_OK; 196} 197 198/************************************************************************** 199* IEnumIDList_fnClone 200*/ 201HRESULT WINAPI CEnumIDListBase::Clone(LPENUMIDLIST *ppenum) 202{ 203 TRACE("(%p)->() to (%p)->() E_NOTIMPL\n", this, ppenum); 204 return E_NOTIMPL; 205} 206 207/************************************************************************** 208 * IEnumIDList_Folder_Constructor 209 * 210 */ 211HRESULT IEnumIDList_Constructor(IEnumIDList **enumerator) 212{ 213 return ShellObjectCreator<CEnumIDListBase>(IID_PPV_ARG(IEnumIDList, enumerator)); 214}