From fe55cb10312e984a58f927ac459f233c031e51e4 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Fri, 17 Jan 2014 17:59:49 +0900 Subject: [PATCH] taskschd: Add ITaskFolder stub implementation. --- dlls/taskschd/Makefile.in | 1 + dlls/taskschd/folder.c | 233 +++++++++++++++++++++++++++++++ dlls/taskschd/task.c | 7 +- dlls/taskschd/taskschd_private.h | 1 + dlls/taskschd/tests/scheduler.c | 39 ++++-- 5 files changed, 264 insertions(+), 17 deletions(-) create mode 100644 dlls/taskschd/folder.c diff --git a/dlls/taskschd/Makefile.in b/dlls/taskschd/Makefile.in index 2b495850207..80775c7eaa0 100644 --- a/dlls/taskschd/Makefile.in +++ b/dlls/taskschd/Makefile.in @@ -2,6 +2,7 @@ MODULE = taskschd.dll IMPORTS = oleaut32 C_SRCS = \ + folder.c \ task.c \ taskschd.c diff --git a/dlls/taskschd/folder.c b/dlls/taskschd/folder.c new file mode 100644 index 00000000000..ef69cfe2bfb --- /dev/null +++ b/dlls/taskschd/folder.c @@ -0,0 +1,233 @@ +/* + * Copyright 2014 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "taskschd.h" +#include "taskschd_private.h" + +#include "wine/unicode.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(taskschd); + +typedef struct +{ + ITaskFolder ITaskFolder_iface; + LONG ref; +} TaskFolder; + +static inline TaskFolder *impl_from_ITaskFolder(ITaskFolder *iface) +{ + return CONTAINING_RECORD(iface, TaskFolder, ITaskFolder_iface); +} + +static ULONG WINAPI TaskFolder_AddRef(ITaskFolder *iface) +{ + TaskFolder *folder = impl_from_ITaskFolder(iface); + return InterlockedIncrement(&folder->ref); +} + +static ULONG WINAPI TaskFolder_Release(ITaskFolder *iface) +{ + TaskFolder *folder = impl_from_ITaskFolder(iface); + LONG ref = InterlockedDecrement(&folder->ref); + + if (!ref) + { + TRACE("destroying %p\n", iface); + HeapFree(GetProcessHeap(), 0, folder); + } + + return ref; +} + +static HRESULT WINAPI TaskFolder_QueryInterface(ITaskFolder *iface, REFIID riid, void **obj) +{ + if (!riid || !obj) return E_INVALIDARG; + + TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj); + + if (IsEqualGUID(riid, &IID_ITaskFolder) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IUnknown)) + { + ITaskFolder_AddRef(iface); + *obj = iface; + return S_OK; + } + + FIXME("interface %s is not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static HRESULT WINAPI TaskFolder_GetTypeInfoCount(ITaskFolder *iface, UINT *count) +{ + FIXME("%p,%p: stub\n", iface, count); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_GetTypeInfo(ITaskFolder *iface, UINT index, LCID lcid, ITypeInfo **info) +{ + FIXME("%p,%u,%u,%p: stub\n", iface, index, lcid, info); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_GetIDsOfNames(ITaskFolder *iface, REFIID riid, LPOLESTR *names, + UINT count, LCID lcid, DISPID *dispid) +{ + FIXME("%p,%s,%p,%u,%u,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_Invoke(ITaskFolder *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags, + DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr) +{ + FIXME("%p,%d,%s,%04x,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags, + params, result, excepinfo, argerr); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_get_Name(ITaskFolder *iface, BSTR *name) +{ + FIXME("%p,%p: stub\n", iface, name); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_get_Path(ITaskFolder *iface, BSTR *path) +{ + FIXME("%p,%p: stub\n", iface, path); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_GetFolder(ITaskFolder *iface, BSTR path, ITaskFolder **folder) +{ + FIXME("%p,%s,%p: stub\n", iface, debugstr_w(path), folder); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_GetFolders(ITaskFolder *iface, LONG flags, ITaskFolderCollection **folders) +{ + FIXME("%p,%x,%p: stub\n", iface, flags, folders); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_CreateFolder(ITaskFolder *iface, BSTR name, VARIANT sddl, ITaskFolder **folder) +{ + FIXME("%p,%s,%s,%p: stub\n", iface, debugstr_w(name), debugstr_variant(&sddl), folder); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_DeleteFolder(ITaskFolder *iface, BSTR name, LONG flags) +{ + FIXME("%p,%s,%x: stub\n", iface, debugstr_w(name), flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_GetTask(ITaskFolder *iface, BSTR path, IRegisteredTask **task) +{ + FIXME("%p,%s,%p: stub\n", iface, debugstr_w(path), task); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_GetTasks(ITaskFolder *iface, LONG flags, IRegisteredTaskCollection **tasks) +{ + FIXME("%p,%x,%p: stub\n", iface, flags, tasks); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_DeleteTask(ITaskFolder *iface, BSTR name, LONG flags) +{ + FIXME("%p,%s,%x: stub\n", iface, debugstr_w(name), flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_RegisterTask(ITaskFolder *iface, BSTR path, BSTR xml, LONG flags, + VARIANT user, VARIANT password, TASK_LOGON_TYPE logon, + VARIANT sddl, IRegisteredTask **task) +{ + FIXME("%p,%s,%s,%x,%s,%s,%d,%s,%p: stub\n", iface, debugstr_w(path), debugstr_w(xml), flags, + debugstr_variant(&user), debugstr_variant(&password), logon, debugstr_variant(&sddl), task); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_RegisterTaskDefinition(ITaskFolder *iface, BSTR path, ITaskDefinition *definition, LONG flags, + VARIANT user, VARIANT password, TASK_LOGON_TYPE logon, + VARIANT sddl, IRegisteredTask **task) +{ + FIXME("%p,%s,%p,%x,%s,%s,%d,%s,%p: stub\n", iface, debugstr_w(path), definition, flags, + debugstr_variant(&user), debugstr_variant(&password), logon, debugstr_variant(&sddl), task); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_GetSecurityDescriptor(ITaskFolder *iface, LONG info, BSTR *sddl) +{ + FIXME("%p,%x,%p: stub\n", iface, info, sddl); + return E_NOTIMPL; +} + +static HRESULT WINAPI TaskFolder_SetSecurityDescriptor(ITaskFolder *iface, BSTR sddl, LONG flags) +{ + FIXME("%p,%s,%x: stub\n", iface, debugstr_w(sddl), flags); + return E_NOTIMPL; +} + +static const ITaskFolderVtbl TaskFolder_vtbl = +{ + TaskFolder_QueryInterface, + TaskFolder_AddRef, + TaskFolder_Release, + TaskFolder_GetTypeInfoCount, + TaskFolder_GetTypeInfo, + TaskFolder_GetIDsOfNames, + TaskFolder_Invoke, + TaskFolder_get_Name, + TaskFolder_get_Path, + TaskFolder_GetFolder, + TaskFolder_GetFolders, + TaskFolder_CreateFolder, + TaskFolder_DeleteFolder, + TaskFolder_GetTask, + TaskFolder_GetTasks, + TaskFolder_DeleteTask, + TaskFolder_RegisterTask, + TaskFolder_RegisterTaskDefinition, + TaskFolder_GetSecurityDescriptor, + TaskFolder_SetSecurityDescriptor +}; + +HRESULT TaskFolder_create(const WCHAR *parent, const WCHAR *path, ITaskFolder **obj) +{ + TaskFolder *folder; + + folder = HeapAlloc(GetProcessHeap(), 0, sizeof(*folder)); + if (!folder) return E_OUTOFMEMORY; + + folder->ITaskFolder_iface.lpVtbl = &TaskFolder_vtbl; + folder->ref = 1; + *obj = &folder->ITaskFolder_iface; + + TRACE("created %p\n", *obj); + + return S_OK; +} diff --git a/dlls/taskschd/task.c b/dlls/taskschd/task.c index c8f8fdf76b6..632cabb500e 100644 --- a/dlls/taskschd/task.c +++ b/dlls/taskschd/task.c @@ -113,8 +113,11 @@ static HRESULT WINAPI TaskService_Invoke(ITaskService *iface, DISPID dispid, REF static HRESULT WINAPI TaskService_GetFolder(ITaskService *iface, BSTR path, ITaskFolder **folder) { - FIXME("%p,%s,%p: stub\n", iface, debugstr_w(path), folder); - return E_NOTIMPL; + TRACE("%p,%s,%p\n", iface, debugstr_w(path), folder); + + if (!folder) return E_POINTER; + + return TaskFolder_create(path, NULL, folder); } static HRESULT WINAPI TaskService_GetRunningTasks(ITaskService *iface, LONG flags, IRunningTaskCollection **tasks) diff --git a/dlls/taskschd/taskschd_private.h b/dlls/taskschd/taskschd_private.h index be6d3189d04..deebc417fc0 100644 --- a/dlls/taskschd/taskschd_private.h +++ b/dlls/taskschd/taskschd_private.h @@ -17,5 +17,6 @@ */ HRESULT TaskService_create(void **obj) DECLSPEC_HIDDEN; +HRESULT TaskFolder_create(const WCHAR *parent, const WCHAR *path, ITaskFolder **obj) DECLSPEC_HIDDEN; const char *debugstr_variant(const VARIANT *v) DECLSPEC_HIDDEN; diff --git a/dlls/taskschd/tests/scheduler.c b/dlls/taskschd/tests/scheduler.c index 63b5730c464..74ae95f05c9 100644 --- a/dlls/taskschd/tests/scheduler.c +++ b/dlls/taskschd/tests/scheduler.c @@ -155,47 +155,47 @@ todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), "expected ERROR_INVALID_NAME, got %#x\n", hr); hr = ITaskService_GetFolder(service, bslash, &folder); -todo_wine ok(hr == S_OK, "GetFolder error %#x\n", hr); - if (hr == S_OK) - ITaskFolder_Release(folder); + ITaskFolder_Release(folder); hr = ITaskService_GetFolder(service, NULL, NULL); -todo_wine ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr); hr = ITaskService_GetFolder(service, empty, &folder); -todo_wine ok(hr == S_OK, "GetFolder error %#x\n", hr); - if (hr == S_OK) - ITaskFolder_Release(folder); + ITaskFolder_Release(folder); hr = ITaskService_GetFolder(service, NULL, &folder); -todo_wine ok(hr == S_OK, "GetFolder error %#x\n", hr); - if (hr != S_OK) - { - ITaskService_Release(service); - return; - } hr = ITaskFolder_get_Name(folder, NULL); +todo_wine ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr); hr = ITaskFolder_get_Name(folder, &bstr); +todo_wine ok (hr == S_OK, "get_Name error %#x\n", hr); +if (hr == S_OK) +{ ok(!lstrcmpW(bstr, bslash), "expected '\\', got %s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr); +} hr = ITaskFolder_get_Path(folder, NULL); +todo_wine ok(hr == E_POINTER, "expected E_POINTER, got %#x\n", hr); hr = ITaskFolder_get_Path(folder, &bstr); +todo_wine ok(hr == S_OK, "get_Path error %#x\n", hr); +if (hr == S_OK) +{ ok(!lstrcmpW(bstr, bslash), "expected '\\', got %s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr); +} hr = ITaskFolder_CreateFolder(folder, NULL, v_null, &subfolder); +todo_wine ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); /* Just in case something was left from previous runs */ @@ -204,18 +204,27 @@ todo_wine ITaskFolder_DeleteFolder(folder, Wine, 0); hr = ITaskFolder_CreateFolder(folder, slash, v_null, &subfolder); +todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), "expected ERROR_INVALID_NAME, got %#x\n", hr); hr = ITaskService_GetFolder(service, Wine_Folder1_Folder2, &subfolder); +todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "expected ERROR_PATH_NOT_FOUND, got %#x\n", hr); hr = ITaskFolder_CreateFolder(folder, bslash, v_null, &subfolder); +todo_wine ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr); hr = ITaskFolder_CreateFolder(folder, Wine_Folder1_Folder2, v_null, &subfolder); +todo_wine ok(hr == S_OK, "CreateFolder error %#x\n", hr); - if (hr == S_OK) - ITaskFolder_Release(subfolder); + if (hr != S_OK) + { + ITaskFolder_Release(folder); + ITaskService_Release(service); + return; + } + ITaskFolder_Release(subfolder); hr = ITaskFolder_CreateFolder(folder, Wine, v_null, NULL); ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), "expected ERROR_ALREADY_EXISTS, got %#x\n", hr);