WIN_ListParents no longer needs to be exported, make it static.
[wine] / dlls / msi / suminfo.c
1 /*
2  * Implementation of the Microsoft Installer (msi.dll)
3  *
4  * Copyright 2002 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "winnls.h"
30 #include "shlwapi.h"
31 #include "wine/debug.h"
32 #include "msi.h"
33 #include "msiquery.h"
34 #include "msipriv.h"
35 #include "objidl.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(msi);
38
39 static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y',
40                        'I','n','f','o','r','m','a','t','i','o','n',0 };
41
42 static void MSI_CloseSummaryInfo( MSIOBJECTHDR *arg )
43 {
44     MSISUMMARYINFO *suminfo = (MSISUMMARYINFO *) arg;
45     IPropertyStorage_Release( suminfo->propstg );
46 }
47
48 UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase, 
49               LPCSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo)
50 {
51     LPWSTR szwDatabase = NULL;
52     UINT ret;
53
54     TRACE("%ld %s %d %p\n", hDatabase, debugstr_a(szDatabase), 
55           uiUpdateCount, phSummaryInfo);
56
57     if( szDatabase )
58     {
59         UINT len = MultiByteToWideChar( CP_ACP, 0, szDatabase, -1, NULL, 0 );
60         szwDatabase = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
61         if( !szwDatabase )
62             return ERROR_FUNCTION_FAILED;
63         MultiByteToWideChar( CP_ACP, 0, szDatabase, -1, szwDatabase, len );
64     }
65
66     ret = MsiGetSummaryInformationW(hDatabase, szwDatabase, uiUpdateCount, phSummaryInfo);
67
68     HeapFree( GetProcessHeap(), 0, szwDatabase );
69
70     return ret;
71 }
72
73 UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, 
74               LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo)
75 {
76     HRESULT r;
77     MSIHANDLE handle;
78     MSISUMMARYINFO *suminfo;
79     MSIDATABASE *db;
80     UINT ret = ERROR_SUCCESS;
81     IPropertySetStorage *psstg = NULL;
82     IPropertyStorage *ps = NULL;
83     DWORD grfMode;
84
85     TRACE("%ld %s %d %p\n", hDatabase, debugstr_w(szDatabase),
86            uiUpdateCount, phSummaryInfo);
87
88     if( !phSummaryInfo )
89         return ERROR_INVALID_PARAMETER;
90
91     if( szDatabase )
92     {
93         UINT res;
94
95         res = MSI_OpenDatabaseW(szDatabase, NULL, &db);
96         if( res != ERROR_SUCCESS )
97             return res;
98     }
99     else
100     {
101         db = msihandle2msiinfo(hDatabase, MSIHANDLETYPE_DATABASE);
102         if( !db )
103             return ERROR_INVALID_PARAMETER;
104     }
105
106     r = IStorage_QueryInterface( db->storage, 
107              &IID_IPropertySetStorage, (LPVOID)&psstg);
108     if( FAILED( r ) )
109     {
110         ERR("IStorage -> IPropertySetStorage failed\n");
111         if (db)
112             msiobj_release(&db->hdr);
113         return ERROR_FUNCTION_FAILED;
114     }
115     ERR("storage = %p propertysetstorage = %p\n", db->storage, psstg);
116
117     grfMode = STGM_READ | STGM_SHARE_EXCLUSIVE;
118     r = IPropertySetStorage_Open( psstg, &FMTID_SummaryInformation, grfMode, &ps );
119     if( FAILED( r ) )
120     {
121         ERR("failed to get IPropertyStorage r=%08lx\n",r);
122         ret = ERROR_FUNCTION_FAILED;
123         goto end;
124     }
125
126     suminfo = alloc_msiobject( MSIHANDLETYPE_SUMMARYINFO, 
127                   sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo );
128     if( !suminfo )
129     {
130         ret = ERROR_FUNCTION_FAILED;
131         goto end;
132     }
133
134     IPropertyStorage_AddRef(ps);
135     suminfo->propstg = ps;
136     handle = alloc_msihandle( &suminfo->hdr );
137     if( handle )
138     *phSummaryInfo = handle;
139     else
140         ret = ERROR_FUNCTION_FAILED;
141     msiobj_release( &suminfo->hdr );
142
143 end:
144     if( ps )
145         IPropertyStorage_Release(ps);
146     if( psstg )
147         IPropertySetStorage_Release(psstg);
148     if (db)
149         msiobj_release(&db->hdr);
150
151     return ret;
152 }
153
154 UINT WINAPI MsiSummaryInfoGetPropertyCount(MSIHANDLE hSummaryInfo, UINT *pCount)
155 {
156     MSISUMMARYINFO *suminfo;
157
158     FIXME("%ld %p\n",hSummaryInfo, pCount);
159
160     suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO );
161     if( !suminfo )
162         return ERROR_INVALID_HANDLE;
163
164     return ERROR_CALL_NOT_IMPLEMENTED;
165 }
166
167 UINT WINAPI MsiSummaryInfoGetPropertyA(
168       MSIHANDLE hSummaryInfo, UINT uiProperty, UINT *puiDataType, INT *piValue,
169       FILETIME *pftValue, LPSTR szValueBuf, DWORD *pcchValueBuf)
170 {
171     MSISUMMARYINFO *suminfo;
172     HRESULT r;
173     PROPSPEC spec;
174     PROPVARIANT var;
175
176     TRACE("%ld %d %p %p %p %p %p\n",
177         hSummaryInfo, uiProperty, puiDataType, piValue,
178         pftValue, szValueBuf, pcchValueBuf);
179
180     suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO );
181     if( !suminfo )
182         return ERROR_INVALID_HANDLE;
183
184     spec.ulKind = PRSPEC_PROPID;
185     spec.u.propid = uiProperty;
186
187     r = IPropertyStorage_ReadMultiple( suminfo->propstg, 1, &spec, &var);
188     if( FAILED(r) )
189         return ERROR_FUNCTION_FAILED;
190
191     if( puiDataType )
192         *puiDataType = var.vt;
193
194     switch( var.vt )
195     {
196     case VT_I4:
197         if( piValue )
198             *piValue = var.u.lVal;
199         break;
200     case VT_LPSTR:
201         if( pcchValueBuf && szValueBuf )
202         {
203             lstrcpynA(szValueBuf, var.u.pszVal, *pcchValueBuf );
204             *pcchValueBuf = lstrlenA( var.u.pszVal );
205         }
206         break;
207     case VT_FILETIME:
208         if( pftValue )
209             memcpy(pftValue, &var.u.filetime, sizeof (FILETIME) );
210         break;
211     case VT_EMPTY:
212         break;
213     default:
214         FIXME("Unknown property variant type\n");
215         break;
216     }
217
218     return ERROR_SUCCESS;
219 }
220
221 UINT WINAPI MsiSummaryInfoGetPropertyW(
222       MSIHANDLE hSummaryInfo, UINT uiProperty, UINT *puiDataType, INT *piValue,
223       FILETIME *pftValue, LPWSTR szValueBuf, DWORD *pcchValueBuf)
224 {
225     MSISUMMARYINFO *suminfo;
226     HRESULT r;
227     PROPSPEC spec;
228     PROPVARIANT var;
229
230     TRACE("%ld %d %p %p %p %p %p\n",
231         hSummaryInfo, uiProperty, puiDataType, piValue,
232         pftValue, szValueBuf, pcchValueBuf);
233
234     suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO );
235     if( !suminfo )
236         return ERROR_INVALID_HANDLE;
237
238     spec.ulKind = PRSPEC_PROPID;
239     spec.u.propid = uiProperty;
240
241     r = IPropertyStorage_ReadMultiple( suminfo->propstg, 1, &spec, &var);
242     if( FAILED(r) )
243         return ERROR_FUNCTION_FAILED;
244
245     if( puiDataType )
246         *puiDataType = var.vt;
247
248     switch( var.vt )
249     {
250     case VT_I4:
251         if( piValue )
252             *piValue = var.u.lVal;
253         break;
254     case VT_LPSTR:
255         if( pcchValueBuf && szValueBuf )
256         {
257             MultiByteToWideChar(CP_ACP, 0,  var.u.pszVal, -1, szValueBuf, 
258                                 *pcchValueBuf );
259             *pcchValueBuf = lstrlenA( var.u.pszVal );
260         }
261         break;
262     case VT_FILETIME:
263         if( pftValue )
264             memcpy(pftValue, &var.u.filetime, sizeof (FILETIME) );
265         break;
266     case VT_EMPTY:
267         break;
268     default:
269         FIXME("Unknown property variant type\n");
270         break;
271     }
272
273     return ERROR_SUCCESS;
274 }