/* * 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 */ #include #define COBJMACROS #define NONAMELESSUNION #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); static 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( MSIOBJECTHDR *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); HeapFree( GetProcessHeap(), 0, szwDatabase ); return ret; } UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo) { HRESULT r; MSIHANDLE handle; 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 = MSI_OpenDatabaseW(szDatabase, NULL, &db); if( res != ERROR_SUCCESS ) return res; } else { db = msihandle2msiinfo(hDatabase, 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"); ret = ERROR_FUNCTION_FAILED; goto end; } 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; } suminfo = alloc_msiobject( MSIHANDLETYPE_SUMMARYINFO, sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo ); if( !suminfo ) { ret = ERROR_FUNCTION_FAILED; goto end; } IPropertyStorage_AddRef(ps); suminfo->propstg = ps; handle = alloc_msihandle( &suminfo->hdr ); if( handle ) *phSummaryInfo = handle; else ret = ERROR_FUNCTION_FAILED; msiobj_release( &suminfo->hdr ); end: if( ps ) IPropertyStorage_Release(ps); if( psstg ) IPropertySetStorage_Release(psstg); if( db ) msiobj_release(&db->hdr); 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.u.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.u.lVal; break; case VT_LPSTR: if( pcchValueBuf && szValueBuf ) { lstrcpynA(szValueBuf, var.u.pszVal, *pcchValueBuf ); *pcchValueBuf = lstrlenA( var.u.pszVal ); } break; case VT_FILETIME: if( pftValue ) memcpy(pftValue, &var.u.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) { 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.u.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.u.lVal; break; case VT_LPSTR: if( pcchValueBuf && szValueBuf ) { MultiByteToWideChar(CP_ACP, 0, var.u.pszVal, -1, szValueBuf, *pcchValueBuf ); *pcchValueBuf = lstrlenA( var.u.pszVal ); } break; case VT_FILETIME: if( pftValue ) memcpy(pftValue, &var.u.filetime, sizeof (FILETIME) ); break; case VT_EMPTY: break; default: FIXME("Unknown property variant type\n"); break; } return ERROR_SUCCESS; } UINT WINAPI MsiSummaryInfoSetPropertyA( MSIHANDLE hSummaryInfo, UINT uiProperty, UINT uiDataType, INT iValue, FILETIME* pftValue, LPSTR szValue ) { FIXME("%ld %u %u %i %p %s\n", hSummaryInfo, uiProperty, uiDataType, iValue, pftValue, debugstr_a(szValue) ); return ERROR_CALL_NOT_IMPLEMENTED; } UINT WINAPI MsiSummaryInfoSetPropertyW( MSIHANDLE hSummaryInfo, UINT uiProperty, UINT uiDataType, INT iValue, FILETIME* pftValue, LPWSTR szValue ) { FIXME("%ld %u %u %i %p %s\n", hSummaryInfo, uiProperty, uiDataType, iValue, pftValue, debugstr_w(szValue) ); return ERROR_CALL_NOT_IMPLEMENTED; } UINT WINAPI MsiSummaryInfoPersist( MSIHANDLE hSummaryInfo ) { FIXME("%ld\n", hSummaryInfo ); return ERROR_CALL_NOT_IMPLEMENTED; }