dmloader: Simplify the module refcount handling.
[wine] / dlls / dmloader / dmloader_main.c
1 /* DirectMusicLoader Main
2  *
3  * Copyright (C) 2003-2004 Rok Mandeljc
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include "dmloader_private.h"
21 #include "rpcproxy.h"
22
23 WINE_DEFAULT_DEBUG_CHANNEL(dmloader);
24
25 static HINSTANCE instance;
26 LONG module_ref = 0;
27
28 typedef struct {
29     IClassFactory IClassFactory_iface;
30     HRESULT WINAPI (*fnCreateInstance)(REFIID riid, void **ppv, IUnknown *pUnkOuter);
31 } IClassFactoryImpl;
32
33 /******************************************************************
34  *      IClassFactory implementation
35  */
36 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
37 {
38     return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
39 }
40
41 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
42 {
43     if (ppv == NULL)
44         return E_POINTER;
45
46     if (IsEqualGUID(&IID_IUnknown, riid))
47         TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
48     else if (IsEqualGUID(&IID_IClassFactory, riid))
49         TRACE("(%p)->(IID_IClassFactory %p)\n", iface, ppv);
50     else {
51         FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
52         *ppv = NULL;
53         return E_NOINTERFACE;
54 }
55
56     *ppv = iface;
57     IClassFactory_AddRef(iface);
58     return S_OK;
59 }
60
61 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
62 {
63     lock_module();
64
65     return 2; /* non-heap based object */
66 }
67
68 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
69 {
70     unlock_module();
71
72     return 1; /* non-heap based object */
73 }
74
75 static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter,
76     REFIID riid, void **ppv)
77 {
78     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
79
80     TRACE ("(%p, %s, %p)\n", pUnkOuter, debugstr_dmguid(riid), ppv);
81
82     return This->fnCreateInstance(riid, ppv, pUnkOuter);
83 }
84
85 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
86 {
87     TRACE("(%d)\n", dolock);
88
89     if (dolock)
90         lock_module();
91     else
92         unlock_module();
93
94     return S_OK;
95 }
96
97 static const IClassFactoryVtbl classfactory_vtbl = {
98     ClassFactory_QueryInterface,
99     ClassFactory_AddRef,
100     ClassFactory_Release,
101     ClassFactory_CreateInstance,
102     ClassFactory_LockServer
103 };
104
105 static IClassFactoryImpl dm_loader_CF = {{&classfactory_vtbl}, DMUSIC_CreateDirectMusicLoaderImpl};
106 static IClassFactoryImpl dm_container_CF = {{&classfactory_vtbl},
107                                             DMUSIC_CreateDirectMusicContainerImpl};
108
109 /******************************************************************
110  *              DllMain
111  */
112 BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
113         if (fdwReason == DLL_PROCESS_ATTACH) {
114                 instance = hinstDLL;
115                 DisableThreadLibraryCalls(hinstDLL);
116                 /* FIXME: Initialisation */
117         } else if (fdwReason == DLL_PROCESS_DETACH) {
118                 /* FIXME: Cleanup */
119         }
120         return TRUE;
121 }
122
123
124 /******************************************************************
125  *              DllCanUnloadNow (DMLOADER.@)
126  */
127 HRESULT WINAPI DllCanUnloadNow (void)
128 {
129     TRACE("() ref=%d\n", module_ref);
130
131     return module_ref ? S_FALSE : S_OK;
132 }
133
134 /******************************************************************
135  *              DllGetClassObject (DMLOADER.@)
136  */
137 HRESULT WINAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID *ppv)
138 {
139     TRACE("(%s, %s, %p)\n", debugstr_dmguid(rclsid), debugstr_dmguid(riid), ppv);
140     if (IsEqualCLSID (rclsid, &CLSID_DirectMusicLoader) && IsEqualIID (riid, &IID_IClassFactory)) {
141         IClassFactory_AddRef(&dm_loader_CF.IClassFactory_iface);
142         *ppv = &dm_loader_CF.IClassFactory_iface;
143         return S_OK;
144     } else if (IsEqualCLSID (rclsid, &CLSID_DirectMusicContainer) && IsEqualIID (riid, &IID_IClassFactory)) {
145         IClassFactory_AddRef(&dm_container_CF.IClassFactory_iface);
146         *ppv = &dm_container_CF.IClassFactory_iface;
147         return S_OK;
148     }
149
150     WARN(": no class found\n");
151     return CLASS_E_CLASSNOTAVAILABLE;
152 }
153
154 /***********************************************************************
155  *              DllRegisterServer (DMLOADER.@)
156  */
157 HRESULT WINAPI DllRegisterServer(void)
158 {
159     return __wine_register_resources( instance, NULL );
160 }
161
162 /***********************************************************************
163  *              DllUnregisterServer (DMLOADER.@)
164  */
165 HRESULT WINAPI DllUnregisterServer(void)
166 {
167     return __wine_unregister_resources( instance, NULL );
168 }