xref: /reactos/dll/win32/mstask/task_scheduler.c (revision da50a61f)
1 /*
2  * Copyright (C) 2008 Google (Roy Shea)
3  *
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.
8  *
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.
13  *
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
17  */
18 
19 #include "corerror.h"
20 #include "mstask_private.h"
21 #include "wine/debug.h"
22 
23 WINE_DEFAULT_DEBUG_CHANNEL(mstask);
24 
25 typedef struct
26 {
27     ITaskScheduler ITaskScheduler_iface;
28     LONG ref;
29 } TaskSchedulerImpl;
30 
31 typedef struct
32 {
33     IEnumWorkItems IEnumWorkItems_iface;
34     LONG ref;
35 } EnumWorkItemsImpl;
36 
impl_from_ITaskScheduler(ITaskScheduler * iface)37 static inline TaskSchedulerImpl *impl_from_ITaskScheduler(ITaskScheduler *iface)
38 {
39     return CONTAINING_RECORD(iface, TaskSchedulerImpl, ITaskScheduler_iface);
40 }
41 
impl_from_IEnumWorkItems(IEnumWorkItems * iface)42 static inline EnumWorkItemsImpl *impl_from_IEnumWorkItems(IEnumWorkItems *iface)
43 {
44     return CONTAINING_RECORD(iface, EnumWorkItemsImpl, IEnumWorkItems_iface);
45 }
46 
TaskSchedulerDestructor(TaskSchedulerImpl * This)47 static void TaskSchedulerDestructor(TaskSchedulerImpl *This)
48 {
49     TRACE("%p\n", This);
50     HeapFree(GetProcessHeap(), 0, This);
51     InterlockedDecrement(&dll_ref);
52 }
53 
EnumWorkItems_QueryInterface(IEnumWorkItems * iface,REFIID riid,void ** obj)54 static HRESULT WINAPI EnumWorkItems_QueryInterface(IEnumWorkItems *iface, REFIID riid, void **obj)
55 {
56     EnumWorkItemsImpl *This = impl_from_IEnumWorkItems(iface);
57 
58     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
59 
60     if (IsEqualGUID(riid, &IID_IEnumWorkItems) || IsEqualGUID(riid, &IID_IUnknown))
61     {
62         *obj = &This->IEnumWorkItems_iface;
63         IEnumWorkItems_AddRef(iface);
64         return S_OK;
65     }
66 
67     *obj = NULL;
68     return E_NOINTERFACE;
69 }
70 
EnumWorkItems_AddRef(IEnumWorkItems * iface)71 static ULONG WINAPI EnumWorkItems_AddRef(IEnumWorkItems *iface)
72 {
73     EnumWorkItemsImpl *This = impl_from_IEnumWorkItems(iface);
74     ULONG ref = InterlockedIncrement(&This->ref);
75     TRACE("(%p)->(%u)\n", This, ref);
76     return ref;
77 }
78 
EnumWorkItems_Release(IEnumWorkItems * iface)79 static ULONG WINAPI EnumWorkItems_Release(IEnumWorkItems *iface)
80 {
81     EnumWorkItemsImpl *This = impl_from_IEnumWorkItems(iface);
82     ULONG ref = InterlockedDecrement(&This->ref);
83 
84     TRACE("(%p)->(%u)\n", This, ref);
85 
86     if (ref == 0)
87     {
88         HeapFree(GetProcessHeap(), 0, This);
89         InterlockedDecrement(&dll_ref);
90     }
91 
92     return ref;
93 }
94 
EnumWorkItems_Next(IEnumWorkItems * iface,ULONG count,LPWSTR ** names,ULONG * fetched)95 static HRESULT WINAPI EnumWorkItems_Next(IEnumWorkItems *iface, ULONG count, LPWSTR **names, ULONG *fetched)
96 {
97     EnumWorkItemsImpl *This = impl_from_IEnumWorkItems(iface);
98     FIXME("(%p)->(%u %p %p): stub\n", This, count, names, fetched);
99     return E_NOTIMPL;
100 }
101 
EnumWorkItems_Skip(IEnumWorkItems * iface,ULONG count)102 static HRESULT WINAPI EnumWorkItems_Skip(IEnumWorkItems *iface, ULONG count)
103 {
104     EnumWorkItemsImpl *This = impl_from_IEnumWorkItems(iface);
105     FIXME("(%p)->(%u): stub\n", This, count);
106     return E_NOTIMPL;
107 }
108 
EnumWorkItems_Reset(IEnumWorkItems * iface)109 static HRESULT WINAPI EnumWorkItems_Reset(IEnumWorkItems *iface)
110 {
111     EnumWorkItemsImpl *This = impl_from_IEnumWorkItems(iface);
112     FIXME("(%p): stub\n", This);
113     return E_NOTIMPL;
114 }
115 
EnumWorkItems_Clone(IEnumWorkItems * iface,IEnumWorkItems ** cloned)116 static HRESULT WINAPI EnumWorkItems_Clone(IEnumWorkItems *iface, IEnumWorkItems **cloned)
117 {
118     EnumWorkItemsImpl *This = impl_from_IEnumWorkItems(iface);
119     FIXME("(%p)->(%p): stub\n", This, cloned);
120     return E_NOTIMPL;
121 }
122 
123 static const IEnumWorkItemsVtbl EnumWorkItemsVtbl = {
124     EnumWorkItems_QueryInterface,
125     EnumWorkItems_AddRef,
126     EnumWorkItems_Release,
127     EnumWorkItems_Next,
128     EnumWorkItems_Skip,
129     EnumWorkItems_Reset,
130     EnumWorkItems_Clone
131 };
132 
create_task_enum(IEnumWorkItems ** ret)133 static HRESULT create_task_enum(IEnumWorkItems **ret)
134 {
135     EnumWorkItemsImpl *tasks;
136 
137     *ret = NULL;
138 
139     tasks = HeapAlloc(GetProcessHeap(), 0, sizeof(*tasks));
140     if (!tasks)
141         return E_OUTOFMEMORY;
142 
143     tasks->IEnumWorkItems_iface.lpVtbl = &EnumWorkItemsVtbl;
144     tasks->ref = 1;
145 
146     *ret = &tasks->IEnumWorkItems_iface;
147     InterlockedIncrement(&dll_ref);
148     return S_OK;
149 }
150 
MSTASK_ITaskScheduler_QueryInterface(ITaskScheduler * iface,REFIID riid,void ** ppvObject)151 static HRESULT WINAPI MSTASK_ITaskScheduler_QueryInterface(
152         ITaskScheduler* iface,
153         REFIID riid,
154         void **ppvObject)
155 {
156     TaskSchedulerImpl * This = impl_from_ITaskScheduler(iface);
157 
158     TRACE("IID: %s\n", debugstr_guid(riid));
159 
160     if (IsEqualGUID(riid, &IID_IUnknown) ||
161             IsEqualGUID(riid, &IID_ITaskScheduler))
162     {
163         *ppvObject = &This->ITaskScheduler_iface;
164         ITaskScheduler_AddRef(iface);
165         return S_OK;
166     }
167 
168     *ppvObject = NULL;
169     return E_NOINTERFACE;
170 }
171 
MSTASK_ITaskScheduler_AddRef(ITaskScheduler * iface)172 static ULONG WINAPI MSTASK_ITaskScheduler_AddRef(
173         ITaskScheduler* iface)
174 {
175     TaskSchedulerImpl *This = impl_from_ITaskScheduler(iface);
176     TRACE("\n");
177     return InterlockedIncrement(&This->ref);
178 }
179 
MSTASK_ITaskScheduler_Release(ITaskScheduler * iface)180 static ULONG WINAPI MSTASK_ITaskScheduler_Release(
181         ITaskScheduler* iface)
182 {
183     TaskSchedulerImpl * This = impl_from_ITaskScheduler(iface);
184     ULONG ref;
185     TRACE("\n");
186     ref = InterlockedDecrement(&This->ref);
187     if (ref == 0)
188         TaskSchedulerDestructor(This);
189     return ref;
190 }
191 
MSTASK_ITaskScheduler_SetTargetComputer(ITaskScheduler * iface,LPCWSTR pwszComputer)192 static HRESULT WINAPI MSTASK_ITaskScheduler_SetTargetComputer(
193         ITaskScheduler* iface,
194         LPCWSTR pwszComputer)
195 {
196     TaskSchedulerImpl *This = impl_from_ITaskScheduler(iface);
197     WCHAR buffer[MAX_COMPUTERNAME_LENGTH + 3];  /* extra space for two '\' and a zero */
198     DWORD len = MAX_COMPUTERNAME_LENGTH + 1;    /* extra space for a zero */
199 
200     TRACE("(%p)->(%s)\n", This, debugstr_w(pwszComputer));
201 
202     /* NULL is an alias for the local computer */
203     if (!pwszComputer)
204         return S_OK;
205 
206     buffer[0] = '\\';
207     buffer[1] = '\\';
208     if (GetComputerNameW(buffer + 2, &len))
209     {
210         if (!lstrcmpiW(buffer, pwszComputer) ||    /* full unc name */
211             !lstrcmpiW(buffer + 2, pwszComputer))  /* name without backslash */
212             return S_OK;
213     }
214 
215     FIXME("remote computer %s not supported\n", debugstr_w(pwszComputer));
216     return HRESULT_FROM_WIN32(ERROR_BAD_NETPATH);
217 }
218 
MSTASK_ITaskScheduler_GetTargetComputer(ITaskScheduler * iface,LPWSTR * ppwszComputer)219 static HRESULT WINAPI MSTASK_ITaskScheduler_GetTargetComputer(
220         ITaskScheduler* iface,
221         LPWSTR *ppwszComputer)
222 {
223     TaskSchedulerImpl *This = impl_from_ITaskScheduler(iface);
224     LPWSTR buffer;
225     DWORD len = MAX_COMPUTERNAME_LENGTH + 1; /* extra space for the zero */
226 
227     TRACE("(%p)->(%p)\n", This, ppwszComputer);
228 
229     if (!ppwszComputer)
230         return E_INVALIDARG;
231 
232     /* extra space for two '\' and a zero */
233     buffer = CoTaskMemAlloc((MAX_COMPUTERNAME_LENGTH + 3) * sizeof(WCHAR));
234     if (buffer)
235     {
236         buffer[0] = '\\';
237         buffer[1] = '\\';
238         if (GetComputerNameW(buffer + 2, &len))
239         {
240             *ppwszComputer = buffer;
241             return S_OK;
242         }
243         CoTaskMemFree(buffer);
244     }
245     *ppwszComputer = NULL;
246     return HRESULT_FROM_WIN32(GetLastError());
247 }
248 
MSTASK_ITaskScheduler_Enum(ITaskScheduler * iface,IEnumWorkItems ** tasks)249 static HRESULT WINAPI MSTASK_ITaskScheduler_Enum(
250         ITaskScheduler* iface,
251         IEnumWorkItems **tasks)
252 {
253     TaskSchedulerImpl *This = impl_from_ITaskScheduler(iface);
254 
255     TRACE("(%p)->(%p)\n", This, tasks);
256 
257     if (!tasks)
258         return E_INVALIDARG;
259 
260     return create_task_enum(tasks);
261 }
262 
MSTASK_ITaskScheduler_Activate(ITaskScheduler * iface,LPCWSTR pwszName,REFIID riid,IUnknown ** ppunk)263 static HRESULT WINAPI MSTASK_ITaskScheduler_Activate(
264         ITaskScheduler* iface,
265         LPCWSTR pwszName,
266         REFIID riid,
267         IUnknown **ppunk)
268 {
269     TRACE("%p, %s, %s, %p: stub\n", iface, debugstr_w(pwszName),
270             debugstr_guid(riid), ppunk);
271     FIXME("Partial stub always returning COR_E_FILENOTFOUND\n");
272     return COR_E_FILENOTFOUND;
273 }
274 
MSTASK_ITaskScheduler_Delete(ITaskScheduler * iface,LPCWSTR pwszName)275 static HRESULT WINAPI MSTASK_ITaskScheduler_Delete(
276         ITaskScheduler* iface,
277         LPCWSTR pwszName)
278 {
279     FIXME("%p, %s: stub\n", iface, debugstr_w(pwszName));
280     return E_NOTIMPL;
281 }
282 
MSTASK_ITaskScheduler_NewWorkItem(ITaskScheduler * iface,LPCWSTR pwszTaskName,REFCLSID rclsid,REFIID riid,IUnknown ** ppunk)283 static HRESULT WINAPI MSTASK_ITaskScheduler_NewWorkItem(
284         ITaskScheduler* iface,
285         LPCWSTR pwszTaskName,
286         REFCLSID rclsid,
287         REFIID riid,
288         IUnknown **ppunk)
289 {
290     HRESULT hr;
291     TRACE("(%p, %s, %s, %s, %p)\n", iface, debugstr_w(pwszTaskName),
292             debugstr_guid(rclsid) ,debugstr_guid(riid),  ppunk);
293 
294     if (!IsEqualGUID(rclsid, &CLSID_CTask))
295         return CLASS_E_CLASSNOTAVAILABLE;
296 
297     if (!IsEqualGUID(riid, &IID_ITask))
298         return E_NOINTERFACE;
299 
300     hr = TaskConstructor(pwszTaskName, (LPVOID *)ppunk);
301     return hr;
302 }
303 
MSTASK_ITaskScheduler_AddWorkItem(ITaskScheduler * iface,LPCWSTR pwszTaskName,IScheduledWorkItem * pWorkItem)304 static HRESULT WINAPI MSTASK_ITaskScheduler_AddWorkItem(
305         ITaskScheduler* iface,
306         LPCWSTR pwszTaskName,
307         IScheduledWorkItem *pWorkItem)
308 {
309     FIXME("%p, %s, %p: stub\n", iface, debugstr_w(pwszTaskName), pWorkItem);
310     return E_NOTIMPL;
311 }
312 
MSTASK_ITaskScheduler_IsOfType(ITaskScheduler * iface,LPCWSTR pwszName,REFIID riid)313 static HRESULT WINAPI MSTASK_ITaskScheduler_IsOfType(
314         ITaskScheduler* iface,
315         LPCWSTR pwszName,
316         REFIID riid)
317 {
318     FIXME("%p, %s, %s: stub\n", iface, debugstr_w(pwszName),
319             debugstr_guid(riid));
320     return E_NOTIMPL;
321 }
322 
323 static const ITaskSchedulerVtbl MSTASK_ITaskSchedulerVtbl =
324 {
325     MSTASK_ITaskScheduler_QueryInterface,
326     MSTASK_ITaskScheduler_AddRef,
327     MSTASK_ITaskScheduler_Release,
328     MSTASK_ITaskScheduler_SetTargetComputer,
329     MSTASK_ITaskScheduler_GetTargetComputer,
330     MSTASK_ITaskScheduler_Enum,
331     MSTASK_ITaskScheduler_Activate,
332     MSTASK_ITaskScheduler_Delete,
333     MSTASK_ITaskScheduler_NewWorkItem,
334     MSTASK_ITaskScheduler_AddWorkItem,
335     MSTASK_ITaskScheduler_IsOfType
336 };
337 
TaskSchedulerConstructor(LPVOID * ppObj)338 HRESULT TaskSchedulerConstructor(LPVOID *ppObj)
339 {
340     TaskSchedulerImpl *This;
341     TRACE("(%p)\n", ppObj);
342 
343     This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
344     if (!This)
345         return E_OUTOFMEMORY;
346 
347     This->ITaskScheduler_iface.lpVtbl = &MSTASK_ITaskSchedulerVtbl;
348     This->ref = 1;
349 
350     *ppObj = &This->ITaskScheduler_iface;
351     InterlockedIncrement(&dll_ref);
352     return S_OK;
353 }
354