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