a2b3f3222859f3939eac1011ab17d0fff5bf4fa3
[reactos.git] / reactos / dll / win32 / 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 preview->dialog = 0;
58 msiobj_addref( &package->hdr );
59 }
60 msiobj_release( &package->hdr );
61 }
62 return preview;
63 }
64
65 UINT WINAPI MsiEnableUIPreview( MSIHANDLE hdb, MSIHANDLE* phPreview )
66 {
67 MSIDATABASE *db;
68 MSIPREVIEW *preview;
69 UINT r = ERROR_FUNCTION_FAILED;
70
71 TRACE("%d %p\n", hdb, phPreview);
72
73 db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
74 if( !db )
75 {
76 IWineMsiRemoteDatabase *remote_database;
77
78 remote_database = (IWineMsiRemoteDatabase *)msi_get_remote( hdb );
79 if ( !remote_database )
80 return ERROR_INVALID_HANDLE;
81
82 *phPreview = 0;
83
84 IWineMsiRemoteDatabase_Release( remote_database );
85 WARN("MsiEnableUIPreview not allowed during a custom action!\n");
86
87 return ERROR_FUNCTION_FAILED;
88 }
89
90 preview = MSI_EnableUIPreview( db );
91 if( preview )
92 {
93 *phPreview = alloc_msihandle( &preview->hdr );
94 msiobj_release( &preview->hdr );
95 r = ERROR_SUCCESS;
96 if (! *phPreview)
97 r = ERROR_NOT_ENOUGH_MEMORY;
98 }
99 msiobj_release( &db->hdr );
100
101 return r;
102 }
103
104 static UINT preview_event_handler( MSIPACKAGE *package, LPCWSTR event,
105 LPCWSTR argument, msi_dialog *dialog )
106 {
107 MESSAGE("Preview dialog event '%s' (arg='%s')\n",
108 debugstr_w( event ), debugstr_w( argument ));
109 return ERROR_SUCCESS;
110 }
111
112 static UINT MSI_PreviewDialogW( MSIPREVIEW *preview, LPCWSTR szDialogName )
113 {
114 msi_dialog *dialog = NULL;
115 UINT r = ERROR_SUCCESS;
116
117 if( preview->dialog )
118 msi_dialog_destroy( preview->dialog );
119
120 /* an empty name means we should just destroy the current preview dialog */
121 if( szDialogName )
122 {
123 dialog = msi_dialog_create( preview->package, szDialogName, NULL,
124 preview_event_handler );
125 if( dialog )
126 msi_dialog_do_preview( dialog );
127 else
128 r = ERROR_FUNCTION_FAILED;
129 }
130 preview->dialog = dialog;
131
132 return r;
133 }
134
135 UINT WINAPI MsiPreviewDialogW( MSIHANDLE hPreview, LPCWSTR szDialogName )
136 {
137 MSIPREVIEW *preview;
138 UINT r;
139
140 TRACE("%d %s\n", hPreview, debugstr_w(szDialogName));
141
142 preview = msihandle2msiinfo( hPreview, MSIHANDLETYPE_PREVIEW );
143 if( !preview )
144 return ERROR_INVALID_HANDLE;
145
146 r = MSI_PreviewDialogW( preview, szDialogName );
147
148 msiobj_release( &preview->hdr );
149
150 return r;
151 }
152
153 UINT WINAPI MsiPreviewDialogA( MSIHANDLE hPreview, LPCSTR szDialogName )
154 {
155 UINT r;
156 LPWSTR strW = NULL;
157
158 TRACE("%d %s\n", hPreview, debugstr_a(szDialogName));
159
160 if( szDialogName )
161 {
162 strW = strdupAtoW( szDialogName );
163 if( !strW )
164 return ERROR_OUTOFMEMORY;
165 }
166 r = MsiPreviewDialogW( hPreview, strW );
167 msi_free( strW );
168 return r;
169 }
170
171 UINT WINAPI MsiPreviewBillboardW( MSIHANDLE hPreview, LPCWSTR szControlName,
172 LPCWSTR szBillboard)
173 {
174 FIXME("%d %s %s\n", hPreview, debugstr_w(szControlName),
175 debugstr_w(szBillboard));
176 return ERROR_CALL_NOT_IMPLEMENTED;
177 }
178
179 UINT WINAPI MsiPreviewBillboardA( MSIHANDLE hPreview, LPCSTR szControlName,
180 LPCSTR szBillboard)
181 {
182 FIXME("%d %s %s\n", hPreview, debugstr_a(szControlName),
183 debugstr_a(szBillboard));
184 return ERROR_CALL_NOT_IMPLEMENTED;
185 }