xref: /reactos/dll/win32/msi/msi_main.c (revision 85d9a38a)
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