2 * Copyright 2014 Dmitry Timoshkov
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "taskschd_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(taskschd
);
36 ITaskFolderCollection ITaskFolderCollection_iface
;
41 } TaskFolderCollection
;
43 static HRESULT
NewEnum_create(TaskFolderCollection
*folders
, IUnknown
**obj
);
45 static inline TaskFolderCollection
*impl_from_ITaskFolderCollection(ITaskFolderCollection
*iface
)
47 return CONTAINING_RECORD(iface
, TaskFolderCollection
, ITaskFolderCollection_iface
);
50 static ULONG WINAPI
folders_AddRef(ITaskFolderCollection
*iface
)
52 TaskFolderCollection
*folders
= impl_from_ITaskFolderCollection(iface
);
53 return InterlockedIncrement(&folders
->ref
);
56 static void free_list(LPWSTR
*list
, DWORD count
)
60 for (i
= 0; i
< count
; i
++)
61 MIDL_user_free(list
[i
]);
66 static ULONG WINAPI
folders_Release(ITaskFolderCollection
*iface
)
68 TaskFolderCollection
*folders
= impl_from_ITaskFolderCollection(iface
);
69 LONG ref
= InterlockedDecrement(&folders
->ref
);
73 TRACE("destroying %p\n", iface
);
74 free_list(folders
->list
, folders
->count
);
75 heap_free(folders
->path
);
82 static HRESULT WINAPI
folders_QueryInterface(ITaskFolderCollection
*iface
, REFIID riid
, void **obj
)
84 if (!riid
|| !obj
) return E_INVALIDARG
;
86 TRACE("%p,%s,%p\n", iface
, debugstr_guid(riid
), obj
);
88 if (IsEqualGUID(riid
, &IID_ITaskFolderCollection
) ||
89 IsEqualGUID(riid
, &IID_IDispatch
) ||
90 IsEqualGUID(riid
, &IID_IUnknown
))
92 ITaskFolderCollection_AddRef(iface
);
97 FIXME("interface %s is not implemented\n", debugstr_guid(riid
));
102 static HRESULT WINAPI
folders_GetTypeInfoCount(ITaskFolderCollection
*iface
, UINT
*count
)
104 FIXME("%p,%p: stub\n", iface
, count
);
108 static HRESULT WINAPI
folders_GetTypeInfo(ITaskFolderCollection
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
110 FIXME("%p,%u,%u,%p: stub\n", iface
, index
, lcid
, info
);
114 static HRESULT WINAPI
folders_GetIDsOfNames(ITaskFolderCollection
*iface
, REFIID riid
, LPOLESTR
*names
,
115 UINT count
, LCID lcid
, DISPID
*dispid
)
117 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
121 static HRESULT WINAPI
folders_Invoke(ITaskFolderCollection
*iface
, DISPID dispid
, REFIID riid
, LCID lcid
, WORD flags
,
122 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*argerr
)
124 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface
, dispid
, debugstr_guid(riid
), lcid
, flags
,
125 params
, result
, excepinfo
, argerr
);
129 static HRESULT WINAPI
folders_get_Count(ITaskFolderCollection
*iface
, LONG
*count
)
131 TaskFolderCollection
*folders
= impl_from_ITaskFolderCollection(iface
);
133 TRACE("%p,%p\n", iface
, count
);
135 if (!count
) return E_POINTER
;
137 *count
= folders
->count
;
142 static LONG
get_var_int(const VARIANT
*var
)
167 FIXME("unsupported variant type %d\n", V_VT(var
));
172 static HRESULT WINAPI
folders_get_Item(ITaskFolderCollection
*iface
, VARIANT index
, ITaskFolder
**folder
)
174 TaskFolderCollection
*folders
= impl_from_ITaskFolderCollection(iface
);
177 TRACE("%p,%s,%p\n", iface
, debugstr_variant(&index
), folder
);
179 if (!folder
) return E_POINTER
;
181 if (V_VT(&index
) == VT_BSTR
)
182 return TaskFolder_create(folders
->path
, V_BSTR(&index
), folder
, FALSE
);
184 idx
= get_var_int(&index
);
185 /* collections are 1 based */
186 if (idx
< 1 || idx
> folders
->count
)
189 return TaskFolder_create(folders
->path
, folders
->list
[idx
- 1], folder
, FALSE
);
192 static HRESULT WINAPI
folders_get__NewEnum(ITaskFolderCollection
*iface
, IUnknown
**penum
)
194 TaskFolderCollection
*folders
= impl_from_ITaskFolderCollection(iface
);
196 TRACE("%p,%p\n", iface
, penum
);
198 if (!penum
) return E_POINTER
;
200 return NewEnum_create(folders
, penum
);
203 static const ITaskFolderCollectionVtbl TaskFolderCollection_vtbl
=
205 folders_QueryInterface
,
208 folders_GetTypeInfoCount
,
210 folders_GetIDsOfNames
,
217 HRESULT
TaskFolderCollection_create(const WCHAR
*path
, ITaskFolderCollection
**obj
)
219 TaskFolderCollection
*folders
;
222 DWORD start_index
, count
;
226 hr
= SchRpcEnumFolders(path
, 0, &start_index
, 0, &count
, &list
);
227 if (hr
!= S_OK
) return hr
;
229 folders
= heap_alloc(sizeof(*folders
));
232 free_list(list
, count
);
233 return E_OUTOFMEMORY
;
236 folders
->ITaskFolderCollection_iface
.lpVtbl
= &TaskFolderCollection_vtbl
;
238 if (!(folders
->path
= heap_strdupW(path
)))
241 free_list(list
, count
);
242 return E_OUTOFMEMORY
;
244 folders
->count
= count
;
245 folders
->list
= list
;
246 *obj
= &folders
->ITaskFolderCollection_iface
;
248 TRACE("created %p\n", *obj
);
255 IEnumVARIANT IEnumVARIANT_iface
;
257 TaskFolderCollection
*folders
;
260 static inline EnumVARIANT
*impl_from_IEnumVARIANT(IEnumVARIANT
*iface
)
262 return CONTAINING_RECORD(iface
, EnumVARIANT
, IEnumVARIANT_iface
);
265 static HRESULT WINAPI
enumvar_QueryInterface(IEnumVARIANT
*iface
, REFIID riid
, void **obj
)
267 if (!riid
|| !obj
) return E_INVALIDARG
;
269 TRACE("%p,%s,%p\n", iface
, debugstr_guid(riid
), obj
);
271 if (IsEqualGUID(riid
, &IID_IEnumVARIANT
) ||
272 IsEqualGUID(riid
, &IID_IUnknown
))
274 IEnumVARIANT_AddRef(iface
);
279 FIXME("interface %s is not implemented\n", debugstr_guid(riid
));
281 return E_NOINTERFACE
;
284 static ULONG WINAPI
enumvar_AddRef(IEnumVARIANT
*iface
)
286 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
287 return InterlockedIncrement(&enumvar
->ref
);
290 static ULONG WINAPI
enumvar_Release(IEnumVARIANT
*iface
)
292 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
293 LONG ref
= InterlockedDecrement(&enumvar
->ref
);
297 TRACE("destroying %p\n", iface
);
298 ITaskFolderCollection_Release(&enumvar
->folders
->ITaskFolderCollection_iface
);
305 static HRESULT WINAPI
enumvar_Next(IEnumVARIANT
*iface
, ULONG celt
, VARIANT
*var
, ULONG
*fetched
)
307 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
310 TRACE("%p,%u,%p,%p\n", iface
, celt
, var
, fetched
);
312 for (i
= 0; i
< celt
&& enumvar
->pos
< enumvar
->folders
->count
; i
++)
317 hr
= TaskFolder_create(enumvar
->folders
->path
, enumvar
->folders
->list
[enumvar
->pos
++], &folder
, FALSE
);
322 ITaskFolder_Release(folder
);
326 V_VT(&var
[i
]) = VT_DISPATCH
;
327 V_DISPATCH(&var
[i
]) = (IDispatch
*)folder
;
330 if (fetched
) *fetched
= i
;
332 return i
== celt
? S_OK
: S_FALSE
;
335 static HRESULT WINAPI
enumvar_Skip(IEnumVARIANT
*iface
, ULONG celt
)
337 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
339 TRACE("%p,%u\n", iface
, celt
);
341 enumvar
->pos
+= celt
;
343 if (enumvar
->pos
> enumvar
->folders
->count
)
345 enumvar
->pos
= enumvar
->folders
->count
;
352 static HRESULT WINAPI
enumvar_Reset(IEnumVARIANT
*iface
)
354 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
356 TRACE("%p\n", iface
);
363 static HRESULT WINAPI
enumvar_Clone(IEnumVARIANT
*iface
, IEnumVARIANT
**penum
)
365 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
367 TRACE("%p,%p\n", iface
, penum
);
369 return NewEnum_create(enumvar
->folders
, (IUnknown
**)penum
);
372 static const struct IEnumVARIANTVtbl EnumVARIANT_vtbl
=
374 enumvar_QueryInterface
,
383 static HRESULT
NewEnum_create(TaskFolderCollection
*folders
, IUnknown
**obj
)
385 EnumVARIANT
*enumvar
;
387 enumvar
= heap_alloc(sizeof(*enumvar
));
388 if (!enumvar
) return E_OUTOFMEMORY
;
390 enumvar
->IEnumVARIANT_iface
.lpVtbl
= &EnumVARIANT_vtbl
;
393 enumvar
->folders
= folders
;
394 ITaskFolderCollection_AddRef(&folders
->ITaskFolderCollection_iface
);
396 *obj
= (IUnknown
*)&enumvar
->IEnumVARIANT_iface
;
398 TRACE("created %p\n", *obj
);