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/unicode.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(taskschd
);
37 ITaskFolderCollection ITaskFolderCollection_iface
;
42 } TaskFolderCollection
;
44 static HRESULT
NewEnum_create(TaskFolderCollection
*folders
, IUnknown
**obj
);
46 static inline TaskFolderCollection
*impl_from_ITaskFolderCollection(ITaskFolderCollection
*iface
)
48 return CONTAINING_RECORD(iface
, TaskFolderCollection
, ITaskFolderCollection_iface
);
51 static ULONG WINAPI
folders_AddRef(ITaskFolderCollection
*iface
)
53 TaskFolderCollection
*folders
= impl_from_ITaskFolderCollection(iface
);
54 return InterlockedIncrement(&folders
->ref
);
57 static void free_list(LPWSTR
*list
, DWORD count
)
61 for (i
= 0; i
< count
; i
++)
62 MIDL_user_free(list
[i
]);
67 static ULONG WINAPI
folders_Release(ITaskFolderCollection
*iface
)
69 TaskFolderCollection
*folders
= impl_from_ITaskFolderCollection(iface
);
70 LONG ref
= InterlockedDecrement(&folders
->ref
);
74 TRACE("destroying %p\n", iface
);
75 free_list(folders
->list
, folders
->count
);
76 heap_free(folders
->path
);
83 static HRESULT WINAPI
folders_QueryInterface(ITaskFolderCollection
*iface
, REFIID riid
, void **obj
)
85 if (!riid
|| !obj
) return E_INVALIDARG
;
87 TRACE("%p,%s,%p\n", iface
, debugstr_guid(riid
), obj
);
89 if (IsEqualGUID(riid
, &IID_ITaskFolderCollection
) ||
90 IsEqualGUID(riid
, &IID_IDispatch
) ||
91 IsEqualGUID(riid
, &IID_IUnknown
))
93 ITaskFolderCollection_AddRef(iface
);
98 FIXME("interface %s is not implemented\n", debugstr_guid(riid
));
100 return E_NOINTERFACE
;
103 static HRESULT WINAPI
folders_GetTypeInfoCount(ITaskFolderCollection
*iface
, UINT
*count
)
105 FIXME("%p,%p: stub\n", iface
, count
);
109 static HRESULT WINAPI
folders_GetTypeInfo(ITaskFolderCollection
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
111 FIXME("%p,%u,%u,%p: stub\n", iface
, index
, lcid
, info
);
115 static HRESULT WINAPI
folders_GetIDsOfNames(ITaskFolderCollection
*iface
, REFIID riid
, LPOLESTR
*names
,
116 UINT count
, LCID lcid
, DISPID
*dispid
)
118 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
122 static HRESULT WINAPI
folders_Invoke(ITaskFolderCollection
*iface
, DISPID dispid
, REFIID riid
, LCID lcid
, WORD flags
,
123 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*argerr
)
125 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface
, dispid
, debugstr_guid(riid
), lcid
, flags
,
126 params
, result
, excepinfo
, argerr
);
130 static HRESULT WINAPI
folders_get_Count(ITaskFolderCollection
*iface
, LONG
*count
)
132 TaskFolderCollection
*folders
= impl_from_ITaskFolderCollection(iface
);
134 TRACE("%p,%p\n", iface
, count
);
136 if (!count
) return E_POINTER
;
138 *count
= folders
->count
;
143 static LONG
get_var_int(const VARIANT
*var
)
168 FIXME("unsupported variant type %d\n", V_VT(var
));
173 static HRESULT WINAPI
folders_get_Item(ITaskFolderCollection
*iface
, VARIANT index
, ITaskFolder
**folder
)
175 TaskFolderCollection
*folders
= impl_from_ITaskFolderCollection(iface
);
178 TRACE("%p,%s,%p\n", iface
, debugstr_variant(&index
), folder
);
180 if (!folder
) return E_POINTER
;
182 if (V_VT(&index
) == VT_BSTR
)
183 return TaskFolder_create(folders
->path
, V_BSTR(&index
), folder
, FALSE
);
185 idx
= get_var_int(&index
);
186 /* collections are 1 based */
187 if (idx
< 1 || idx
> folders
->count
)
190 return TaskFolder_create(folders
->path
, folders
->list
[idx
- 1], folder
, FALSE
);
193 static HRESULT WINAPI
folders_get__NewEnum(ITaskFolderCollection
*iface
, IUnknown
**penum
)
195 TaskFolderCollection
*folders
= impl_from_ITaskFolderCollection(iface
);
197 TRACE("%p,%p\n", iface
, penum
);
199 if (!penum
) return E_POINTER
;
201 return NewEnum_create(folders
, penum
);
204 static const ITaskFolderCollectionVtbl TaskFolderCollection_vtbl
=
206 folders_QueryInterface
,
209 folders_GetTypeInfoCount
,
211 folders_GetIDsOfNames
,
218 HRESULT
TaskFolderCollection_create(const WCHAR
*path
, ITaskFolderCollection
**obj
)
220 TaskFolderCollection
*folders
;
223 DWORD start_index
, count
;
227 hr
= SchRpcEnumFolders(path
, 0, &start_index
, 0, &count
, &list
);
228 if (hr
!= S_OK
) return hr
;
230 folders
= heap_alloc(sizeof(*folders
));
233 free_list(list
, count
);
234 return E_OUTOFMEMORY
;
237 folders
->ITaskFolderCollection_iface
.lpVtbl
= &TaskFolderCollection_vtbl
;
239 folders
->path
= heap_strdupW(path
);
240 folders
->count
= count
;
241 folders
->list
= list
;
242 *obj
= &folders
->ITaskFolderCollection_iface
;
244 TRACE("created %p\n", *obj
);
251 IEnumVARIANT IEnumVARIANT_iface
;
253 TaskFolderCollection
*folders
;
256 static inline EnumVARIANT
*impl_from_IEnumVARIANT(IEnumVARIANT
*iface
)
258 return CONTAINING_RECORD(iface
, EnumVARIANT
, IEnumVARIANT_iface
);
261 static HRESULT WINAPI
enumvar_QueryInterface(IEnumVARIANT
*iface
, REFIID riid
, void **obj
)
263 if (!riid
|| !obj
) return E_INVALIDARG
;
265 TRACE("%p,%s,%p\n", iface
, debugstr_guid(riid
), obj
);
267 if (IsEqualGUID(riid
, &IID_IEnumVARIANT
) ||
268 IsEqualGUID(riid
, &IID_IUnknown
))
270 IEnumVARIANT_AddRef(iface
);
275 FIXME("interface %s is not implemented\n", debugstr_guid(riid
));
277 return E_NOINTERFACE
;
280 static ULONG WINAPI
enumvar_AddRef(IEnumVARIANT
*iface
)
282 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
283 return InterlockedIncrement(&enumvar
->ref
);
286 static ULONG WINAPI
enumvar_Release(IEnumVARIANT
*iface
)
288 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
289 LONG ref
= InterlockedDecrement(&enumvar
->ref
);
293 TRACE("destroying %p\n", iface
);
294 ITaskFolderCollection_Release(&enumvar
->folders
->ITaskFolderCollection_iface
);
301 static HRESULT WINAPI
enumvar_Next(IEnumVARIANT
*iface
, ULONG celt
, VARIANT
*var
, ULONG
*fetched
)
303 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
306 TRACE("%p,%u,%p,%p\n", iface
, celt
, var
, fetched
);
308 for (i
= 0; i
< celt
&& enumvar
->pos
< enumvar
->folders
->count
; i
++)
313 hr
= TaskFolder_create(enumvar
->folders
->path
, enumvar
->folders
->list
[enumvar
->pos
++], &folder
, FALSE
);
318 ITaskFolder_Release(folder
);
322 V_VT(&var
[i
]) = VT_DISPATCH
;
323 V_DISPATCH(&var
[i
]) = (IDispatch
*)folder
;
326 if (fetched
) *fetched
= i
;
328 return i
== celt
? S_OK
: S_FALSE
;
331 static HRESULT WINAPI
enumvar_Skip(IEnumVARIANT
*iface
, ULONG celt
)
333 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
335 TRACE("%p,%u\n", iface
, celt
);
337 enumvar
->pos
+= celt
;
339 if (enumvar
->pos
> enumvar
->folders
->count
)
341 enumvar
->pos
= enumvar
->folders
->count
;
348 static HRESULT WINAPI
enumvar_Reset(IEnumVARIANT
*iface
)
350 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
352 TRACE("%p\n", iface
);
359 static HRESULT WINAPI
enumvar_Clone(IEnumVARIANT
*iface
, IEnumVARIANT
**penum
)
361 EnumVARIANT
*enumvar
= impl_from_IEnumVARIANT(iface
);
363 TRACE("%p,%p\n", iface
, penum
);
365 return NewEnum_create(enumvar
->folders
, (IUnknown
**)penum
);
368 static const struct IEnumVARIANTVtbl EnumVARIANT_vtbl
=
370 enumvar_QueryInterface
,
379 static HRESULT
NewEnum_create(TaskFolderCollection
*folders
, IUnknown
**obj
)
381 EnumVARIANT
*enumvar
;
383 enumvar
= heap_alloc(sizeof(*enumvar
));
384 if (!enumvar
) return E_OUTOFMEMORY
;
386 enumvar
->IEnumVARIANT_iface
.lpVtbl
= &EnumVARIANT_vtbl
;
389 enumvar
->folders
= folders
;
390 ITaskFolderCollection_AddRef(&folders
->ITaskFolderCollection_iface
);
392 *obj
= (IUnknown
*)&enumvar
->IEnumVARIANT_iface
;
394 TRACE("created %p\n", *obj
);