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