From dab039630cc52f1633d6f878b4ee8a8866d3a490 Mon Sep 17 00:00:00 2001 From: Roy Shea Date: Tue, 22 Jul 2008 16:54:07 -0700 Subject: [PATCH] mstask: Implement ClassFactory, DllGetClassObject, and DllCanUnloadNow. --- dlls/mstask/Makefile.in | 1 + dlls/mstask/factory.c | 108 +++++++++++++++++++++++++++++++++++ dlls/mstask/mstask.spec | 4 +- dlls/mstask/mstask_main.c | 19 ++++++ dlls/mstask/mstask_private.h | 9 +++ dlls/mstask/task_scheduler.c | 2 + 6 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 dlls/mstask/factory.c diff --git a/dlls/mstask/Makefile.in b/dlls/mstask/Makefile.in index b193ae7227c..2202e227561 100644 --- a/dlls/mstask/Makefile.in +++ b/dlls/mstask/Makefile.in @@ -6,6 +6,7 @@ MODULE = mstask.dll IMPORTS = uuid kernel32 C_SRCS = \ + factory.c \ mstask_main.c \ task_scheduler.c diff --git a/dlls/mstask/factory.c b/dlls/mstask/factory.c new file mode 100644 index 00000000000..8906d922359 --- /dev/null +++ b/dlls/mstask/factory.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2008 Google (Roy Shea) + * + * 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 "mstask_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mstask); + +static HRESULT WINAPI MSTASK_IClassFactory_QueryInterface( + LPCLASSFACTORY iface, + REFIID riid, + LPVOID *ppvObj) +{ + ClassFactoryImpl *This = (ClassFactoryImpl *)iface; + + TRACE("IID: %s\n",debugstr_guid(riid)); + if (ppvObj == NULL) + return E_POINTER; + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IClassFactory)) + { + *ppvObj = &This->lpVtbl; + IClassFactory_AddRef(iface); + return S_OK; + } + + WARN("Unknown interface: %s\n", debugstr_guid(riid)); + *ppvObj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI MSTASK_IClassFactory_AddRef(LPCLASSFACTORY iface) +{ + TRACE("\n"); + InterlockedIncrement(&dll_ref); + return 2; +} + +static ULONG WINAPI MSTASK_IClassFactory_Release(LPCLASSFACTORY iface) +{ + TRACE("\n"); + InterlockedDecrement(&dll_ref); + return 1; +} + +static HRESULT WINAPI MSTASK_IClassFactory_CreateInstance( + LPCLASSFACTORY iface, + LPUNKNOWN pUnkOuter, + REFIID riid, + LPVOID *ppvObj) +{ + HRESULT res; + IUnknown *punk = NULL; + *ppvObj = NULL; + + TRACE("IID: %s\n",debugstr_guid(riid)); + + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + res = TaskSchedulerConstructor((LPVOID*) &punk); + if (FAILED(res)) + return res; + + res = ITaskScheduler_QueryInterface(punk, riid, ppvObj); + ITaskScheduler_Release(punk); + return res; +} + +static HRESULT WINAPI MSTASK_IClassFactory_LockServer( + LPCLASSFACTORY iface, + BOOL fLock) +{ + TRACE("\n"); + + if (fLock != FALSE) + MSTASK_IClassFactory_AddRef(iface); + else + MSTASK_IClassFactory_Release(iface); + return S_OK; +} + +static const IClassFactoryVtbl IClassFactory_Vtbl = +{ + MSTASK_IClassFactory_QueryInterface, + MSTASK_IClassFactory_AddRef, + MSTASK_IClassFactory_Release, + MSTASK_IClassFactory_CreateInstance, + MSTASK_IClassFactory_LockServer +}; + +ClassFactoryImpl MSTASK_ClassFactory = { &IClassFactory_Vtbl }; diff --git a/dlls/mstask/mstask.spec b/dlls/mstask/mstask.spec index a65cae09d06..24d5af52ccb 100644 --- a/dlls/mstask/mstask.spec +++ b/dlls/mstask/mstask.spec @@ -1,6 +1,6 @@ @ stub ConvertAtJobsToTasks -@ stub DllCanUnloadNow -@ stub DllGetClassObject +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stub GetNetScheduleAccountInformation @ stub NetrJobAdd @ stub NetrJobDel diff --git a/dlls/mstask/mstask_main.c b/dlls/mstask/mstask_main.c index b1984ebff8c..61e0a99c813 100644 --- a/dlls/mstask/mstask_main.c +++ b/dlls/mstask/mstask_main.c @@ -21,6 +21,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mstask); +LONG dll_ref = 0; + BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); @@ -38,3 +40,20 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return TRUE; } + +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) +{ + TRACE("(%s %s %p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); + + if (IsEqualGUID(rclsid, &CLSID_CTaskScheduler)) { + return IClassFactory_QueryInterface((LPCLASSFACTORY)&MSTASK_ClassFactory, iid, ppv); + } + + FIXME("Not supported class: %s\n", debugstr_guid(rclsid)); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllCanUnloadNow(void) +{ + return dll_ref != 0 ? S_FALSE : S_OK; +} diff --git a/dlls/mstask/mstask_private.h b/dlls/mstask/mstask_private.h index 3a08e7a60b9..3ddd2b9b4dc 100644 --- a/dlls/mstask/mstask_private.h +++ b/dlls/mstask/mstask_private.h @@ -29,6 +29,15 @@ #include "ole2.h" #include "mstask.h" +extern LONG dll_ref; + +typedef struct +{ + const IClassFactoryVtbl *lpVtbl; + LONG ref; +} ClassFactoryImpl; +extern ClassFactoryImpl MSTASK_ClassFactory; + typedef struct { const ITaskSchedulerVtbl *lpVtbl; diff --git a/dlls/mstask/task_scheduler.c b/dlls/mstask/task_scheduler.c index 5d4768ed857..a1d52a893d0 100644 --- a/dlls/mstask/task_scheduler.c +++ b/dlls/mstask/task_scheduler.c @@ -25,6 +25,7 @@ static void TaskSchedulerDestructor(TaskSchedulerImpl *This) { TRACE("%p\n", This); HeapFree(GetProcessHeap(), 0, This); + InterlockedDecrement(&dll_ref); } static HRESULT WINAPI MSTASK_ITaskScheduler_QueryInterface( @@ -170,5 +171,6 @@ HRESULT TaskSchedulerConstructor(LPVOID *ppObj) This->ref = 1; *ppObj = &This->lpVtbl; + InterlockedIncrement(&dll_ref); return S_OK; }