odbccp32: Fix SQLInstallDriverManager{,W}.
[wine] / dlls / msi / preview.c
1 /*
2  * Implementation of the Microsoft Installer (msi.dll)
3  *
4  * Copyright 2005 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 #define COBJMACROS
22
23 #include <stdarg.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winnls.h"
28 #include "msi.h"
29 #include "msipriv.h"
30 #include "msiserver.h"
31
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(msi);
36
37 static void MSI_ClosePreview( MSIOBJECTHDR *arg )
38 {
39     MSIPREVIEW *preview = (MSIPREVIEW *) arg;
40
41     msiobj_release( &preview->package->hdr );
42 }
43
44 static MSIPREVIEW *MSI_EnableUIPreview( MSIDATABASE *db )
45 {
46     MSIPREVIEW *preview = NULL;
47     MSIPACKAGE *package;
48
49     package = MSI_CreatePackage( db, NULL );
50     if( package )
51     {
52         preview = alloc_msiobject( MSIHANDLETYPE_PREVIEW, sizeof (MSIPREVIEW),
53                                MSI_ClosePreview );
54         if( preview )
55         {
56             preview->package = package;
57             msiobj_addref( &package->hdr );
58         }
59         msiobj_release( &package->hdr );
60     }
61     return preview;
62 }
63
64 UINT WINAPI MsiEnableUIPreview( MSIHANDLE hdb, MSIHANDLE* phPreview )
65 {
66     MSIDATABASE *db;
67     MSIPREVIEW *preview;
68     UINT r = ERROR_FUNCTION_FAILED;
69
70     TRACE("%d %p\n", hdb, phPreview);
71
72     db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
73     if( !db )
74     {
75         IWineMsiRemoteDatabase *remote_database;
76
77         remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
78         if ( !remote_database )
79             return ERROR_INVALID_HANDLE;
80
81         *phPreview = 0;
82
83         IWineMsiRemoteDatabase_Release( remote_database );
84         WARN("MsiEnableUIPreview not allowed during a custom action!\n");
85
86         return ERROR_FUNCTION_FAILED;
87     }
88
89     preview = MSI_EnableUIPreview( db );
90     if( preview )
91     {
92         *phPreview = alloc_msihandle( &preview->hdr );
93         msiobj_release( &preview->hdr );
94         r = ERROR_SUCCESS;
95         if (! *phPreview)
96             r = ERROR_NOT_ENOUGH_MEMORY;
97     }
98     msiobj_release( &db->hdr );
99
100     return r;
101 }
102
103 static UINT preview_event_handler( MSIPACKAGE *package, LPCWSTR event,
104                                    LPCWSTR argument, msi_dialog *dialog )
105 {
106     MESSAGE("Preview dialog event '%s' (arg='%s')\n",
107             debugstr_w( event ), debugstr_w( argument ));
108     return ERROR_SUCCESS;
109 }
110
111 static UINT MSI_PreviewDialogW( MSIPREVIEW *preview, LPCWSTR szDialogName )
112 {
113     msi_dialog *dialog = NULL;
114     UINT r = ERROR_SUCCESS;
115
116     if( preview->dialog )
117         msi_dialog_destroy( preview->dialog );
118
119     /* an empty name means we should just destroy the current preview dialog */
120     if( szDialogName )
121     {
122         dialog = msi_dialog_create( preview->package, szDialogName, NULL,
123                                     preview_event_handler );
124         if( dialog )
125             msi_dialog_do_preview( dialog );
126         else
127             r = ERROR_FUNCTION_FAILED;
128     }
129     preview->dialog = dialog;
130
131     return r;
132 }
133
134 UINT WINAPI MsiPreviewDialogW( MSIHANDLE hPreview, LPCWSTR szDialogName )
135 {
136     MSIPREVIEW *preview;
137     UINT r;
138
139     TRACE("%d %s\n", hPreview, debugstr_w(szDialogName));
140
141     preview = msihandle2msiinfo( hPreview, MSIHANDLETYPE_PREVIEW );
142     if( !preview )
143         return ERROR_INVALID_HANDLE;
144
145     r = MSI_PreviewDialogW( preview, szDialogName );
146
147     msiobj_release( &preview->hdr );
148
149     return r;
150 }
151
152 UINT WINAPI MsiPreviewDialogA( MSIHANDLE hPreview, LPCSTR szDialogName )
153 {
154     UINT r;
155     LPWSTR strW = NULL;
156
157     TRACE("%d %s\n", hPreview, debugstr_a(szDialogName));
158
159     if( szDialogName )
160     {
161         strW = strdupAtoW( szDialogName );
162         if( !strW )
163             return ERROR_OUTOFMEMORY;
164     }
165     r = MsiPreviewDialogW( hPreview, strW );
166     msi_free( strW );
167     return r;
168 }
169
170 UINT WINAPI MsiPreviewBillboardW( MSIHANDLE hPreview, LPCWSTR szControlName,
171                                   LPCWSTR szBillboard)
172 {
173     FIXME("%d %s %s\n", hPreview, debugstr_w(szControlName),
174           debugstr_w(szBillboard));
175     return ERROR_CALL_NOT_IMPLEMENTED;
176 }
177
178 UINT WINAPI MsiPreviewBillboardA( MSIHANDLE hPreview, LPCSTR szControlName,
179                                   LPCSTR szBillboard)
180 {
181     FIXME("%d %s %s\n", hPreview, debugstr_a(szControlName),
182           debugstr_a(szBillboard));
183     return ERROR_CALL_NOT_IMPLEMENTED;
184 }