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
);
35 static const char root
[] = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Schedule\\TaskCache\\Tree";
39 ITaskFolder ITaskFolder_iface
;
44 static inline TaskFolder
*impl_from_ITaskFolder(ITaskFolder
*iface
)
46 return CONTAINING_RECORD(iface
, TaskFolder
, ITaskFolder_iface
);
49 static ULONG WINAPI
TaskFolder_AddRef(ITaskFolder
*iface
)
51 TaskFolder
*folder
= impl_from_ITaskFolder(iface
);
52 return InterlockedIncrement(&folder
->ref
);
55 static ULONG WINAPI
TaskFolder_Release(ITaskFolder
*iface
)
57 TaskFolder
*folder
= impl_from_ITaskFolder(iface
);
58 LONG ref
= InterlockedDecrement(&folder
->ref
);
62 TRACE("destroying %p\n", iface
);
63 HeapFree(GetProcessHeap(), 0, folder
->path
);
64 HeapFree(GetProcessHeap(), 0, folder
);
70 static HRESULT WINAPI
TaskFolder_QueryInterface(ITaskFolder
*iface
, REFIID riid
, void **obj
)
72 if (!riid
|| !obj
) return E_INVALIDARG
;
74 TRACE("%p,%s,%p\n", iface
, debugstr_guid(riid
), obj
);
76 if (IsEqualGUID(riid
, &IID_ITaskFolder
) ||
77 IsEqualGUID(riid
, &IID_IDispatch
) ||
78 IsEqualGUID(riid
, &IID_IUnknown
))
80 ITaskFolder_AddRef(iface
);
85 FIXME("interface %s is not implemented\n", debugstr_guid(riid
));
89 static HRESULT WINAPI
TaskFolder_GetTypeInfoCount(ITaskFolder
*iface
, UINT
*count
)
91 FIXME("%p,%p: stub\n", iface
, count
);
95 static HRESULT WINAPI
TaskFolder_GetTypeInfo(ITaskFolder
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
97 FIXME("%p,%u,%u,%p: stub\n", iface
, index
, lcid
, info
);
101 static HRESULT WINAPI
TaskFolder_GetIDsOfNames(ITaskFolder
*iface
, REFIID riid
, LPOLESTR
*names
,
102 UINT count
, LCID lcid
, DISPID
*dispid
)
104 FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
108 static HRESULT WINAPI
TaskFolder_Invoke(ITaskFolder
*iface
, DISPID dispid
, REFIID riid
, LCID lcid
, WORD flags
,
109 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*argerr
)
111 FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface
, dispid
, debugstr_guid(riid
), lcid
, flags
,
112 params
, result
, excepinfo
, argerr
);
116 static HRESULT WINAPI
TaskFolder_get_Name(ITaskFolder
*iface
, BSTR
*name
)
118 FIXME("%p,%p: stub\n", iface
, name
);
122 static HRESULT
reg_open_folder(const WCHAR
*path
, HKEY
*hfolder
)
127 ret
= RegCreateKeyA(HKEY_LOCAL_MACHINE
, root
, &hroot
);
128 if (ret
) return HRESULT_FROM_WIN32(ret
);
130 while (*path
== '\\') path
++;
131 ret
= RegOpenKeyExW(hroot
, path
, 0, KEY_ALL_ACCESS
, hfolder
);
132 if (ret
== ERROR_FILE_NOT_FOUND
)
133 ret
= ERROR_PATH_NOT_FOUND
;
137 return HRESULT_FROM_WIN32(ret
);
140 static inline void reg_close_folder(HKEY hfolder
)
142 RegCloseKey(hfolder
);
145 static HRESULT WINAPI
TaskFolder_get_Path(ITaskFolder
*iface
, BSTR
*path
)
147 TaskFolder
*folder
= impl_from_ITaskFolder(iface
);
149 TRACE("%p,%p\n", iface
, path
);
151 if (!path
) return E_POINTER
;
153 *path
= SysAllocString(folder
->path
);
154 if (!*path
) return E_OUTOFMEMORY
;
159 static HRESULT WINAPI
TaskFolder_GetFolder(ITaskFolder
*iface
, BSTR path
, ITaskFolder
**folder
)
161 FIXME("%p,%s,%p: stub\n", iface
, debugstr_w(path
), folder
);
165 static HRESULT WINAPI
TaskFolder_GetFolders(ITaskFolder
*iface
, LONG flags
, ITaskFolderCollection
**folders
)
167 FIXME("%p,%x,%p: stub\n", iface
, flags
, folders
);
171 static HRESULT WINAPI
TaskFolder_CreateFolder(ITaskFolder
*iface
, BSTR name
, VARIANT sddl
, ITaskFolder
**folder
)
173 FIXME("%p,%s,%s,%p: stub\n", iface
, debugstr_w(name
), debugstr_variant(&sddl
), folder
);
177 static HRESULT WINAPI
TaskFolder_DeleteFolder(ITaskFolder
*iface
, BSTR name
, LONG flags
)
179 FIXME("%p,%s,%x: stub\n", iface
, debugstr_w(name
), flags
);
183 static HRESULT WINAPI
TaskFolder_GetTask(ITaskFolder
*iface
, BSTR path
, IRegisteredTask
**task
)
185 FIXME("%p,%s,%p: stub\n", iface
, debugstr_w(path
), task
);
189 static HRESULT WINAPI
TaskFolder_GetTasks(ITaskFolder
*iface
, LONG flags
, IRegisteredTaskCollection
**tasks
)
191 FIXME("%p,%x,%p: stub\n", iface
, flags
, tasks
);
195 static HRESULT WINAPI
TaskFolder_DeleteTask(ITaskFolder
*iface
, BSTR name
, LONG flags
)
197 FIXME("%p,%s,%x: stub\n", iface
, debugstr_w(name
), flags
);
201 static HRESULT WINAPI
TaskFolder_RegisterTask(ITaskFolder
*iface
, BSTR path
, BSTR xml
, LONG flags
,
202 VARIANT user
, VARIANT password
, TASK_LOGON_TYPE logon
,
203 VARIANT sddl
, IRegisteredTask
**task
)
205 FIXME("%p,%s,%s,%x,%s,%s,%d,%s,%p: stub\n", iface
, debugstr_w(path
), debugstr_w(xml
), flags
,
206 debugstr_variant(&user
), debugstr_variant(&password
), logon
, debugstr_variant(&sddl
), task
);
210 static HRESULT WINAPI
TaskFolder_RegisterTaskDefinition(ITaskFolder
*iface
, BSTR path
, ITaskDefinition
*definition
, LONG flags
,
211 VARIANT user
, VARIANT password
, TASK_LOGON_TYPE logon
,
212 VARIANT sddl
, IRegisteredTask
**task
)
214 FIXME("%p,%s,%p,%x,%s,%s,%d,%s,%p: stub\n", iface
, debugstr_w(path
), definition
, flags
,
215 debugstr_variant(&user
), debugstr_variant(&password
), logon
, debugstr_variant(&sddl
), task
);
219 static HRESULT WINAPI
TaskFolder_GetSecurityDescriptor(ITaskFolder
*iface
, LONG info
, BSTR
*sddl
)
221 FIXME("%p,%x,%p: stub\n", iface
, info
, sddl
);
225 static HRESULT WINAPI
TaskFolder_SetSecurityDescriptor(ITaskFolder
*iface
, BSTR sddl
, LONG flags
)
227 FIXME("%p,%s,%x: stub\n", iface
, debugstr_w(sddl
), flags
);
231 static const ITaskFolderVtbl TaskFolder_vtbl
=
233 TaskFolder_QueryInterface
,
236 TaskFolder_GetTypeInfoCount
,
237 TaskFolder_GetTypeInfo
,
238 TaskFolder_GetIDsOfNames
,
242 TaskFolder_GetFolder
,
243 TaskFolder_GetFolders
,
244 TaskFolder_CreateFolder
,
245 TaskFolder_DeleteFolder
,
248 TaskFolder_DeleteTask
,
249 TaskFolder_RegisterTask
,
250 TaskFolder_RegisterTaskDefinition
,
251 TaskFolder_GetSecurityDescriptor
,
252 TaskFolder_SetSecurityDescriptor
255 HRESULT
TaskFolder_create(const WCHAR
*parent
, const WCHAR
*path
, ITaskFolder
**obj
)
257 static const WCHAR bslash
[] = { '\\', 0 };
267 if (len
&& path
[len
- 1] == '\\') return ERROR_INVALID_NAME
;
270 if (parent
) len
+= strlenW(parent
);
272 /* +1 if parent is not '\' terminated */
273 folder_path
= HeapAlloc(GetProcessHeap(), 0, (len
+ 2) * sizeof(WCHAR
));
274 if (!folder_path
) return E_OUTOFMEMORY
;
279 strcpyW(folder_path
, parent
);
281 len
= strlenW(folder_path
);
282 if (!len
|| folder_path
[len
- 1] != '\\')
283 strcatW(folder_path
, bslash
);
287 while (*path
== '\\') path
++;
288 strcatW(folder_path
, path
);
291 hr
= reg_open_folder(folder_path
, &hfolder
);
294 HeapFree(GetProcessHeap(), 0, folder_path
);
298 reg_close_folder(hfolder
);
300 folder
= HeapAlloc(GetProcessHeap(), 0, sizeof(*folder
));
303 HeapFree(GetProcessHeap(), 0, folder_path
);
304 return E_OUTOFMEMORY
;
307 folder
->ITaskFolder_iface
.lpVtbl
= &TaskFolder_vtbl
;
309 folder
->path
= folder_path
;
310 *obj
= &folder
->ITaskFolder_iface
;
312 TRACE("created %p\n", *obj
);