2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2006 Mike McCormack for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define NONAMELESSUNION
33 #include "msiserver.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msi);
39 static LONG dll_count;
42 INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
44 INSTALLUI_HANDLERA gUIHandlerA = NULL;
45 INSTALLUI_HANDLERW gUIHandlerW = NULL;
46 INSTALLUI_HANDLER_RECORD gUIHandlerRecord = NULL;
48 LPVOID gUIContext = NULL;
49 WCHAR *gszLogFile = NULL;
50 HINSTANCE msi_hInstance;
52 static WCHAR msi_path[MAX_PATH];
53 static ITypeLib *msi_typelib;
56 * Dll lifetime tracking declaration
58 static void LockModule(void)
60 InterlockedIncrement(&dll_count);
63 static void UnlockModule(void)
65 InterlockedDecrement(&dll_count);
68 /******************************************************************
71 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
75 case DLL_PROCESS_ATTACH:
76 msi_hInstance = hinstDLL;
77 DisableThreadLibraryCalls(hinstDLL);
79 case DLL_PROCESS_DETACH:
80 if (msi_typelib) ITypeLib_Release( msi_typelib );
81 msi_dialog_unregister_class();
82 msi_free_handle_table();
83 msi_free( gszLogFile );
89 static CRITICAL_SECTION MSI_typelib_cs;
90 static CRITICAL_SECTION_DEBUG MSI_typelib_cs_debug =
92 0, 0, &MSI_typelib_cs,
93 { &MSI_typelib_cs_debug.ProcessLocksList,
94 &MSI_typelib_cs_debug.ProcessLocksList },
95 0, 0, { (DWORD_PTR)(__FILE__ ": MSI_typelib_cs") }
97 static CRITICAL_SECTION MSI_typelib_cs = { &MSI_typelib_cs_debug, -1, 0, 0, 0, 0 };
99 ITypeLib *get_msi_typelib( LPWSTR *path )
101 EnterCriticalSection( &MSI_typelib_cs );
105 TRACE("loading typelib\n");
107 if (GetModuleFileNameW( msi_hInstance, msi_path, MAX_PATH ))
108 LoadTypeLib( msi_path, &msi_typelib );
111 LeaveCriticalSection( &MSI_typelib_cs );
117 ITypeLib_AddRef( msi_typelib );
122 typedef struct tagIClassFactoryImpl {
123 IClassFactory IClassFactory_iface;
124 HRESULT (*create_object)( IUnknown*, LPVOID* );
127 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
129 return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
132 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
133 REFIID riid,LPVOID *ppobj)
135 IClassFactoryImpl *This = impl_from_IClassFactory(iface);
137 TRACE("%p %s %p\n",This,debugstr_guid(riid),ppobj);
139 if( IsEqualCLSID( riid, &IID_IUnknown ) ||
140 IsEqualCLSID( riid, &IID_IClassFactory ) )
142 IClassFactory_AddRef( iface );
146 return E_NOINTERFACE;
149 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
155 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
161 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
162 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
164 IClassFactoryImpl *This = impl_from_IClassFactory(iface);
165 IUnknown *unk = NULL;
168 TRACE("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
170 r = This->create_object( pOuter, (LPVOID*) &unk );
173 r = IUnknown_QueryInterface( unk, riid, ppobj );
174 IUnknown_Release( unk );
179 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
181 TRACE("%p %d\n", iface, dolock);
191 static const IClassFactoryVtbl MsiCF_Vtbl =
193 MsiCF_QueryInterface,
196 MsiCF_CreateInstance,
200 static IClassFactoryImpl MsiServer_CF = { { &MsiCF_Vtbl }, create_msiserver };
201 static IClassFactoryImpl WineMsiCustomRemote_CF = { { &MsiCF_Vtbl }, create_msi_custom_remote };
202 static IClassFactoryImpl WineMsiRemotePackage_CF = { { &MsiCF_Vtbl }, create_msi_remote_package };
204 /******************************************************************
205 * DllGetClassObject [MSI.@]
207 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
209 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
211 if ( IsEqualCLSID (rclsid, &CLSID_MsiInstaller) )
213 *ppv = &MsiServer_CF;
217 if ( IsEqualCLSID (rclsid, &CLSID_WineMsiRemoteCustomAction) )
219 *ppv = &WineMsiCustomRemote_CF;
223 if ( IsEqualCLSID (rclsid, &CLSID_WineMsiRemotePackage) )
225 *ppv = &WineMsiRemotePackage_CF;
229 if( IsEqualCLSID (rclsid, &CLSID_MsiServerMessage) ||
230 IsEqualCLSID (rclsid, &CLSID_MsiServer) ||
231 IsEqualCLSID (rclsid, &CLSID_PSFactoryBuffer) ||
232 IsEqualCLSID (rclsid, &CLSID_MsiServerX3) )
234 FIXME("create %s object\n", debugstr_guid( rclsid ));
237 return CLASS_E_CLASSNOTAVAILABLE;
240 /******************************************************************
241 * DllGetVersion [MSI.@]
243 HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *pdvi)
247 if (pdvi->cbSize < sizeof(DLLVERSIONINFO))
250 pdvi->dwMajorVersion = MSI_MAJORVERSION;
251 pdvi->dwMinorVersion = MSI_MINORVERSION;
252 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
253 pdvi->dwPlatformID = DLLVER_PLATFORM_WINDOWS;
258 /******************************************************************
259 * DllCanUnloadNow [MSI.@]
261 HRESULT WINAPI DllCanUnloadNow(void)
263 return dll_count == 0 ? S_OK : S_FALSE;
266 /***********************************************************************
267 * DllRegisterServer (MSI.@)
269 HRESULT WINAPI DllRegisterServer(void)
271 return __wine_register_resources( msi_hInstance, NULL );
274 /***********************************************************************
275 * DllUnregisterServer (MSI.@)
277 HRESULT WINAPI DllUnregisterServer(void)
279 return __wine_unregister_resources( msi_hInstance, NULL );