/* * 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 "windef.h" #include "winbase.h" #include "winreg.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 ) { szwDatabase = HEAP_strdupAtoW( GetProcessHeap(), 0, szDatabase ); if( !szwDatabase ) return ERROR_FUNCTION_FAILED; } 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; }