1 /* 2 * Implementation of the Microsoft Installer (msi.dll) 3 * 4 * Copyright 2006 Mike McCormack for CodeWeavers 5 * 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. 10 * 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. 15 * 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 19 */ 20 21 #include <stdarg.h> 22 23 #define COBJMACROS 24 25 #include "windef.h" 26 #include "winbase.h" 27 #include "winreg.h" 28 #include "shlwapi.h" 29 #include "oleauto.h" 30 #include "rpcproxy.h" 31 #include "msipriv.h" 32 #include "msiserver.h" 33 34 #include "wine/debug.h" 35 36 WINE_DEFAULT_DEBUG_CHANNEL(msi); 37 38 static LONG dll_count; 39 40 /* the UI level */ 41 INSTALLUILEVEL gUILevel = INSTALLUILEVEL_DEFAULT; 42 HWND gUIhwnd = 0; 43 INSTALLUI_HANDLERA gUIHandlerA = NULL; 44 INSTALLUI_HANDLERW gUIHandlerW = NULL; 45 INSTALLUI_HANDLER_RECORD gUIHandlerRecord = NULL; 46 DWORD gUIFilter = 0; 47 DWORD gUIFilterRecord = 0; 48 LPVOID gUIContext = NULL; 49 LPVOID gUIContextRecord = NULL; 50 WCHAR *gszLogFile = NULL; 51 HINSTANCE msi_hInstance; 52 53 54 /* 55 * Dll lifetime tracking declaration 56 */ 57 static void LockModule(void) 58 { 59 InterlockedIncrement(&dll_count); 60 } 61 62 static void UnlockModule(void) 63 { 64 InterlockedDecrement(&dll_count); 65 } 66 67 /****************************************************************** 68 * DllMain 69 */ 70 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 71 { 72 switch (fdwReason) 73 { 74 case DLL_PROCESS_ATTACH: 75 msi_hInstance = hinstDLL; 76 DisableThreadLibraryCalls(hinstDLL); 77 IsWow64Process( GetCurrentProcess(), &is_wow64 ); 78 break; 79 case DLL_PROCESS_DETACH: 80 if (lpvReserved) break; 81 msi_dialog_unregister_class(); 82 msi_free_handle_table(); 83 free( gszLogFile ); 84 release_typelib(); 85 break; 86 } 87 return TRUE; 88 } 89 90 struct class_factory 91 { 92 IClassFactory IClassFactory_iface; 93 HRESULT (*create_object)( IUnknown *, void ** ); 94 }; 95 96 static inline struct class_factory *impl_from_IClassFactory(IClassFactory *iface) 97 { 98 return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface); 99 } 100 101 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface, 102 REFIID riid,LPVOID *ppobj) 103 { 104 struct class_factory *This = impl_from_IClassFactory(iface); 105 106 TRACE("%p %s %p\n",This,debugstr_guid(riid),ppobj); 107 108 if( IsEqualCLSID( riid, &IID_IUnknown ) || 109 IsEqualCLSID( riid, &IID_IClassFactory ) ) 110 { 111 IClassFactory_AddRef( iface ); 112 *ppobj = iface; 113 return S_OK; 114 } 115 return E_NOINTERFACE; 116 } 117 118 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface) 119 { 120 LockModule(); 121 return 2; 122 } 123 124 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface) 125 { 126 UnlockModule(); 127 return 1; 128 } 129 130 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface, 131 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) 132 { 133 struct class_factory *This = impl_from_IClassFactory(iface); 134 IUnknown *unk = NULL; 135 HRESULT r; 136 137 TRACE("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj); 138 139 r = This->create_object( pOuter, (LPVOID*) &unk ); 140 if (SUCCEEDED(r)) 141 { 142 r = IUnknown_QueryInterface( unk, riid, ppobj ); 143 IUnknown_Release( unk ); 144 } 145 return r; 146 } 147 148 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock) 149 { 150 TRACE("%p %d\n", iface, dolock); 151 152 if (dolock) 153 LockModule(); 154 else 155 UnlockModule(); 156 157 return S_OK; 158 } 159 160 static const IClassFactoryVtbl MsiCF_Vtbl = 161 { 162 MsiCF_QueryInterface, 163 MsiCF_AddRef, 164 MsiCF_Release, 165 MsiCF_CreateInstance, 166 MsiCF_LockServer 167 }; 168 169 static struct class_factory MsiServer_CF = { { &MsiCF_Vtbl }, create_msiserver }; 170 171 /****************************************************************** 172 * DllGetClassObject [MSI.@] 173 */ 174 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 175 { 176 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); 177 178 if ( IsEqualCLSID (rclsid, &CLSID_MsiInstaller) ) 179 { 180 *ppv = &MsiServer_CF; 181 return S_OK; 182 } 183 184 if( IsEqualCLSID (rclsid, &CLSID_MsiServerMessage) || 185 IsEqualCLSID (rclsid, &CLSID_MsiServer) || 186 IsEqualCLSID (rclsid, &CLSID_PSFactoryBuffer) || 187 IsEqualCLSID (rclsid, &CLSID_MsiServerX3) ) 188 { 189 FIXME("create %s object\n", debugstr_guid( rclsid )); 190 } 191 192 return CLASS_E_CLASSNOTAVAILABLE; 193 } 194 195 /****************************************************************** 196 * DllGetVersion [MSI.@] 197 */ 198 HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *pdvi) 199 { 200 TRACE("%p\n",pdvi); 201 202 if (pdvi->cbSize < sizeof(DLLVERSIONINFO)) 203 return E_INVALIDARG; 204 205 pdvi->dwMajorVersion = MSI_MAJORVERSION; 206 pdvi->dwMinorVersion = MSI_MINORVERSION; 207 pdvi->dwBuildNumber = MSI_BUILDNUMBER; 208 pdvi->dwPlatformID = DLLVER_PLATFORM_WINDOWS; 209 210 return S_OK; 211 } 212 213 /****************************************************************** 214 * DllCanUnloadNow [MSI.@] 215 */ 216 HRESULT WINAPI DllCanUnloadNow(void) 217 { 218 return dll_count == 0 ? S_OK : S_FALSE; 219 } 220