summaryrefslogtreecommitdiffstats
path: root/libmsi/msi_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmsi/msi_main.c')
-rw-r--r--libmsi/msi_main.c245
1 files changed, 245 insertions, 0 deletions
diff --git a/libmsi/msi_main.c b/libmsi/msi_main.c
new file mode 100644
index 0000000..de0534a
--- /dev/null
+++ b/libmsi/msi_main.c
@@ -0,0 +1,245 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2006 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "shlwapi.h"
+#include "oleauto.h"
+#include "rpcproxy.h"
+#include "msipriv.h"
+#include "msiserver.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+static LONG dll_count;
+
+/* the UI level */
+INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
+HWND gUIhwnd = 0;
+INSTALLUI_HANDLERA gUIHandlerA = NULL;
+INSTALLUI_HANDLERW gUIHandlerW = NULL;
+INSTALLUI_HANDLER_RECORD gUIHandlerRecord = NULL;
+DWORD gUIFilter = 0;
+LPVOID gUIContext = NULL;
+WCHAR *gszLogFile = NULL;
+HINSTANCE msi_hInstance;
+
+
+/*
+ * Dll lifetime tracking declaration
+ */
+static void LockModule(void)
+{
+ InterlockedIncrement(&dll_count);
+}
+
+static void UnlockModule(void)
+{
+ InterlockedDecrement(&dll_count);
+}
+
+/******************************************************************
+ * DllMain
+ */
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ msi_hInstance = hinstDLL;
+ DisableThreadLibraryCalls(hinstDLL);
+ IsWow64Process( GetCurrentProcess(), &is_wow64 );
+ break;
+ case DLL_PROCESS_DETACH:
+ msi_dialog_unregister_class();
+ msi_free_handle_table();
+ msi_free( gszLogFile );
+ break;
+ }
+ return TRUE;
+}
+
+typedef struct tagIClassFactoryImpl {
+ IClassFactory IClassFactory_iface;
+ HRESULT (*create_object)( IUnknown*, LPVOID* );
+} IClassFactoryImpl;
+
+static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface)
+{
+ return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface);
+}
+
+static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
+ REFIID riid,LPVOID *ppobj)
+{
+ IClassFactoryImpl *This = impl_from_IClassFactory(iface);
+
+ TRACE("%p %s %p\n",This,debugstr_guid(riid),ppobj);
+
+ if( IsEqualCLSID( riid, &IID_IUnknown ) ||
+ IsEqualCLSID( riid, &IID_IClassFactory ) )
+ {
+ IClassFactory_AddRef( iface );
+ *ppobj = iface;
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
+{
+ LockModule();
+ return 2;
+}
+
+static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
+{
+ UnlockModule();
+ return 1;
+}
+
+static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
+ LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
+{
+ IClassFactoryImpl *This = impl_from_IClassFactory(iface);
+ IUnknown *unk = NULL;
+ HRESULT r;
+
+ TRACE("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
+
+ r = This->create_object( pOuter, (LPVOID*) &unk );
+ if (SUCCEEDED(r))
+ {
+ r = IUnknown_QueryInterface( unk, riid, ppobj );
+ IUnknown_Release( unk );
+ }
+ return r;
+}
+
+static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
+{
+ TRACE("%p %d\n", iface, dolock);
+
+ if (dolock)
+ LockModule();
+ else
+ UnlockModule();
+
+ return S_OK;
+}
+
+static const IClassFactoryVtbl MsiCF_Vtbl =
+{
+ MsiCF_QueryInterface,
+ MsiCF_AddRef,
+ MsiCF_Release,
+ MsiCF_CreateInstance,
+ MsiCF_LockServer
+};
+
+static IClassFactoryImpl MsiServer_CF = { { &MsiCF_Vtbl }, create_msiserver };
+static IClassFactoryImpl WineMsiCustomRemote_CF = { { &MsiCF_Vtbl }, create_msi_custom_remote };
+static IClassFactoryImpl WineMsiRemotePackage_CF = { { &MsiCF_Vtbl }, create_msi_remote_package };
+
+/******************************************************************
+ * DllGetClassObject [MSI.@]
+ */
+HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+ TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+
+ if ( IsEqualCLSID (rclsid, &CLSID_MsiInstaller) )
+ {
+ *ppv = &MsiServer_CF;
+ return S_OK;
+ }
+
+ if ( IsEqualCLSID (rclsid, &CLSID_WineMsiRemoteCustomAction) )
+ {
+ *ppv = &WineMsiCustomRemote_CF;
+ return S_OK;
+ }
+
+ if ( IsEqualCLSID (rclsid, &CLSID_WineMsiRemotePackage) )
+ {
+ *ppv = &WineMsiRemotePackage_CF;
+ return S_OK;
+ }
+
+ if( IsEqualCLSID (rclsid, &CLSID_MsiServerMessage) ||
+ IsEqualCLSID (rclsid, &CLSID_MsiServer) ||
+ IsEqualCLSID (rclsid, &CLSID_PSFactoryBuffer) ||
+ IsEqualCLSID (rclsid, &CLSID_MsiServerX3) )
+ {
+ FIXME("create %s object\n", debugstr_guid( rclsid ));
+ }
+
+ return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+/******************************************************************
+ * DllGetVersion [MSI.@]
+ */
+HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *pdvi)
+{
+ TRACE("%p\n",pdvi);
+
+ if (pdvi->cbSize < sizeof(DLLVERSIONINFO))
+ return E_INVALIDARG;
+
+ pdvi->dwMajorVersion = MSI_MAJORVERSION;
+ pdvi->dwMinorVersion = MSI_MINORVERSION;
+ pdvi->dwBuildNumber = MSI_BUILDNUMBER;
+ pdvi->dwPlatformID = DLLVER_PLATFORM_WINDOWS;
+
+ return S_OK;
+}
+
+/******************************************************************
+ * DllCanUnloadNow [MSI.@]
+ */
+HRESULT WINAPI DllCanUnloadNow(void)
+{
+ return dll_count == 0 ? S_OK : S_FALSE;
+}
+
+/***********************************************************************
+ * DllRegisterServer (MSI.@)
+ */
+HRESULT WINAPI DllRegisterServer(void)
+{
+ return __wine_register_resources( msi_hInstance );
+}
+
+/***********************************************************************
+ * DllUnregisterServer (MSI.@)
+ */
+HRESULT WINAPI DllUnregisterServer(void)
+{
+ return __wine_unregister_resources( msi_hInstance );
+}