| /* |
| * Implementation of the Microsoft Installer (msi.dll) |
| * |
| * Copyright 2002 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| #define NONAMELESSUNION |
| |
| #include <stdarg.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winreg.h" |
| #include "winnls.h" |
| #include "shlwapi.h" |
| #include "wine/debug.h" |
| #include "msi.h" |
| #include "msiquery.h" |
| #include "msipriv.h" |
| #include "objidl.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(msi); |
| |
| const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y', |
| 'I','n','f','o','r','m','a','t','i','o','n',0 }; |
| |
| static void MSI_CloseSummaryInfo( VOID *arg ) |
| { |
| MSISUMMARYINFO *suminfo = (MSISUMMARYINFO *) arg; |
| IPropertyStorage_Release( suminfo->propstg ); |
| } |
| |
| UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase, |
| LPCSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo) |
| { |
| LPWSTR szwDatabase = NULL; |
| UINT ret; |
| |
| TRACE("%ld %s %d %p\n", hDatabase, debugstr_a(szDatabase), |
| uiUpdateCount, phSummaryInfo); |
| |
| if( szDatabase ) |
| { |
| UINT len = MultiByteToWideChar( CP_ACP, 0, szDatabase, -1, NULL, 0 ); |
| szwDatabase = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); |
| if( !szwDatabase ) |
| return ERROR_FUNCTION_FAILED; |
| MultiByteToWideChar( CP_ACP, 0, szDatabase, -1, szwDatabase, len ); |
| } |
| |
| ret = MsiGetSummaryInformationW(hDatabase, szwDatabase, uiUpdateCount, phSummaryInfo); |
| |
| if( szwDatabase ) |
| HeapFree( GetProcessHeap(), 0, szwDatabase ); |
| |
| return ret; |
| } |
| |
| UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, |
| LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo) |
| { |
| HRESULT r; |
| MSIHANDLE handle, hdb = hDatabase; |
| MSISUMMARYINFO *suminfo; |
| MSIDATABASE *db; |
| UINT ret = ERROR_SUCCESS; |
| IPropertySetStorage *psstg = NULL; |
| IPropertyStorage *ps = NULL; |
| DWORD grfMode; |
| |
| TRACE("%ld %s %d %p\n", hDatabase, debugstr_w(szDatabase), |
| uiUpdateCount, phSummaryInfo); |
| |
| if( !phSummaryInfo ) |
| return ERROR_INVALID_PARAMETER; |
| |
| if( szDatabase ) |
| { |
| UINT res; |
| |
| res = MsiOpenDatabaseW(szDatabase, NULL, &hdb); |
| if( res != ERROR_SUCCESS ) |
| return res; |
| } |
| |
| db = msihandle2msiinfo(hdb, MSIHANDLETYPE_DATABASE); |
| if( !db ) |
| return ERROR_INVALID_PARAMETER; |
| |
| r = IStorage_QueryInterface( db->storage, |
| &IID_IPropertySetStorage, (LPVOID)&psstg); |
| if( FAILED( r ) ) |
| { |
| ERR("IStorage -> IPropertySetStorage failed\n"); |
| return ERROR_FUNCTION_FAILED; |
| } |
| ERR("storage = %p propertysetstorage = %p\n", db->storage, psstg); |
| |
| grfMode = STGM_READ | STGM_SHARE_EXCLUSIVE; |
| r = IPropertySetStorage_Open( psstg, &FMTID_SummaryInformation, grfMode, &ps ); |
| if( FAILED( r ) ) |
| { |
| ERR("failed to get IPropertyStorage r=%08lx\n",r); |
| ret = ERROR_FUNCTION_FAILED; |
| goto end; |
| } |
| |
| handle = alloc_msihandle( MSIHANDLETYPE_SUMMARYINFO, |
| sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo ); |
| if( !handle ) |
| { |
| ret = ERROR_FUNCTION_FAILED; |
| goto end; |
| } |
| |
| suminfo = msihandle2msiinfo( handle, MSIHANDLETYPE_SUMMARYINFO ); |
| if( !suminfo ) |
| { |
| ret = ERROR_FUNCTION_FAILED; |
| goto end; |
| } |
| |
| IPropertyStorage_AddRef(ps); |
| suminfo->propstg = ps; |
| *phSummaryInfo = handle; |
| |
| end: |
| if( ps ) |
| IPropertyStorage_Release(ps); |
| if( psstg ) |
| IPropertySetStorage_Release(psstg); |
| if( !hDatabase ) |
| MsiCloseHandle( hdb ); |
| |
| return ret; |
| } |
| |
| UINT WINAPI MsiSummaryInfoGetPropertyCount(MSIHANDLE hSummaryInfo, UINT *pCount) |
| { |
| MSISUMMARYINFO *suminfo; |
| |
| FIXME("%ld %p\n",hSummaryInfo, pCount); |
| |
| suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO ); |
| if( !suminfo ) |
| return ERROR_INVALID_HANDLE; |
| |
| return ERROR_CALL_NOT_IMPLEMENTED; |
| } |
| |
| UINT WINAPI MsiSummaryInfoGetPropertyA( |
| MSIHANDLE hSummaryInfo, UINT uiProperty, UINT *puiDataType, INT *piValue, |
| FILETIME *pftValue, LPSTR szValueBuf, DWORD *pcchValueBuf) |
| { |
| MSISUMMARYINFO *suminfo; |
| HRESULT r; |
| PROPSPEC spec; |
| PROPVARIANT var; |
| |
| TRACE("%ld %d %p %p %p %p %p\n", |
| hSummaryInfo, uiProperty, puiDataType, piValue, |
| pftValue, szValueBuf, pcchValueBuf); |
| |
| suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO ); |
| if( !suminfo ) |
| return ERROR_INVALID_HANDLE; |
| |
| spec.ulKind = PRSPEC_PROPID; |
| spec.DUMMYUNIONNAME.propid = uiProperty; |
| |
| r = IPropertyStorage_ReadMultiple( suminfo->propstg, 1, &spec, &var); |
| if( FAILED(r) ) |
| return ERROR_FUNCTION_FAILED; |
| |
| if( puiDataType ) |
| *puiDataType = var.vt; |
| |
| switch( var.vt ) |
| { |
| case VT_I4: |
| if( piValue ) |
| *piValue = var.DUMMYUNIONNAME.lVal; |
| break; |
| case VT_LPSTR: |
| if( pcchValueBuf && szValueBuf ) |
| { |
| lstrcpynA(szValueBuf, var.DUMMYUNIONNAME.pszVal, *pcchValueBuf ); |
| *pcchValueBuf = lstrlenA( var.DUMMYUNIONNAME.pszVal ); |
| } |
| break; |
| case VT_FILETIME: |
| if( pftValue ) |
| memcpy(pftValue, &var.DUMMYUNIONNAME.filetime, sizeof (FILETIME) ); |
| break; |
| case VT_EMPTY: |
| break; |
| default: |
| FIXME("Unknown property variant type\n"); |
| break; |
| } |
| |
| return ERROR_SUCCESS; |
| } |
| |
| UINT WINAPI MsiSummaryInfoGetPropertyW( |
| MSIHANDLE hSummaryInfo, UINT uiProperty, UINT *puiDataType, INT *piValue, |
| FILETIME *pftValue, LPWSTR szValueBuf, DWORD *pcchValueBuf) |
| { |
| FIXME("%ld %d %p %p %p %p %p\n", |
| hSummaryInfo, uiProperty, puiDataType, piValue, |
| pftValue, szValueBuf, pcchValueBuf); |
| |
| return ERROR_CALL_NOT_IMPLEMENTED; |
| } |