xref: /reactos/dll/win32/msi/msi_main.c (revision f4be6dc3)
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  */
LockModule(void)57 static void LockModule(void)
58 {
59     InterlockedIncrement(&dll_count);
60 }
61 
UnlockModule(void)62 static void UnlockModule(void)
63 {
64     InterlockedDecrement(&dll_count);
65 }
66 
67 /******************************************************************
68  *      DllMain
69  */
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)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 
impl_from_IClassFactory(IClassFactory * iface)96 static inline struct class_factory *impl_from_IClassFactory(IClassFactory *iface)
97 {
98     return CONTAINING_RECORD(iface, struct class_factory, IClassFactory_iface);
99 }
100 
MsiCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID * ppobj)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 
MsiCF_AddRef(LPCLASSFACTORY iface)118 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
119 {
120     LockModule();
121     return 2;
122 }
123 
MsiCF_Release(LPCLASSFACTORY iface)124 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
125 {
126     UnlockModule();
127     return 1;
128 }
129 
MsiCF_CreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID * ppobj)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 
MsiCF_LockServer(LPCLASSFACTORY iface,BOOL dolock)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  */
DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID * ppv)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  */
DllGetVersion(DLLVERSIONINFO * pdvi)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  */
DllCanUnloadNow(void)216 HRESULT WINAPI DllCanUnloadNow(void)
217 {
218     return dll_count == 0 ? S_OK : S_FALSE;
219 }
220