xref: /reactos/dll/win32/msi/msi_main.c (revision 8a978a17)
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         msi_free( gszLogFile );
84         release_typelib();
85         break;
86     }
87     return TRUE;
88 }
89 
90 typedef struct tagIClassFactoryImpl {
91     IClassFactory IClassFactory_iface;
92     HRESULT (*create_object)( IUnknown*, LPVOID* );
93 } IClassFactoryImpl;
94 
95 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
96 {
97     return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
98 }
99 
100 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
101                 REFIID riid,LPVOID *ppobj)
102 {
103     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
104 
105     TRACE("%p %s %p\n",This,debugstr_guid(riid),ppobj);
106 
107     if( IsEqualCLSID( riid, &IID_IUnknown ) ||
108         IsEqualCLSID( riid, &IID_IClassFactory ) )
109     {
110         IClassFactory_AddRef( iface );
111         *ppobj = iface;
112         return S_OK;
113     }
114     return E_NOINTERFACE;
115 }
116 
117 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
118 {
119     LockModule();
120     return 2;
121 }
122 
123 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
124 {
125     UnlockModule();
126     return 1;
127 }
128 
129 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
130     LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
131 {
132     IClassFactoryImpl *This = impl_from_IClassFactory(iface);
133     IUnknown *unk = NULL;
134     HRESULT r;
135 
136     TRACE("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
137 
138     r = This->create_object( pOuter, (LPVOID*) &unk );
139     if (SUCCEEDED(r))
140     {
141         r = IUnknown_QueryInterface( unk, riid, ppobj );
142         IUnknown_Release( unk );
143     }
144     return r;
145 }
146 
147 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
148 {
149     TRACE("%p %d\n", iface, dolock);
150 
151     if (dolock)
152         LockModule();
153     else
154         UnlockModule();
155 
156     return S_OK;
157 }
158 
159 static const IClassFactoryVtbl MsiCF_Vtbl =
160 {
161     MsiCF_QueryInterface,
162     MsiCF_AddRef,
163     MsiCF_Release,
164     MsiCF_CreateInstance,
165     MsiCF_LockServer
166 };
167 
168 static IClassFactoryImpl MsiServer_CF = { { &MsiCF_Vtbl }, create_msiserver };
169 static IClassFactoryImpl WineMsiCustomRemote_CF = { { &MsiCF_Vtbl }, create_msi_custom_remote };
170 static IClassFactoryImpl WineMsiRemotePackage_CF = { { &MsiCF_Vtbl }, create_msi_remote_package };
171 
172 /******************************************************************
173  * DllGetClassObject          [MSI.@]
174  */
175 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
176 {
177     TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
178 
179     if ( IsEqualCLSID (rclsid, &CLSID_MsiInstaller) )
180     {
181         *ppv = &MsiServer_CF;
182         return S_OK;
183     }
184 
185     if ( IsEqualCLSID (rclsid, &CLSID_WineMsiRemoteCustomAction) )
186     {
187         *ppv = &WineMsiCustomRemote_CF;
188         return S_OK;
189     }
190 
191     if ( IsEqualCLSID (rclsid, &CLSID_WineMsiRemotePackage) )
192     {
193         *ppv = &WineMsiRemotePackage_CF;
194         return S_OK;
195     }
196 
197     if( IsEqualCLSID (rclsid, &CLSID_MsiServerMessage) ||
198         IsEqualCLSID (rclsid, &CLSID_MsiServer) ||
199         IsEqualCLSID (rclsid, &CLSID_PSFactoryBuffer) ||
200         IsEqualCLSID (rclsid, &CLSID_MsiServerX3) )
201     {
202         FIXME("create %s object\n", debugstr_guid( rclsid ));
203     }
204 
205     return CLASS_E_CLASSNOTAVAILABLE;
206 }
207 
208 /******************************************************************
209  * DllGetVersion              [MSI.@]
210  */
211 HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *pdvi)
212 {
213     TRACE("%p\n",pdvi);
214 
215     if (pdvi->cbSize < sizeof(DLLVERSIONINFO))
216         return E_INVALIDARG;
217 
218     pdvi->dwMajorVersion = MSI_MAJORVERSION;
219     pdvi->dwMinorVersion = MSI_MINORVERSION;
220     pdvi->dwBuildNumber = MSI_BUILDNUMBER;
221     pdvi->dwPlatformID = DLLVER_PLATFORM_WINDOWS;
222 
223     return S_OK;
224 }
225 
226 /******************************************************************
227  * DllCanUnloadNow            [MSI.@]
228  */
229 HRESULT WINAPI DllCanUnloadNow(void)
230 {
231     return dll_count == 0 ? S_OK : S_FALSE;
232 }
233 
234 /***********************************************************************
235  *  DllRegisterServer (MSI.@)
236  */
237 HRESULT WINAPI DllRegisterServer(void)
238 {
239     return __wine_register_resources( msi_hInstance );
240 }
241 
242 /***********************************************************************
243  *  DllUnregisterServer (MSI.@)
244  */
245 HRESULT WINAPI DllUnregisterServer(void)
246 {
247     return __wine_unregister_resources( msi_hInstance );
248 }
249