taskschd: Make GetFolder check whether task folder tree exists in the registry.
[wine/multimedia.git] / dlls / taskschd / folder.c
blobcb285fdc88221cba44d284ccdbc6498d7969ded6
1 /*
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
19 #include <stdarg.h>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winreg.h"
26 #include "objbase.h"
27 #include "taskschd.h"
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";
37 typedef struct
39 ITaskFolder ITaskFolder_iface;
40 LONG ref;
41 WCHAR *path;
42 } TaskFolder;
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);
60 if (!ref)
62 TRACE("destroying %p\n", iface);
63 HeapFree(GetProcessHeap(), 0, folder->path);
64 HeapFree(GetProcessHeap(), 0, folder);
67 return ref;
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);
81 *obj = iface;
82 return S_OK;
85 FIXME("interface %s is not implemented\n", debugstr_guid(riid));
86 return E_NOINTERFACE;
89 static HRESULT WINAPI TaskFolder_GetTypeInfoCount(ITaskFolder *iface, UINT *count)
91 FIXME("%p,%p: stub\n", iface, count);
92 return E_NOTIMPL;
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);
98 return E_NOTIMPL;
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);
105 return E_NOTIMPL;
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);
113 return E_NOTIMPL;
116 static HRESULT WINAPI TaskFolder_get_Name(ITaskFolder *iface, BSTR *name)
118 FIXME("%p,%p: stub\n", iface, name);
119 return E_NOTIMPL;
122 static HRESULT reg_open_folder(const WCHAR *path, HKEY *hfolder)
124 HKEY hroot;
125 DWORD ret;
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;
135 RegCloseKey(hroot);
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;
156 return S_OK;
159 static HRESULT WINAPI TaskFolder_GetFolder(ITaskFolder *iface, BSTR path, ITaskFolder **folder)
161 FIXME("%p,%s,%p: stub\n", iface, debugstr_w(path), folder);
162 return E_NOTIMPL;
165 static HRESULT WINAPI TaskFolder_GetFolders(ITaskFolder *iface, LONG flags, ITaskFolderCollection **folders)
167 FIXME("%p,%x,%p: stub\n", iface, flags, folders);
168 return E_NOTIMPL;
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);
174 return E_NOTIMPL;
177 static HRESULT WINAPI TaskFolder_DeleteFolder(ITaskFolder *iface, BSTR name, LONG flags)
179 FIXME("%p,%s,%x: stub\n", iface, debugstr_w(name), flags);
180 return E_NOTIMPL;
183 static HRESULT WINAPI TaskFolder_GetTask(ITaskFolder *iface, BSTR path, IRegisteredTask **task)
185 FIXME("%p,%s,%p: stub\n", iface, debugstr_w(path), task);
186 return E_NOTIMPL;
189 static HRESULT WINAPI TaskFolder_GetTasks(ITaskFolder *iface, LONG flags, IRegisteredTaskCollection **tasks)
191 FIXME("%p,%x,%p: stub\n", iface, flags, tasks);
192 return E_NOTIMPL;
195 static HRESULT WINAPI TaskFolder_DeleteTask(ITaskFolder *iface, BSTR name, LONG flags)
197 FIXME("%p,%s,%x: stub\n", iface, debugstr_w(name), flags);
198 return E_NOTIMPL;
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);
207 return E_NOTIMPL;
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);
216 return E_NOTIMPL;
219 static HRESULT WINAPI TaskFolder_GetSecurityDescriptor(ITaskFolder *iface, LONG info, BSTR *sddl)
221 FIXME("%p,%x,%p: stub\n", iface, info, sddl);
222 return E_NOTIMPL;
225 static HRESULT WINAPI TaskFolder_SetSecurityDescriptor(ITaskFolder *iface, BSTR sddl, LONG flags)
227 FIXME("%p,%s,%x: stub\n", iface, debugstr_w(sddl), flags);
228 return E_NOTIMPL;
231 static const ITaskFolderVtbl TaskFolder_vtbl =
233 TaskFolder_QueryInterface,
234 TaskFolder_AddRef,
235 TaskFolder_Release,
236 TaskFolder_GetTypeInfoCount,
237 TaskFolder_GetTypeInfo,
238 TaskFolder_GetIDsOfNames,
239 TaskFolder_Invoke,
240 TaskFolder_get_Name,
241 TaskFolder_get_Path,
242 TaskFolder_GetFolder,
243 TaskFolder_GetFolders,
244 TaskFolder_CreateFolder,
245 TaskFolder_DeleteFolder,
246 TaskFolder_GetTask,
247 TaskFolder_GetTasks,
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 };
258 TaskFolder *folder;
259 WCHAR *folder_path;
260 int len = 0;
261 HRESULT hr;
262 HKEY hfolder;
264 if (path)
266 len = strlenW(path);
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;
276 folder_path[0] = 0;
278 if (parent)
279 strcpyW(folder_path, parent);
281 len = strlenW(folder_path);
282 if (!len || folder_path[len - 1] != '\\')
283 strcatW(folder_path, bslash);
285 if (path)
287 while (*path == '\\') path++;
288 strcatW(folder_path, path);
291 hr = reg_open_folder(folder_path, &hfolder);
292 if (hr)
294 HeapFree(GetProcessHeap(), 0, folder_path);
295 return hr;
298 reg_close_folder(hfolder);
300 folder = HeapAlloc(GetProcessHeap(), 0, sizeof(*folder));
301 if (!folder)
303 HeapFree(GetProcessHeap(), 0, folder_path);
304 return E_OUTOFMEMORY;
307 folder->ITaskFolder_iface.lpVtbl = &TaskFolder_vtbl;
308 folder->ref = 1;
309 folder->path = folder_path;
310 *obj = &folder->ITaskFolder_iface;
312 TRACE("created %p\n", *obj);
314 return S_OK;