dmusic: Avoid swallowing collection Load failures.
[wine.git] / dlls / qmgr / enum_files.c
bloba7a26da60c9c5b7a01656bcb93b1d3225ac1dd03
1 /*
2 * Queue Manager (BITS) File Enumerator
4 * Copyright 2007, 2008 Google (Roy Shea, Dan Hipschman)
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.
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.
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
21 #include "qmgr.h"
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(qmgr);
26 typedef struct
28 IEnumBackgroundCopyFiles IEnumBackgroundCopyFiles_iface;
29 LONG ref;
30 IBackgroundCopyFile2 **files;
31 ULONG numFiles;
32 ULONG indexFiles;
33 } EnumBackgroundCopyFilesImpl;
35 static inline EnumBackgroundCopyFilesImpl *impl_from_IEnumBackgroundCopyFiles(IEnumBackgroundCopyFiles *iface)
37 return CONTAINING_RECORD(iface, EnumBackgroundCopyFilesImpl, IEnumBackgroundCopyFiles_iface);
40 static HRESULT WINAPI EnumBackgroundCopyFiles_QueryInterface(IEnumBackgroundCopyFiles *iface,
41 REFIID riid, void **ppv)
43 EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface);
45 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
47 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumBackgroundCopyFiles))
49 *ppv = iface;
50 IEnumBackgroundCopyFiles_AddRef(iface);
51 return S_OK;
54 *ppv = NULL;
55 return E_NOINTERFACE;
58 static ULONG WINAPI EnumBackgroundCopyFiles_AddRef(IEnumBackgroundCopyFiles *iface)
60 EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface);
61 ULONG ref = InterlockedIncrement(&This->ref);
63 TRACE("(%p)->(%ld)\n", This, ref);
64 return ref;
67 static ULONG WINAPI EnumBackgroundCopyFiles_Release(IEnumBackgroundCopyFiles *iface)
69 EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface);
70 ULONG ref = InterlockedDecrement(&This->ref);
71 ULONG i;
73 TRACE("(%p)->(%ld)\n", This, ref);
75 if (ref == 0)
77 for(i = 0; i < This->numFiles; i++)
78 IBackgroundCopyFile2_Release(This->files[i]);
79 free(This->files);
80 free(This);
83 return ref;
86 /* Return reference to one or more files in the file enumerator */
87 static HRESULT WINAPI EnumBackgroundCopyFiles_Next(IEnumBackgroundCopyFiles *iface,
88 ULONG celt, IBackgroundCopyFile **rgelt, ULONG *pceltFetched)
90 EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface);
91 ULONG fetched;
92 ULONG i;
93 IBackgroundCopyFile2 *file;
95 TRACE("(%p)->(%ld %p %p)\n", This, celt, rgelt, pceltFetched);
97 /* Despite documented behavior, Windows (tested on XP) is not verifying
98 that the caller set pceltFetched to zero. No check here. */
100 fetched = min(celt, This->numFiles - This->indexFiles);
101 if (pceltFetched)
102 *pceltFetched = fetched;
103 else
105 /* We need to initialize this array if the caller doesn't request
106 the length because length_is will default to celt. */
107 for (i = 0; i < celt; i++)
108 rgelt[i] = NULL;
110 /* pceltFetched can only be NULL if celt is 1 */
111 if (celt != 1)
112 return E_INVALIDARG;
115 /* Fill in the array of objects */
116 for (i = 0; i < fetched; i++)
118 file = This->files[This->indexFiles++];
119 IBackgroundCopyFile2_AddRef(file);
120 rgelt[i] = (IBackgroundCopyFile *)file;
123 return fetched == celt ? S_OK : S_FALSE;
126 /* Skip over one or more files in the file enumerator */
127 static HRESULT WINAPI EnumBackgroundCopyFiles_Skip(IEnumBackgroundCopyFiles *iface,
128 ULONG celt)
130 EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface);
132 TRACE("(%p)->(%ld)\n", This, celt);
134 if (celt > This->numFiles - This->indexFiles)
136 This->indexFiles = This->numFiles;
137 return S_FALSE;
140 This->indexFiles += celt;
141 return S_OK;
144 static HRESULT WINAPI EnumBackgroundCopyFiles_Reset(IEnumBackgroundCopyFiles *iface)
146 EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface);
148 TRACE("(%p)\n", This);
150 This->indexFiles = 0;
151 return S_OK;
154 static HRESULT WINAPI EnumBackgroundCopyFiles_Clone(IEnumBackgroundCopyFiles *iface,
155 IEnumBackgroundCopyFiles **ppenum)
157 EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface);
158 FIXME("(%p)->(%p): stub\n", This, ppenum);
159 return E_NOTIMPL;
162 static HRESULT WINAPI EnumBackgroundCopyFiles_GetCount(IEnumBackgroundCopyFiles *iface,
163 ULONG *puCount)
165 EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface);
166 TRACE("(%p)->(%p)\n", This, puCount);
167 *puCount = This->numFiles;
168 return S_OK;
171 static const IEnumBackgroundCopyFilesVtbl EnumBackgroundCopyFilesVtbl =
173 EnumBackgroundCopyFiles_QueryInterface,
174 EnumBackgroundCopyFiles_AddRef,
175 EnumBackgroundCopyFiles_Release,
176 EnumBackgroundCopyFiles_Next,
177 EnumBackgroundCopyFiles_Skip,
178 EnumBackgroundCopyFiles_Reset,
179 EnumBackgroundCopyFiles_Clone,
180 EnumBackgroundCopyFiles_GetCount
183 HRESULT EnumBackgroundCopyFilesConstructor(BackgroundCopyJobImpl *job, IEnumBackgroundCopyFiles **enum_files)
185 EnumBackgroundCopyFilesImpl *This;
186 BackgroundCopyFileImpl *file;
187 ULONG i;
189 TRACE("%p, %p)\n", job, enum_files);
191 This = malloc(sizeof(*This));
192 if (!This)
193 return E_OUTOFMEMORY;
195 This->IEnumBackgroundCopyFiles_iface.lpVtbl = &EnumBackgroundCopyFilesVtbl;
196 This->ref = 1;
198 /* Create array of files */
199 This->indexFiles = 0;
200 EnterCriticalSection(&job->cs);
201 This->numFiles = list_count(&job->files);
202 This->files = NULL;
203 if (This->numFiles > 0)
205 This->files = malloc(This->numFiles * sizeof This->files[0]);
206 if (!This->files)
208 LeaveCriticalSection(&job->cs);
209 free(This);
210 return E_OUTOFMEMORY;
214 i = 0;
215 LIST_FOR_EACH_ENTRY(file, &job->files, BackgroundCopyFileImpl, entryFromJob)
217 IBackgroundCopyFile2_AddRef(&file->IBackgroundCopyFile2_iface);
218 This->files[i] = &file->IBackgroundCopyFile2_iface;
219 ++i;
221 LeaveCriticalSection(&job->cs);
223 *enum_files = &This->IEnumBackgroundCopyFiles_iface;
224 return S_OK;