msi: Add support for exporting the _SummaryInformation table.
The _SummaryInformation table stores a lot of important information about an MSI database. This patch adds the ability to export that table since, like _ForceCodepage, it is stored in a different format than the other tables. Signed-off-by: Erich E. Hoover <erich.e.hoover@gmail.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
51d5242a5f
commit
79fd42fc1a
@ -974,24 +974,35 @@ static UINT msi_export_forcecodepage( HANDLE handle, UINT codepage )
|
|||||||
{
|
{
|
||||||
static const char fmt[] = "\r\n\r\n%u\t_ForceCodepage\r\n";
|
static const char fmt[] = "\r\n\r\n%u\t_ForceCodepage\r\n";
|
||||||
char data[sizeof(fmt) + 10];
|
char data[sizeof(fmt) + 10];
|
||||||
DWORD sz;
|
DWORD sz = sprintf( data, fmt, codepage );
|
||||||
|
|
||||||
sprintf( data, fmt, codepage );
|
|
||||||
|
|
||||||
sz = lstrlenA(data) + 1;
|
|
||||||
if (!WriteFile(handle, data, sz, &sz, NULL))
|
if (!WriteFile(handle, data, sz, &sz, NULL))
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table,
|
static UINT msi_export_summaryinformation( MSIDATABASE *db, HANDLE handle )
|
||||||
LPCWSTR folder, LPCWSTR file )
|
{
|
||||||
|
static const char header[] = "PropertyId\tValue\r\n"
|
||||||
|
"i2\tl255\r\n"
|
||||||
|
"_SummaryInformation\tPropertyId\r\n";
|
||||||
|
DWORD sz = ARRAY_SIZE(header) - 1;
|
||||||
|
|
||||||
|
if (!WriteFile(handle, header, sz, &sz, NULL))
|
||||||
|
return ERROR_WRITE_FAULT;
|
||||||
|
|
||||||
|
return msi_export_suminfo( db, handle );
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table, LPCWSTR folder, LPCWSTR file )
|
||||||
{
|
{
|
||||||
static const WCHAR query[] = {
|
static const WCHAR query[] = {
|
||||||
's','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','%','s',0 };
|
's','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','%','s',0 };
|
||||||
static const WCHAR forcecodepage[] = {
|
static const WCHAR forcecodepage[] = {
|
||||||
'_','F','o','r','c','e','C','o','d','e','p','a','g','e',0 };
|
'_','F','o','r','c','e','C','o','d','e','p','a','g','e',0 };
|
||||||
|
static const WCHAR summaryinformation[] = {
|
||||||
|
'_','S','u','m','m','a','r','y','I','n','f','o','r','m','a','t','i','o','n',0 };
|
||||||
MSIRECORD *rec = NULL;
|
MSIRECORD *rec = NULL;
|
||||||
MSIQUERY *view = NULL;
|
MSIQUERY *view = NULL;
|
||||||
LPWSTR filename;
|
LPWSTR filename;
|
||||||
@ -1026,6 +1037,12 @@ static UINT MSI_DatabaseExport( MSIDATABASE *db, LPCWSTR table,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmpW( table, summaryinformation ))
|
||||||
|
{
|
||||||
|
r = msi_export_summaryinformation( db, handle );
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
r = MSI_OpenQuery( db, &view, query, table );
|
r = MSI_OpenQuery( db, &view, query, table );
|
||||||
if (r == ERROR_SUCCESS)
|
if (r == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -961,6 +961,7 @@ extern LPWSTR msi_suminfo_dup_string( MSISUMMARYINFO *si, UINT uiProperty ) DECL
|
|||||||
extern INT msi_suminfo_get_int32( MSISUMMARYINFO *si, UINT uiProperty ) DECLSPEC_HIDDEN;
|
extern INT msi_suminfo_get_int32( MSISUMMARYINFO *si, UINT uiProperty ) DECLSPEC_HIDDEN;
|
||||||
extern LPWSTR msi_get_suminfo_product( IStorage *stg ) DECLSPEC_HIDDEN;
|
extern LPWSTR msi_get_suminfo_product( IStorage *stg ) DECLSPEC_HIDDEN;
|
||||||
extern UINT msi_add_suminfo( MSIDATABASE *db, LPWSTR **records, int num_records, int num_columns ) DECLSPEC_HIDDEN;
|
extern UINT msi_add_suminfo( MSIDATABASE *db, LPWSTR **records, int num_records, int num_columns ) DECLSPEC_HIDDEN;
|
||||||
|
extern UINT msi_export_suminfo( MSIDATABASE *db, HANDLE handle ) DECLSPEC_HIDDEN;
|
||||||
extern UINT msi_load_suminfo_properties( MSIPACKAGE *package ) DECLSPEC_HIDDEN;
|
extern UINT msi_load_suminfo_properties( MSIPACKAGE *package ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* undocumented functions */
|
/* undocumented functions */
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
#define NONAMELESSUNION
|
#define NONAMELESSUNION
|
||||||
|
|
||||||
|
#include "stdio.h"
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
@ -1096,6 +1097,114 @@ end:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UINT save_prop( MSISUMMARYINFO *si, HANDLE handle, UINT row )
|
||||||
|
{
|
||||||
|
static const char fmt_systemtime[] = "%04u/%02u/%02u %02u:%02u:%02u";
|
||||||
|
char data[36]; /* largest string: YYYY/MM/DD hh:mm:ss */
|
||||||
|
static const char fmt_begin[] = "%u\t";
|
||||||
|
static const char data_end[] = "\r\n";
|
||||||
|
static const char fmt_int[] = "%u";
|
||||||
|
UINT r, data_type, len;
|
||||||
|
SYSTEMTIME system_time;
|
||||||
|
FILETIME file_time;
|
||||||
|
INT int_value;
|
||||||
|
awstring str;
|
||||||
|
DWORD sz;
|
||||||
|
|
||||||
|
str.unicode = FALSE;
|
||||||
|
str.str.a = NULL;
|
||||||
|
len = 0;
|
||||||
|
r = get_prop( si, row, &data_type, &int_value, &file_time, &str, &len );
|
||||||
|
if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
|
||||||
|
return r;
|
||||||
|
if (data_type == VT_EMPTY)
|
||||||
|
return ERROR_SUCCESS; /* property not set */
|
||||||
|
sz = sprintf( data, fmt_begin, row );
|
||||||
|
if (!WriteFile( handle, data, sz, &sz, NULL ))
|
||||||
|
return ERROR_WRITE_FAULT;
|
||||||
|
|
||||||
|
switch( data_type )
|
||||||
|
{
|
||||||
|
case VT_I2:
|
||||||
|
case VT_I4:
|
||||||
|
sz = sprintf( data, fmt_int, int_value );
|
||||||
|
if (!WriteFile( handle, data, sz, &sz, NULL ))
|
||||||
|
return ERROR_WRITE_FAULT;
|
||||||
|
break;
|
||||||
|
case VT_LPSTR:
|
||||||
|
len++;
|
||||||
|
if (!(str.str.a = msi_alloc( len )))
|
||||||
|
return ERROR_OUTOFMEMORY;
|
||||||
|
r = get_prop( si, row, NULL, NULL, NULL, &str, &len );
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
msi_free( str.str.a );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
sz = len;
|
||||||
|
if (!WriteFile( handle, str.str.a, sz, &sz, NULL ))
|
||||||
|
{
|
||||||
|
msi_free( str.str.a );
|
||||||
|
return ERROR_WRITE_FAULT;
|
||||||
|
}
|
||||||
|
msi_free( str.str.a );
|
||||||
|
break;
|
||||||
|
case VT_FILETIME:
|
||||||
|
if (!FileTimeToSystemTime( &file_time, &system_time ))
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
sz = sprintf( data, fmt_systemtime, system_time.wYear, system_time.wMonth,
|
||||||
|
system_time.wDay, system_time.wHour, system_time.wMinute,
|
||||||
|
system_time.wSecond );
|
||||||
|
if (!WriteFile( handle, data, sz, &sz, NULL ))
|
||||||
|
return ERROR_WRITE_FAULT;
|
||||||
|
break;
|
||||||
|
case VT_EMPTY:
|
||||||
|
/* cannot reach here, property not set */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FIXME( "Unknown property variant type\n" );
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
sz = ARRAY_SIZE(data_end) - 1;
|
||||||
|
if (!WriteFile( handle, data_end, sz, &sz, NULL ))
|
||||||
|
return ERROR_WRITE_FAULT;
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT msi_export_suminfo( MSIDATABASE *db, HANDLE handle )
|
||||||
|
{
|
||||||
|
UINT i, r, num_rows;
|
||||||
|
MSISUMMARYINFO *si;
|
||||||
|
|
||||||
|
r = msi_get_suminfo( db->storage, 0, &si );
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
r = msi_get_db_suminfo( db, 0, &si );
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
num_rows = get_property_count( si->property );
|
||||||
|
if (!num_rows)
|
||||||
|
{
|
||||||
|
msiobj_release( &si->hdr );
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_rows; i++)
|
||||||
|
{
|
||||||
|
r = save_prop( si, handle, i );
|
||||||
|
if (r != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
msiobj_release( &si->hdr );
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msiobj_release( &si->hdr );
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiSummaryInfoPersist( MSIHANDLE handle )
|
UINT WINAPI MsiSummaryInfoPersist( MSIHANDLE handle )
|
||||||
{
|
{
|
||||||
MSISUMMARYINFO *si;
|
MSISUMMARYINFO *si;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user