ReactOS 0.4.15-dev-7942-gd23573b
database.c File Reference
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winnls.h"
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "msipriv.h"
#include "objidl.h"
#include "objbase.h"
#include "msiserver.h"
#include "query.h"
#include "initguid.h"
Include dependency graph for database.c:

Go to the source code of this file.

Classes

struct  row_export_info
 
struct  _tagMERGETABLE
 
struct  _tagMERGEROW
 
struct  _tagMERGEDATA
 

Macros

#define COBJMACROS
 
#define IS_INTMSIDBOPEN(x)   (((ULONG_PTR)(x) >> 16) == 0)
 

Typedefs

typedef struct _tagMERGETABLE MERGETABLE
 
typedef struct _tagMERGEROW MERGEROW
 
typedef struct _tagMERGEDATA MERGEDATA
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msi)
 
static void free_transforms (MSIDATABASE *db)
 
static void free_streams (MSIDATABASE *db)
 
void append_storage_to_db (MSIDATABASE *db, IStorage *stg)
 
static VOID MSI_CloseDatabase (MSIOBJECTHDR *arg)
 
static HRESULT db_initialize (IStorage *stg, const GUID *clsid)
 
UINT MSI_OpenDatabaseW (LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
 
UINT WINAPI MsiOpenDatabaseW (LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
 
UINT WINAPI MsiOpenDatabaseA (LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
 
static LPWSTR msi_read_text_archive (LPCWSTR path, DWORD *len)
 
static void msi_parse_line (LPWSTR *line, LPWSTR **entries, DWORD *num_entries, DWORD *len)
 
static LPWSTR msi_build_createsql_prelude (LPWSTR table)
 
static LPWSTR msi_build_createsql_columns (LPWSTR *columns_data, LPWSTR *types, DWORD num_columns)
 
static LPWSTR msi_build_createsql_postlude (LPWSTR *primary_keys, DWORD num_keys)
 
static UINT msi_add_table_to_db (MSIDATABASE *db, LPWSTR *columns, LPWSTR *types, LPWSTR *labels, DWORD num_labels, DWORD num_columns)
 
static LPWSTR msi_import_stream_filename (LPCWSTR path, LPCWSTR name)
 
static UINT construct_record (DWORD num_columns, LPWSTR *types, LPWSTR *data, LPWSTR path, MSIRECORD **rec)
 
static UINT msi_add_records_to_table (MSIDATABASE *db, LPWSTR *columns, LPWSTR *types, LPWSTR *labels, LPWSTR **records, int num_columns, int num_records, LPWSTR path)
 
static UINT MSI_DatabaseImport (MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
 
UINT WINAPI MsiDatabaseImportW (MSIHANDLE handle, const WCHAR *szFolder, const WCHAR *szFilename)
 
UINT WINAPI MsiDatabaseImportA (MSIHANDLE handle, const char *szFolder, const char *szFilename)
 
static UINT msi_export_field (HANDLE handle, MSIRECORD *row, UINT field)
 
static UINT msi_export_stream (const WCHAR *folder, const WCHAR *table, MSIRECORD *row, UINT field, UINT start)
 
static UINT msi_export_record (struct row_export_info *row_export_info, MSIRECORD *row, UINT start)
 
static UINT msi_export_row (MSIRECORD *row, void *arg)
 
static UINT msi_export_forcecodepage (HANDLE handle, UINT codepage)
 
static UINT msi_export_summaryinformation (MSIDATABASE *db, HANDLE handle)
 
static UINT MSI_DatabaseExport (MSIDATABASE *db, LPCWSTR table, LPCWSTR folder, LPCWSTR file)
 
UINT WINAPI MsiDatabaseExportW (MSIHANDLE handle, const WCHAR *szTable, const WCHAR *szFolder, const WCHAR *szFilename)
 
UINT WINAPI MsiDatabaseExportA (MSIHANDLE handle, const char *szTable, const char *szFolder, const char *szFilename)
 
UINT WINAPI MsiDatabaseMergeA (MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge, const char *szTableName)
 
static BOOL merge_type_match (LPCWSTR type1, LPCWSTR type2)
 
static UINT merge_verify_colnames (MSIQUERY *dbview, MSIQUERY *mergeview)
 
static UINT merge_verify_primary_keys (MSIDATABASE *db, MSIDATABASE *mergedb, LPCWSTR table)
 
static LPWSTR get_key_value (MSIQUERY *view, LPCWSTR key, MSIRECORD *rec)
 
static LPWSTR create_diff_row_query (MSIDATABASE *merge, MSIQUERY *view, LPWSTR table, MSIRECORD *rec)
 
static UINT merge_diff_row (MSIRECORD *rec, LPVOID param)
 
static UINT msi_get_table_labels (MSIDATABASE *db, LPCWSTR table, LPWSTR **labels, DWORD *numlabels)
 
static UINT msi_get_query_columns (MSIQUERY *query, LPWSTR **columns, DWORD *numcolumns)
 
static UINT msi_get_query_types (MSIQUERY *query, LPWSTR **types, DWORD *numtypes)
 
static void merge_free_rows (MERGETABLE *table)
 
static void free_merge_table (MERGETABLE *table)
 
static UINT msi_get_merge_table (MSIDATABASE *db, LPCWSTR name, MERGETABLE **ptable)
 
static UINT merge_diff_tables (MSIRECORD *rec, LPVOID param)
 
static UINT gather_merge_data (MSIDATABASE *db, MSIDATABASE *merge, struct list *tabledata)
 
static UINT merge_table (MSIDATABASE *db, MERGETABLE *table)
 
static UINT update_merge_errors (MSIDATABASE *db, LPCWSTR error, LPWSTR table, DWORD numconflicts)
 
UINT WINAPI MsiDatabaseMergeW (MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge, const WCHAR *szTableName)
 
MSIDBSTATE WINAPI MsiGetDatabaseState (MSIHANDLE handle)
 
MSICONDITION __cdecl s_remote_DatabaseIsTablePersistent (MSIHANDLE db, LPCWSTR table)
 
UINT __cdecl s_remote_DatabaseGetPrimaryKeys (MSIHANDLE db, LPCWSTR table, struct wire_record **rec)
 
UINT __cdecl s_remote_DatabaseGetSummaryInformation (MSIHANDLE db, UINT updatecount, MSIHANDLE *suminfo)
 
UINT __cdecl s_remote_DatabaseOpenView (MSIHANDLE db, LPCWSTR query, MSIHANDLE *view)
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 24 of file database.c.

◆ IS_INTMSIDBOPEN

#define IS_INTMSIDBOPEN (   x)    (((ULONG_PTR)(x) >> 16) == 0)

Definition at line 53 of file database.c.

Typedef Documentation

◆ MERGEDATA

◆ MERGEROW

◆ MERGETABLE

Function Documentation

◆ append_storage_to_db()

void append_storage_to_db ( MSIDATABASE db,
IStorage stg 
)

Definition at line 76 of file database.c.

77{
79
80 t = msi_alloc( sizeof *t );
81 t->stg = stg;
82 IStorage_AddRef( stg );
83 list_add_head( &db->transforms, &t->entry );
84}
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
GLdouble GLdouble t
Definition: gl.h:2047
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
struct list transforms
Definition: msipriv.h:119

Referenced by msi_table_apply_transform().

◆ construct_record()

static UINT construct_record ( DWORD  num_columns,
LPWSTR types,
LPWSTR data,
LPWSTR  path,
MSIRECORD **  rec 
)
static

Definition at line 646 of file database.c.

648{
649 UINT i;
650
651 *rec = MSI_CreateRecord(num_columns);
652 if (!*rec)
653 return ERROR_OUTOFMEMORY;
654
655 for (i = 0; i < num_columns; i++)
656 {
657 switch (types[i][0])
658 {
659 case 'L': case 'l': case 'S': case 's':
660 MSI_RecordSetStringW(*rec, i + 1, data[i]);
661 break;
662 case 'I': case 'i':
663 if (*data[i])
664 MSI_RecordSetInteger(*rec, i + 1, wcstol(data[i], NULL, 10));
665 break;
666 case 'V': case 'v':
667 if (*data[i])
668 {
669 UINT r;
671 if (!file)
673
674 r = MSI_RecordSetStreamFromFileW(*rec, i + 1, file);
675 msi_free (file);
676 if (r != ERROR_SUCCESS)
678 }
679 break;
680 default:
681 ERR("Unhandled column type: %c\n", types[i][0]);
682 msiobj_release(&(*rec)->hdr);
684 }
685 }
686
687 return ERROR_SUCCESS;
688}
#define ERR(fmt,...)
Definition: debug.h:110
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
static LPWSTR msi_import_stream_filename(LPCWSTR path, LPCWSTR name)
Definition: database.c:622
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
UINT MSI_RecordSetStreamFromFileW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:683
static void msi_free(void *mem)
Definition: msipriv.h:1159
UINT MSI_RecordSetInteger(MSIRECORD *, UINT, int) DECLSPEC_HIDDEN
Definition: record.c:280
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:76
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:597
unsigned int UINT
Definition: ndis.h:50
Definition: fci.c:127
Definition: cmds.c:130
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by msi_add_records_to_table().

◆ create_diff_row_query()

static LPWSTR create_diff_row_query ( MSIDATABASE merge,
MSIQUERY view,
LPWSTR  table,
MSIRECORD rec 
)
static

Definition at line 1412 of file database.c.

1414{
1415 LPWSTR query = NULL, clause = NULL, val;
1416 LPCWSTR setptr, key;
1417 DWORD size, oldsize;
1418 MSIRECORD *keys;
1419 UINT r, i, count;
1420
1422 if (r != ERROR_SUCCESS)
1423 return NULL;
1424
1425 clause = msi_alloc_zero(sizeof(WCHAR));
1426 if (!clause)
1427 goto done;
1428
1429 size = 1;
1431 for (i = 1; i <= count; i++)
1432 {
1433 key = MSI_RecordGetString(keys, i);
1434 val = get_key_value(view, key, rec);
1435
1436 if (i == count)
1437 setptr = L"`%s` = %s ";
1438 else
1439 setptr = L"`%s` = %s AND ";
1440
1441 oldsize = size;
1442 size += lstrlenW(setptr) + lstrlenW(key) + lstrlenW(val) - 4;
1443 clause = msi_realloc(clause, size * sizeof (WCHAR));
1444 if (!clause)
1445 {
1446 msi_free(val);
1447 goto done;
1448 }
1449
1450 swprintf(clause + oldsize - 1, size - (oldsize - 1), setptr, key, val);
1451 msi_free(val);
1452 }
1453
1454 size = lstrlenW(L"SELECT * FROM `%s` WHERE %s") + lstrlenW(table) + lstrlenW(clause) + 1;
1455 query = msi_alloc(size * sizeof(WCHAR));
1456 if (!query)
1457 goto done;
1458
1459 swprintf(query, size, L"SELECT * FROM `%s` WHERE %s", table, clause);
1460
1461done:
1462 msi_free(clause);
1463 msiobj_release(&keys->hdr);
1464 return query;
1465}
_STLP_MOVE_TO_STD_NAMESPACE _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result)
Definition: _algo.c:1419
#define lstrlenW
Definition: compat.h:750
static LPWSTR get_key_value(MSIQUERY *view, LPCWSTR key, MSIRECORD *rec)
Definition: database.c:1354
#define swprintf
Definition: precomp.h:40
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint GLfloat * val
Definition: glext.h:7180
static void * msi_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2)
Definition: msipriv.h:1154
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:433
UINT MSI_RecordGetFieldCount(const MSIRECORD *rec) DECLSPEC_HIDDEN
Definition: record.c:108
UINT MSI_DatabaseGetPrimaryKeys(MSIDATABASE *, LPCWSTR, MSIRECORD **) DECLSPEC_HIDDEN
Definition: msiquery.c:1044
#define L(x)
Definition: ntvdm.h:50
Definition: copy.c:22
MSIOBJECTHDR hdr
Definition: msipriv.h:151
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by merge_diff_row().

◆ db_initialize()

static HRESULT db_initialize ( IStorage stg,
const GUID clsid 
)
static

Definition at line 104 of file database.c.

105{
106 HRESULT hr;
107
108 hr = IStorage_SetClass( stg, clsid );
109 if (FAILED( hr ))
110 {
111 WARN("failed to set class id %#lx\n", hr);
112 return hr;
113 }
114
115 /* create the _Tables stream */
116 hr = write_stream_data( stg, L"_Tables", NULL, 0, TRUE );
117 if (FAILED( hr ))
118 {
119 WARN("failed to create _Tables stream %#lx\n", hr);
120 return hr;
121 }
122
123 hr = msi_init_string_table( stg );
124 if (FAILED( hr ))
125 {
126 WARN("failed to initialize string table %#lx\n", hr);
127 return hr;
128 }
129
130 hr = IStorage_Commit( stg, 0 );
131 if (FAILED( hr ))
132 {
133 WARN("failed to commit changes %#lx\n", hr);
134 return hr;
135 }
136
137 return S_OK;
138}
#define WARN(fmt,...)
Definition: debug.h:112
#define TRUE
Definition: types.h:120
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
REFCLSID clsid
Definition: msctf.c:82
HRESULT msi_init_string_table(IStorage *stg) DECLSPEC_HIDDEN
Definition: string.c:460
UINT write_stream_data(IStorage *stg, LPCWSTR stname, LPCVOID data, UINT sz, BOOL bTable) DECLSPEC_HIDDEN
Definition: table.c:296
HRESULT hr
Definition: shlfolder.c:183

Referenced by MSI_OpenDatabaseW().

◆ free_merge_table()

static void free_merge_table ( MERGETABLE table)
static

Definition at line 1627 of file database.c.

1628{
1629 UINT i;
1630
1631 if (table->labels != NULL)
1632 {
1633 for (i = 0; i < table->numlabels; i++)
1634 msi_free(table->labels[i]);
1635
1636 msi_free(table->labels);
1637 }
1638
1639 if (table->columns != NULL)
1640 {
1641 for (i = 0; i < table->numcolumns; i++)
1643
1645 }
1646
1647 if (table->types != NULL)
1648 {
1649 for (i = 0; i < table->numtypes; i++)
1650 msi_free(table->types[i]);
1651
1652 msi_free(table->types);
1653 }
1654
1657
1658 msi_free(table);
1659}
static void merge_free_rows(MERGETABLE *table)
Definition: database.c:1613
const struct column * columns
const WCHAR * name

Referenced by merge_diff_tables(), msi_get_merge_table(), and MsiDatabaseMergeW().

◆ free_streams()

static void free_streams ( MSIDATABASE db)
static

Definition at line 66 of file database.c.

67{
68 UINT i;
69 for (i = 0; i < db->num_streams; i++)
70 {
71 if (db->streams[i].stream) IStream_Release( db->streams[i].stream );
72 }
73 msi_free( db->streams );
74}
MSISTREAM * streams
Definition: msipriv.h:120
UINT num_streams
Definition: msipriv.h:121
IStream * stream
Definition: msipriv.h:89

Referenced by MSI_CloseDatabase().

◆ free_transforms()

static void free_transforms ( MSIDATABASE db)
static

Definition at line 55 of file database.c.

56{
57 while( !list_empty( &db->transforms ) )
58 {
60 list_remove( &t->entry );
61 IStorage_Release( t->stg );
62 msi_free( t );
63 }
64}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
uint32_t entry
Definition: isohybrid.c:63
Definition: list.h:15
#define LIST_ENTRY(type)
Definition: queue.h:175

Referenced by MSI_CloseDatabase().

◆ gather_merge_data()

static UINT gather_merge_data ( MSIDATABASE db,
MSIDATABASE merge,
struct list tabledata 
)
static

Definition at line 1757 of file database.c.

1759{
1760 MSIQUERY *view;
1762 UINT r;
1763
1764 r = MSI_DatabaseOpenViewW(merge, L"SELECT * FROM `_Tables`", &view);
1765 if (r != ERROR_SUCCESS)
1766 return r;
1767
1768 data.db = db;
1769 data.merge = merge;
1770 data.tabledata = tabledata;
1772 msiobj_release(&view->hdr);
1773 return r;
1774}
static UINT merge_diff_tables(MSIRECORD *rec, LPVOID param)
Definition: database.c:1706
UINT MSI_IterateRecords(MSIQUERY *, LPDWORD, record_func, LPVOID) DECLSPEC_HIDDEN
Definition: msiquery.c:163
UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY **) DECLSPEC_HIDDEN

Referenced by MsiDatabaseMergeW().

◆ get_key_value()

static LPWSTR get_key_value ( MSIQUERY view,
LPCWSTR  key,
MSIRECORD rec 
)
static

Definition at line 1354 of file database.c.

1355{
1356 MSIRECORD *colnames;
1357 LPWSTR str, val;
1358 UINT r, i = 0;
1359 DWORD sz = 0;
1360 int cmp;
1361
1363 if (r != ERROR_SUCCESS)
1364 return NULL;
1365
1366 do
1367 {
1368 str = msi_dup_record_field(colnames, ++i);
1369 cmp = wcscmp( key, str );
1370 msi_free(str);
1371 } while (cmp);
1372
1373 msiobj_release(&colnames->hdr);
1374
1375 r = MSI_RecordGetStringW(rec, i, NULL, &sz);
1376 if (r != ERROR_SUCCESS)
1377 return NULL;
1378 sz++;
1379
1380 if (MSI_RecordGetString(rec, i)) /* check record field is a string */
1381 {
1382 /* quote string record fields */
1383 sz += 2;
1384 val = msi_alloc(sz * sizeof(WCHAR));
1385 if (!val)
1386 return NULL;
1387
1388 lstrcpyW(val, L"'");
1389 r = MSI_RecordGetStringW(rec, i, val + 1, &sz);
1390 lstrcpyW(val + 1 + sz, L"'");
1391 }
1392 else
1393 {
1394 /* do not quote integer record fields */
1395 val = msi_alloc(sz * sizeof(WCHAR));
1396 if (!val)
1397 return NULL;
1398
1399 r = MSI_RecordGetStringW(rec, i, val, &sz);
1400 }
1401
1402 if (r != ERROR_SUCCESS)
1403 {
1404 ERR("failed to get string!\n");
1405 msi_free(val);
1406 return NULL;
1407 }
1408
1409 return val;
1410}
#define lstrcpyW
Definition: compat.h:749
#define cmp(status, error)
Definition: error.c:114
WCHAR * msi_dup_record_field(MSIRECORD *row, INT index) DECLSPEC_HIDDEN
Definition: record.c:1002
UINT MSI_RecordGetStringW(MSIRECORD *, UINT, LPWSTR, LPDWORD) DECLSPEC_HIDDEN
UINT MSI_ViewGetColumnInfo(MSIQUERY *, MSICOLINFO, MSIRECORD **) DECLSPEC_HIDDEN
Definition: msiquery.c:603
@ MSICOLINFO_NAMES
Definition: msiquery.h:36
const WCHAR * str
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

Referenced by create_diff_row_query().

◆ merge_diff_row()

static UINT merge_diff_row ( MSIRECORD rec,
LPVOID  param 
)
static

Definition at line 1467 of file database.c.

1468{
1469 MERGEDATA *data = param;
1470 MERGETABLE *table = data->curtable;
1471 MERGEROW *mergerow;
1472 MSIQUERY *dbview = NULL;
1473 MSIRECORD *row = NULL;
1474 LPWSTR query = NULL;
1476
1477 if (TABLE_Exists(data->db, table->name))
1478 {
1479 query = create_diff_row_query(data->merge, data->curview, table->name, rec);
1480 if (!query)
1481 return ERROR_OUTOFMEMORY;
1482
1483 r = MSI_DatabaseOpenViewW(data->db, query, &dbview);
1484 if (r != ERROR_SUCCESS)
1485 goto done;
1486
1487 r = MSI_ViewExecute(dbview, NULL);
1488 if (r != ERROR_SUCCESS)
1489 goto done;
1490
1491 r = MSI_ViewFetch(dbview, &row);
1492 if (r == ERROR_SUCCESS && !MSI_RecordsAreEqual(rec, row))
1493 {
1494 table->numconflicts++;
1495 goto done;
1496 }
1497 else if (r != ERROR_NO_MORE_ITEMS)
1498 goto done;
1499
1500 r = ERROR_SUCCESS;
1501 }
1502
1503 mergerow = msi_alloc(sizeof(MERGEROW));
1504 if (!mergerow)
1505 {
1507 goto done;
1508 }
1509
1510 mergerow->data = MSI_CloneRecord(rec);
1511 if (!mergerow->data)
1512 {
1514 msi_free(mergerow);
1515 goto done;
1516 }
1517
1518 list_add_tail(&table->rows, &mergerow->entry);
1519
1520done:
1521 msi_free(query);
1522 msiobj_release(&row->hdr);
1523 msiobj_release(&dbview->hdr);
1524 return r;
1525}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
static LPWSTR create_diff_row_query(MSIDATABASE *merge, MSIQUERY *view, LPWSTR table, MSIRECORD *rec)
Definition: database.c:1412
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
GLfloat param
Definition: glext.h:5796
UINT MSI_ViewFetch(MSIQUERY *, MSIRECORD **) DECLSPEC_HIDDEN
Definition: msiquery.c:377
BOOL TABLE_Exists(MSIDATABASE *db, LPCWSTR name) DECLSPEC_HIDDEN
Definition: table.c:960
MSIRECORD * MSI_CloneRecord(MSIRECORD *) DECLSPEC_HIDDEN
Definition: record.c:921
BOOL MSI_RecordsAreEqual(MSIRECORD *, MSIRECORD *) DECLSPEC_HIDDEN
Definition: record.c:986
UINT MSI_ViewExecute(MSIQUERY *, MSIRECORD *) DECLSPEC_HIDDEN
Definition: msiquery.c:502
struct list entry
Definition: database.c:1226
MSIRECORD * data
Definition: database.c:1227
MSIOBJECTHDR hdr
Definition: msipriv.h:129

Referenced by merge_diff_tables().

◆ merge_diff_tables()

static UINT merge_diff_tables ( MSIRECORD rec,
LPVOID  param 
)
static

Definition at line 1706 of file database.c.

1707{
1708 MERGEDATA *data = param;
1710 MSIQUERY *dbview = NULL;
1711 MSIQUERY *mergeview = NULL;
1712 LPCWSTR name;
1713 UINT r;
1714
1715 name = MSI_RecordGetString(rec, 1);
1716
1717 r = MSI_OpenQuery(data->merge, &mergeview, L"SELECT * FROM `%s`", name);
1718 if (r != ERROR_SUCCESS)
1719 goto done;
1720
1721 if (TABLE_Exists(data->db, name))
1722 {
1723 r = MSI_OpenQuery(data->db, &dbview, L"SELECT * FROM `%s`", name);
1724 if (r != ERROR_SUCCESS)
1725 goto done;
1726
1727 r = merge_verify_colnames(dbview, mergeview);
1728 if (r != ERROR_SUCCESS)
1729 goto done;
1730
1731 r = merge_verify_primary_keys(data->db, data->merge, name);
1732 if (r != ERROR_SUCCESS)
1733 goto done;
1734 }
1735
1736 r = msi_get_merge_table(data->merge, name, &table);
1737 if (r != ERROR_SUCCESS)
1738 goto done;
1739
1740 data->curtable = table;
1741 data->curview = mergeview;
1743 if (r != ERROR_SUCCESS)
1744 {
1746 goto done;
1747 }
1748
1749 list_add_tail(data->tabledata, &table->entry);
1750
1751done:
1752 msiobj_release(&dbview->hdr);
1753 msiobj_release(&mergeview->hdr);
1754 return r;
1755}
static UINT merge_verify_primary_keys(MSIDATABASE *db, MSIDATABASE *mergedb, LPCWSTR table)
Definition: database.c:1317
static void free_merge_table(MERGETABLE *table)
Definition: database.c:1627
static UINT msi_get_merge_table(MSIDATABASE *db, LPCWSTR name, MERGETABLE **ptable)
Definition: database.c:1661
static UINT merge_verify_colnames(MSIQUERY *dbview, MSIQUERY *mergeview)
Definition: database.c:1252
static UINT merge_diff_row(MSIRECORD *rec, LPVOID param)
Definition: database.c:1467
UINT WINAPIV MSI_OpenQuery(MSIDATABASE *, MSIQUERY **, LPCWSTR,...) DECLSPEC_HIDDEN
Definition: msiquery.c:138
Definition: name.c:39
struct list entry

Referenced by gather_merge_data().

◆ merge_free_rows()

static void merge_free_rows ( MERGETABLE table)
static

Definition at line 1613 of file database.c.

1614{
1615 struct list *item, *cursor;
1616
1618 {
1620
1621 list_remove(&row->entry);
1622 msiobj_release(&row->data->hdr);
1623 msi_free(row);
1624 }
1625}
Definition: list.h:37
const char cursor[]
Definition: icontest.c:13
static ATOM item
Definition: dde.c:856
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:192

Referenced by free_merge_table().

◆ merge_table()

static UINT merge_table ( MSIDATABASE db,
MERGETABLE table 
)
static

Definition at line 1776 of file database.c.

1777{
1778 UINT r;
1779 MERGEROW *row;
1780 MSIVIEW *tv;
1781
1782 if (!TABLE_Exists(db, table->name))
1783 {
1784 r = msi_add_table_to_db(db, table->columns, table->types,
1785 table->labels, table->numlabels, table->numcolumns);
1786 if (r != ERROR_SUCCESS)
1787 return ERROR_FUNCTION_FAILED;
1788 }
1789
1791 {
1792 r = TABLE_CreateView(db, table->name, &tv);
1793 if (r != ERROR_SUCCESS)
1794 return r;
1795
1796 r = tv->ops->insert_row(tv, row->data, -1, FALSE);
1797 tv->ops->delete(tv);
1798
1799 if (r != ERROR_SUCCESS)
1800 return r;
1801 }
1802
1803 return ERROR_SUCCESS;
1804}
#define FALSE
Definition: types.h:117
static UINT msi_add_table_to_db(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types, LPWSTR *labels, DWORD num_labels, DWORD num_columns)
Definition: database.c:582
UINT TABLE_CreateView(MSIDATABASE *db, LPCWSTR name, MSIVIEW **view) DECLSPEC_HIDDEN
Definition: table.c:2189
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
UINT(* insert_row)(struct tagMSIVIEW *view, MSIRECORD *record, UINT row, BOOL temporary)
Definition: msipriv.h:283
UINT(* delete)(struct tagMSIVIEW *)
Definition: msipriv.h:324
const MSIVIEWOPS * ops
Definition: msipriv.h:355

Referenced by MsiDatabaseMergeW().

◆ merge_type_match()

static BOOL merge_type_match ( LPCWSTR  type1,
LPCWSTR  type2 
)
static

Definition at line 1239 of file database.c.

1240{
1241 if (((type1[0] == 'l') || (type1[0] == 's')) &&
1242 ((type2[0] == 'l') || (type2[0] == 's')))
1243 return TRUE;
1244
1245 if (((type1[0] == 'L') || (type1[0] == 'S')) &&
1246 ((type2[0] == 'L') || (type2[0] == 'S')))
1247 return TRUE;
1248
1249 return !wcscmp( type1, type2 );
1250}

Referenced by merge_verify_colnames().

◆ merge_verify_colnames()

static UINT merge_verify_colnames ( MSIQUERY dbview,
MSIQUERY mergeview 
)
static

Definition at line 1252 of file database.c.

1253{
1254 MSIRECORD *dbrec, *mergerec;
1255 UINT r, i, count;
1256
1257 r = MSI_ViewGetColumnInfo(dbview, MSICOLINFO_NAMES, &dbrec);
1258 if (r != ERROR_SUCCESS)
1259 return r;
1260
1261 r = MSI_ViewGetColumnInfo(mergeview, MSICOLINFO_NAMES, &mergerec);
1262 if (r != ERROR_SUCCESS)
1263 {
1264 msiobj_release(&dbrec->hdr);
1265 return r;
1266 }
1267
1269 for (i = 1; i <= count; i++)
1270 {
1271 if (!MSI_RecordGetString(mergerec, i))
1272 break;
1273
1274 if (wcscmp( MSI_RecordGetString( dbrec, i ), MSI_RecordGetString( mergerec, i ) ))
1275 {
1277 goto done;
1278 }
1279 }
1280
1281 msiobj_release(&dbrec->hdr);
1282 msiobj_release(&mergerec->hdr);
1283 dbrec = mergerec = NULL;
1284
1285 r = MSI_ViewGetColumnInfo(dbview, MSICOLINFO_TYPES, &dbrec);
1286 if (r != ERROR_SUCCESS)
1287 return r;
1288
1289 r = MSI_ViewGetColumnInfo(mergeview, MSICOLINFO_TYPES, &mergerec);
1290 if (r != ERROR_SUCCESS)
1291 {
1292 msiobj_release(&dbrec->hdr);
1293 return r;
1294 }
1295
1297 for (i = 1; i <= count; i++)
1298 {
1299 if (!MSI_RecordGetString(mergerec, i))
1300 break;
1301
1303 MSI_RecordGetString(mergerec, i)))
1304 {
1306 break;
1307 }
1308 }
1309
1310done:
1311 msiobj_release(&dbrec->hdr);
1312 msiobj_release(&mergerec->hdr);
1313
1314 return r;
1315}
static BOOL merge_type_match(LPCWSTR type1, LPCWSTR type2)
Definition: database.c:1239
@ MSICOLINFO_TYPES
Definition: msiquery.h:37
#define ERROR_DATATYPE_MISMATCH
Definition: winerror.h:987

Referenced by merge_diff_tables().

◆ merge_verify_primary_keys()

static UINT merge_verify_primary_keys ( MSIDATABASE db,
MSIDATABASE mergedb,
LPCWSTR  table 
)
static

Definition at line 1317 of file database.c.

1319{
1320 MSIRECORD *dbrec, *mergerec = NULL;
1321 UINT r, i, count;
1322
1323 r = MSI_DatabaseGetPrimaryKeys(db, table, &dbrec);
1324 if (r != ERROR_SUCCESS)
1325 return r;
1326
1327 r = MSI_DatabaseGetPrimaryKeys(mergedb, table, &mergerec);
1328 if (r != ERROR_SUCCESS)
1329 goto done;
1330
1332 if (count != MSI_RecordGetFieldCount(mergerec))
1333 {
1335 goto done;
1336 }
1337
1338 for (i = 1; i <= count; i++)
1339 {
1340 if (wcscmp( MSI_RecordGetString( dbrec, i ), MSI_RecordGetString( mergerec, i ) ))
1341 {
1343 goto done;
1344 }
1345 }
1346
1347done:
1348 msiobj_release(&dbrec->hdr);
1349 msiobj_release(&mergerec->hdr);
1350
1351 return r;
1352}

Referenced by merge_diff_tables().

◆ msi_add_records_to_table()

static UINT msi_add_records_to_table ( MSIDATABASE db,
LPWSTR columns,
LPWSTR types,
LPWSTR labels,
LPWSTR **  records,
int  num_columns,
int  num_records,
LPWSTR  path 
)
static

Definition at line 690 of file database.c.

694{
695 UINT r;
696 int i;
697 MSIQUERY *view;
698 MSIRECORD *rec;
699
700 r = MSI_OpenQuery(db, &view, L"SELECT * FROM `%s`", labels[0]);
701 if (r != ERROR_SUCCESS)
702 return r;
703
704 while (MSI_ViewFetch(view, &rec) != ERROR_NO_MORE_ITEMS)
705 {
707 msiobj_release(&rec->hdr);
708 if (r != ERROR_SUCCESS)
709 goto done;
710 }
711
712 for (i = 0; i < num_records; i++)
713 {
714 r = construct_record(num_columns, types, records[i], path, &rec);
715 if (r != ERROR_SUCCESS)
716 goto done;
717
719 if (r != ERROR_SUCCESS)
720 {
721 msiobj_release(&rec->hdr);
722 goto done;
723 }
724
725 msiobj_release(&rec->hdr);
726 }
727
728done:
729 msiobj_release(&view->hdr);
730 return r;
731}
static UINT construct_record(DWORD num_columns, LPWSTR *types, LPWSTR *data, LPWSTR path, MSIRECORD **rec)
Definition: database.c:646
UINT MSI_ViewModify(MSIQUERY *, MSIMODIFY, MSIRECORD *) DECLSPEC_HIDDEN
Definition: msiquery.c:698
@ MSIMODIFY_DELETE
Definition: msiquery.h:57
@ MSIMODIFY_INSERT
Definition: msiquery.h:52

Referenced by MSI_DatabaseImport().

◆ msi_add_table_to_db()

static UINT msi_add_table_to_db ( MSIDATABASE db,
LPWSTR columns,
LPWSTR types,
LPWSTR labels,
DWORD  num_labels,
DWORD  num_columns 
)
static

Definition at line 582 of file database.c.

583{
585 DWORD size;
586 MSIQUERY *view;
587 LPWSTR create_sql = NULL;
588 LPWSTR prelude, columns_sql, postlude;
589
590 prelude = msi_build_createsql_prelude(labels[0]);
591 columns_sql = msi_build_createsql_columns(columns, types, num_columns);
592 postlude = msi_build_createsql_postlude(labels + 1, num_labels - 1); /* skip over table name */
593
594 if (!prelude || !columns_sql || !postlude)
595 goto done;
596
597 size = lstrlenW(prelude) + lstrlenW(columns_sql) + lstrlenW(postlude) + 1;
598 create_sql = msi_alloc(size * sizeof(WCHAR));
599 if (!create_sql)
600 goto done;
601
602 lstrcpyW(create_sql, prelude);
603 lstrcatW(create_sql, columns_sql);
604 lstrcatW(create_sql, postlude);
605
606 r = MSI_DatabaseOpenViewW( db, create_sql, &view );
607 if (r != ERROR_SUCCESS)
608 goto done;
609
612 msiobj_release(&view->hdr);
613
614done:
615 msi_free(prelude);
616 msi_free(columns_sql);
617 msi_free(postlude);
618 msi_free(create_sql);
619 return r;
620}
static LPWSTR msi_build_createsql_columns(LPWSTR *columns_data, LPWSTR *types, DWORD num_columns)
Definition: database.c:463
static LPWSTR msi_build_createsql_postlude(LPWSTR *primary_keys, DWORD num_keys)
Definition: database.c:550
static LPWSTR msi_build_createsql_prelude(LPWSTR table)
Definition: database.c:449
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
UINT MSI_ViewClose(MSIQUERY *) DECLSPEC_HIDDEN
Definition: msiquery.c:454

Referenced by merge_table(), and MSI_DatabaseImport().

◆ msi_build_createsql_columns()

static LPWSTR msi_build_createsql_columns ( LPWSTR columns_data,
LPWSTR types,
DWORD  num_columns 
)
static

Definition at line 463 of file database.c.

464{
465 LPWSTR columns, p;
467 DWORD sql_size = 1, i, len;
468 WCHAR expanded[128], *ptr;
469 WCHAR size[10], comma[2], extra[30];
470
471 columns = msi_alloc_zero(sql_size * sizeof(WCHAR));
472 if (!columns)
473 return NULL;
474
475 for (i = 0; i < num_columns; i++)
476 {
477 type = NULL;
478 comma[1] = size[0] = extra[0] = '\0';
479
480 if (i == num_columns - 1)
481 comma[0] = '\0';
482 else
483 comma[0] = ',';
484
485 ptr = &types[i][1];
486 len = wcstol(ptr, NULL, 10);
487 extra[0] = '\0';
488
489 switch (types[i][0])
490 {
491 case 'l':
492 lstrcpyW(extra, L" NOT NULL");
493 /* fall through */
494 case 'L':
495 lstrcatW(extra, L" LOCALIZABLE");
496 type = L"CHAR";
497 swprintf(size, ARRAY_SIZE(size), L"(%s)", ptr);
498 break;
499 case 's':
500 lstrcpyW(extra, L" NOT NULL");
501 /* fall through */
502 case 'S':
503 type = L"CHAR";
504 swprintf(size, ARRAY_SIZE(size), L"(%s)", ptr);
505 break;
506 case 'i':
507 lstrcpyW(extra, L" NOT NULL");
508 /* fall through */
509 case 'I':
510 if (len <= 2)
511 type = L"INT";
512 else if (len == 4)
513 type = L"LONG";
514 else
515 {
516 WARN("invalid int width %lu\n", len);
517 msi_free(columns);
518 return NULL;
519 }
520 break;
521 case 'v':
522 lstrcpyW(extra, L" NOT NULL");
523 /* fall through */
524 case 'V':
525 type = L"OBJECT";
526 break;
527 default:
528 ERR("Unknown type: %c\n", types[i][0]);
529 msi_free(columns);
530 return NULL;
531 }
532
533 swprintf(expanded, ARRAY_SIZE(expanded), L"`%s` %s%s%s%s ", columns_data[i], type, size, extra, comma);
534 sql_size += lstrlenW(expanded);
535
536 p = msi_realloc(columns, sql_size * sizeof(WCHAR));
537 if (!p)
538 {
539 msi_free(columns);
540 return NULL;
541 }
542 columns = p;
543
544 lstrcatW(columns, expanded);
545 }
546
547 return columns;
548}
#define ARRAY_SIZE(A)
Definition: main.h:33
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
@ extra
Definition: id3.c:95
static PVOID ptr
Definition: dispmode.c:27

Referenced by msi_add_table_to_db().

◆ msi_build_createsql_postlude()

static LPWSTR msi_build_createsql_postlude ( LPWSTR primary_keys,
DWORD  num_keys 
)
static

Definition at line 550 of file database.c.

551{
552 LPWSTR postlude, keys, ptr;
553 DWORD size, i;
554
555 for (i = 0, size = 1; i < num_keys; i++)
556 size += lstrlenW(L"`%s`, ") + lstrlenW(primary_keys[i]) - 2;
557
558 keys = msi_alloc(size * sizeof(WCHAR));
559 if (!keys)
560 return NULL;
561
562 for (i = 0, ptr = keys; i < num_keys; i++)
563 {
564 ptr += swprintf(ptr, size - (ptr - keys), L"`%s`, ", primary_keys[i]);
565 }
566
567 /* remove final ', ' */
568 *(ptr - 2) = '\0';
569
570 size = lstrlenW(L"PRIMARY KEY %s)") + size - 1;
571 postlude = msi_alloc(size * sizeof(WCHAR));
572 if (!postlude)
573 goto done;
574
575 swprintf(postlude, size, L"PRIMARY KEY %s)", keys);
576
577done:
578 msi_free(keys);
579 return postlude;
580}

Referenced by msi_add_table_to_db().

◆ msi_build_createsql_prelude()

static LPWSTR msi_build_createsql_prelude ( LPWSTR  table)
static

Definition at line 449 of file database.c.

450{
451 LPWSTR prelude;
452 DWORD size;
453
454 size = ARRAY_SIZE(L"CREATE TABLE `%s` ( ") + lstrlenW(table) - 2;
455 prelude = msi_alloc(size * sizeof(WCHAR));
456 if (!prelude)
457 return NULL;
458
459 swprintf(prelude, size, L"CREATE TABLE `%s` ( ", table);
460 return prelude;
461}

Referenced by msi_add_table_to_db().

◆ MSI_CloseDatabase()

static VOID MSI_CloseDatabase ( MSIOBJECTHDR arg)
static

Definition at line 86 of file database.c.

87{
88 MSIDATABASE *db = (MSIDATABASE *) arg;
89
90 msi_free(db->path);
91 free_streams( db );
93 free_transforms( db );
95 IStorage_Release( db->storage );
96 if (db->deletefile)
97 {
99 msi_free( db->deletefile );
100 }
101 msi_free( db->tempfolder );
102}
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
static void free_streams(MSIDATABASE *db)
Definition: database.c:66
static void free_transforms(MSIDATABASE *db)
Definition: database.c:55
void free_cached_tables(MSIDATABASE *db) DECLSPEC_HIDDEN
Definition: table.c:470
VOID msi_destroy_stringtable(string_table *st) DECLSPEC_HIDDEN
Definition: string.c:107
LPWSTR deletefile
Definition: msipriv.h:113
IStorage * storage
Definition: msipriv.h:109
LPWSTR tempfolder
Definition: msipriv.h:114
string_table * strings
Definition: msipriv.h:110
LPWSTR path
Definition: msipriv.h:112

Referenced by MSI_OpenDatabaseW().

◆ MSI_DatabaseExport()

static UINT MSI_DatabaseExport ( MSIDATABASE db,
LPCWSTR  table,
LPCWSTR  folder,
LPCWSTR  file 
)
static

Definition at line 1046 of file database.c.

1047{
1048 MSIRECORD *rec = NULL;
1049 MSIQUERY *view = NULL;
1050 WCHAR *filename;
1051 HANDLE handle;
1052 UINT len, r;
1053
1054 TRACE("%p %s %s %s\n", db, debugstr_w(table),
1056
1057 if (!folder || !file)
1059
1060 len = lstrlenW(folder) + lstrlenW(file) + 2;
1061 filename = msi_alloc(len * sizeof (WCHAR));
1062 if (!filename)
1063 return ERROR_OUTOFMEMORY;
1064
1066 lstrcatW( filename, L"\\" );
1068
1071 msi_free( filename );
1073 return ERROR_FUNCTION_FAILED;
1074
1075 if (!wcscmp( table, L"_ForceCodepage" ))
1076 {
1079 goto done;
1080 }
1081
1082 if (!wcscmp( table, L"_SummaryInformation" ))
1083 {
1085 goto done;
1086 }
1087
1088 r = MSI_OpenQuery( db, &view, L"SELECT * FROM %s", table );
1089 if (r == ERROR_SUCCESS)
1090 {
1092
1093 /* write out row 1, the column names */
1095 if (r == ERROR_SUCCESS)
1096 {
1098 msiobj_release( &rec->hdr );
1099 }
1100
1101 /* write out row 2, the column types */
1103 if (r == ERROR_SUCCESS)
1104 {
1106 msiobj_release( &rec->hdr );
1107 }
1108
1109 /* write out row 3, the table name + keys */
1110 r = MSI_DatabaseGetPrimaryKeys( db, table, &rec );
1111 if (r == ERROR_SUCCESS)
1112 {
1113 MSI_RecordSetStringW( rec, 0, table );
1115 msiobj_release( &rec->hdr );
1116 }
1117
1118 /* write out row 4 onwards, the data */
1120 msiobj_release( &view->hdr );
1121 }
1122
1123done:
1125 return r;
1126}
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
static UINT msi_export_record(struct row_export_info *row_export_info, MSIRECORD *row, UINT start)
Definition: database.c:984
static UINT msi_export_row(MSIRECORD *row, void *arg)
Definition: database.c:1016
static UINT msi_export_summaryinformation(MSIDATABASE *db, HANDLE handle)
Definition: database.c:1033
static UINT msi_export_forcecodepage(HANDLE handle, UINT codepage)
Definition: database.c:1021
const char * filename
Definition: ioapi.h:137
#define debugstr_w
Definition: kernel32.h:32
#define CREATE_ALWAYS
Definition: disk.h:72
UINT msi_get_string_table_codepage(const string_table *st) DECLSPEC_HIDDEN
Definition: string.c:671
#define GENERIC_WRITE
Definition: nt_native.h:90
#define TRACE(s)
Definition: solgame.cpp:4
Definition: fci.c:116
const WCHAR * folder
Definition: database.c:980
HANDLE handle
Definition: database.c:979
int codepage
Definition: win_iconv.c:156

Referenced by MsiDatabaseExportW().

◆ MSI_DatabaseImport()

static UINT MSI_DatabaseImport ( MSIDATABASE db,
LPCWSTR  folder,
LPCWSTR  file 
)
static

Definition at line 733 of file database.c.

734{
735 UINT r;
736 DWORD len, i, num_labels, num_types, num_columns, num_records = 0;
737 WCHAR **columns, **types, **labels, *path, *ptr, *data, ***records = NULL, ***temp_records;
738
739 TRACE("%p %s %s\n", db, debugstr_w(folder), debugstr_w(file) );
740
741 if (!folder || !file)
743
744 len = lstrlenW(folder) + lstrlenW(L"\\") + lstrlenW(file) + 1;
745 path = msi_alloc( len * sizeof(WCHAR) );
746 if (!path)
747 return ERROR_OUTOFMEMORY;
748
749 lstrcpyW( path, folder );
750 lstrcatW( path, L"\\" );
751 lstrcatW( path, file );
752
754 if (!data)
755 {
756 msi_free(path);
758 }
759
760 ptr = data;
761 msi_parse_line( &ptr, &columns, &num_columns, &len );
762 msi_parse_line( &ptr, &types, &num_types, &len );
763 msi_parse_line( &ptr, &labels, &num_labels, &len );
764
765 if (num_columns == 1 && !columns[0][0] && num_labels == 1 && !labels[0][0] &&
766 num_types == 2 && !wcscmp( types[1], L"_ForceCodepage" ))
767 {
769 goto done;
770 }
771
772 if (num_columns != num_types)
773 {
775 goto done;
776 }
777
778 records = msi_alloc(sizeof(WCHAR **));
779 if (!records)
780 {
782 goto done;
783 }
784
785 /* read in the table records */
786 while (len)
787 {
788 msi_parse_line( &ptr, &records[num_records], NULL, &len );
789
790 num_records++;
791 temp_records = msi_realloc(records, (num_records + 1) * sizeof(WCHAR **));
792 if (!temp_records)
793 {
795 goto done;
796 }
797 records = temp_records;
798 }
799
800 if (!wcscmp(labels[0], L"_SummaryInformation"))
801 {
802 r = msi_add_suminfo( db, records, num_records, num_columns );
803 if (r != ERROR_SUCCESS)
804 {
806 goto done;
807 }
808 }
809 else
810 {
811 if (!TABLE_Exists(db, labels[0]))
812 {
813 r = msi_add_table_to_db( db, columns, types, labels, num_labels, num_columns );
814 if (r != ERROR_SUCCESS)
815 {
817 goto done;
818 }
819 }
820
821 r = msi_add_records_to_table( db, columns, types, labels, records, num_columns, num_records, path );
822 }
823
824done:
825 msi_free(path);
826 msi_free(data);
827 msi_free(columns);
829 msi_free(labels);
830
831 for (i = 0; i < num_records; i++)
832 msi_free(records[i]);
833
834 msi_free(records);
835 return r;
836}
static void msi_parse_line(LPWSTR *line, LPWSTR **entries, DWORD *num_entries, DWORD *len)
Definition: database.c:380
static UINT msi_add_records_to_table(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types, LPWSTR *labels, LPWSTR **records, int num_columns, int num_records, LPWSTR path)
Definition: database.c:690
static LPWSTR msi_read_text_archive(LPCWSTR path, DWORD *len)
Definition: database.c:350
UINT msi_add_suminfo(MSIDATABASE *db, LPWSTR **records, int num_records, int num_columns) DECLSPEC_HIDDEN
Definition: suminfo.c:1073
UINT msi_set_string_table_codepage(string_table *st, UINT codepage) DECLSPEC_HIDDEN
Definition: string.c:676

Referenced by MsiDatabaseImportW().

◆ msi_export_field()

static UINT msi_export_field ( HANDLE  handle,
MSIRECORD row,
UINT  field 
)
static

Definition at line 883 of file database.c.

884{
885 char *buffer;
886 BOOL ret;
887 DWORD sz = 0x100;
888 UINT r;
889
890 buffer = msi_alloc( sz );
891 if (!buffer)
892 return ERROR_OUTOFMEMORY;
893
895 if (r == ERROR_MORE_DATA)
896 {
897 char *tmp;
898
899 sz++; /* leave room for NULL terminator */
900 tmp = msi_realloc( buffer, sz );
901 if (!tmp)
902 {
903 msi_free( buffer );
904 return ERROR_OUTOFMEMORY;
905 }
906 buffer = tmp;
907
909 if (r != ERROR_SUCCESS)
910 {
911 msi_free( buffer );
912 return r;
913 }
914 }
915 else if (r != ERROR_SUCCESS)
916 {
917 msi_free( buffer );
918 return r;
919 }
920
921 ret = WriteFile( handle, buffer, sz, &sz, NULL );
922 msi_free( buffer );
924}
#define ERROR_MORE_DATA
Definition: dderror.h:13
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint buffer
Definition: glext.h:5915
UINT MSI_RecordGetStringA(MSIRECORD *, UINT, LPSTR, LPDWORD) DECLSPEC_HIDDEN
Definition: record.c:351
Definition: parser.c:44
int ret

Referenced by msi_export_record().

◆ msi_export_forcecodepage()

static UINT msi_export_forcecodepage ( HANDLE  handle,
UINT  codepage 
)
static

Definition at line 1021 of file database.c.

1022{
1023 static const char fmt[] = "\r\n\r\n%u\t_ForceCodepage\r\n";
1024 char data[sizeof(fmt) + 10];
1025 DWORD sz = sprintf( data, fmt, codepage );
1026
1027 if (!WriteFile(handle, data, sz, &sz, NULL))
1028 return ERROR_FUNCTION_FAILED;
1029
1030 return ERROR_SUCCESS;
1031}
#define sprintf(buf, format,...)
Definition: sprintf.c:55
Definition: dsound.c:943

Referenced by MSI_DatabaseExport().

◆ msi_export_record()

static UINT msi_export_record ( struct row_export_info row_export_info,
MSIRECORD row,
UINT  start 
)
static

Definition at line 984 of file database.c.

985{
988 const char *sep;
989 DWORD sz;
990
992 for (i = start; i <= count; i++)
993 {
996 {
998 if (r != ERROR_SUCCESS)
999 return r;
1000
1001 /* exporting a binary stream, repeat the "Name" field */
1003 if (r != ERROR_SUCCESS)
1004 return r;
1005 }
1006 else if (r != ERROR_SUCCESS)
1007 return r;
1008
1009 sep = (i < count) ? "\t" : "\r\n";
1010 if (!WriteFile( handle, sep, strlen(sep), &sz, NULL ))
1011 return ERROR_FUNCTION_FAILED;
1012 }
1013 return r;
1014}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static UINT msi_export_field(HANDLE handle, MSIRECORD *row, UINT field)
Definition: database.c:883
static UINT msi_export_stream(const WCHAR *folder, const WCHAR *table, MSIRECORD *row, UINT field, UINT start)
Definition: database.c:926
GLuint start
Definition: gl.h:1545
const WCHAR * table
Definition: database.c:981

Referenced by MSI_DatabaseExport(), and msi_export_row().

◆ msi_export_row()

static UINT msi_export_row ( MSIRECORD row,
void arg 
)
static

Definition at line 1016 of file database.c.

1017{
1018 return msi_export_record( arg, row, 1 );
1019}

Referenced by MSI_DatabaseExport().

◆ msi_export_stream()

static UINT msi_export_stream ( const WCHAR folder,
const WCHAR table,
MSIRECORD row,
UINT  field,
UINT  start 
)
static

Definition at line 926 of file database.c.

927{
929 DWORD sz, read_size, write_size;
930 char buffer[1024];
931 HANDLE file;
932 UINT len, r;
933
934 sz = ARRAY_SIZE( stream );
936 if (r != ERROR_SUCCESS)
937 return r;
938
939 len = sz + lstrlenW( folder ) + lstrlenW( table ) + ARRAY_SIZE( L"%s\\%s" ) + 1;
940 if (!(path = msi_alloc( len * sizeof(WCHAR) )))
941 return ERROR_OUTOFMEMORY;
942
943 len = swprintf( path, len, L"%s\\%s", folder, table );
945 {
946 msi_free( path );
948 }
949
950 path[len++] = '\\';
951 lstrcpyW( path + len, stream );
954 msi_free( path );
957
958 read_size = sizeof(buffer);
959 while (read_size == sizeof(buffer))
960 {
961 r = MSI_RecordReadStream( row, field, buffer, &read_size );
962 if (r != ERROR_SUCCESS)
963 {
964 CloseHandle( file );
965 return r;
966 }
967 if (!WriteFile( file, buffer, read_size, &write_size, NULL ) || read_size != write_size)
968 {
969 CloseHandle( file );
970 return ERROR_WRITE_FAULT;
971 }
972 }
973 CloseHandle( file );
974 return r;
975}
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
UINT MSI_RecordReadStream(MSIRECORD *, UINT, char *, LPDWORD) DECLSPEC_HIDDEN
Definition: record.c:761
#define MAX_STREAM_NAME_LEN
Definition: msipriv.h:56
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
Definition: parse.h:23
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_WRITE_FAULT
Definition: winerror.h:132

Referenced by msi_export_record().

◆ msi_export_summaryinformation()

static UINT msi_export_summaryinformation ( MSIDATABASE db,
HANDLE  handle 
)
static

Definition at line 1033 of file database.c.

1034{
1035 static const char header[] = "PropertyId\tValue\r\n"
1036 "i2\tl255\r\n"
1037 "_SummaryInformation\tPropertyId\r\n";
1038 DWORD sz = ARRAY_SIZE(header) - 1;
1039
1040 if (!WriteFile(handle, header, sz, &sz, NULL))
1041 return ERROR_WRITE_FAULT;
1042
1043 return msi_export_suminfo( db, handle );
1044}
UINT msi_export_suminfo(MSIDATABASE *db, HANDLE handle) DECLSPEC_HIDDEN
Definition: suminfo.c:1190

Referenced by MSI_DatabaseExport().

◆ msi_get_merge_table()

static UINT msi_get_merge_table ( MSIDATABASE db,
LPCWSTR  name,
MERGETABLE **  ptable 
)
static

Definition at line 1661 of file database.c.

1662{
1663 UINT r;
1665 MSIQUERY *mergeview = NULL;
1666
1667 table = msi_alloc_zero(sizeof(MERGETABLE));
1668 if (!table)
1669 {
1670 *ptable = NULL;
1671 return ERROR_OUTOFMEMORY;
1672 }
1673
1674 r = msi_get_table_labels(db, name, &table->labels, &table->numlabels);
1675 if (r != ERROR_SUCCESS)
1676 goto err;
1677
1678 r = MSI_OpenQuery(db, &mergeview, L"SELECT * FROM `%s`", name);
1679 if (r != ERROR_SUCCESS)
1680 goto err;
1681
1682 r = msi_get_query_columns(mergeview, &table->columns, &table->numcolumns);
1683 if (r != ERROR_SUCCESS)
1684 goto err;
1685
1686 r = msi_get_query_types(mergeview, &table->types, &table->numtypes);
1687 if (r != ERROR_SUCCESS)
1688 goto err;
1689
1690 list_init(&table->rows);
1691
1692 table->name = strdupW(name);
1693 table->numconflicts = 0;
1694
1695 msiobj_release(&mergeview->hdr);
1696 *ptable = table;
1697 return ERROR_SUCCESS;
1698
1699err:
1700 msiobj_release(&mergeview->hdr);
1702 *ptable = NULL;
1703 return r;
1704}
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
static void list_init(struct list_entry *head)
Definition: list.h:51
static UINT msi_get_query_columns(MSIQUERY *query, LPWSTR **columns, DWORD *numcolumns)
Definition: database.c:1556
static UINT msi_get_table_labels(MSIDATABASE *db, LPCWSTR table, LPWSTR **labels, DWORD *numlabels)
Definition: database.c:1527
static UINT msi_get_query_types(MSIQUERY *query, LPWSTR **types, DWORD *numtypes)
Definition: database.c:1585
#define err(...)

Referenced by merge_diff_tables().

◆ msi_get_query_columns()

static UINT msi_get_query_columns ( MSIQUERY query,
LPWSTR **  columns,
DWORD numcolumns 
)
static

Definition at line 1556 of file database.c.

1557{
1558 UINT r, i, count;
1559 MSIRECORD *prec = NULL;
1560
1562 if (r != ERROR_SUCCESS)
1563 return r;
1564
1566 *columns = msi_alloc(count*sizeof(LPWSTR));
1567 if (!*columns)
1568 {
1570 goto end;
1571 }
1572
1573 for (i=1; i<=count; i++ )
1574 {
1575 (*columns)[i-1] = strdupW(MSI_RecordGetString(prec, i));
1576 }
1577
1578 *numcolumns = count;
1579
1580end:
1581 msiobj_release( &prec->hdr );
1582 return r;
1583}
GLuint GLuint end
Definition: gl.h:1545

Referenced by msi_get_merge_table().

◆ msi_get_query_types()

static UINT msi_get_query_types ( MSIQUERY query,
LPWSTR **  types,
DWORD numtypes 
)
static

Definition at line 1585 of file database.c.

1586{
1587 UINT r, i, count;
1588 MSIRECORD *prec = NULL;
1589
1591 if (r != ERROR_SUCCESS)
1592 return r;
1593
1595 *types = msi_alloc(count*sizeof(LPWSTR));
1596 if (!*types)
1597 {
1599 goto end;
1600 }
1601
1602 *numtypes = count;
1603 for (i=1; i<=count; i++ )
1604 {
1605 (*types)[i-1] = strdupW(MSI_RecordGetString(prec, i));
1606 }
1607
1608end:
1609 msiobj_release( &prec->hdr );
1610 return r;
1611}

Referenced by msi_get_merge_table().

◆ msi_get_table_labels()

static UINT msi_get_table_labels ( MSIDATABASE db,
LPCWSTR  table,
LPWSTR **  labels,
DWORD numlabels 
)
static

Definition at line 1527 of file database.c.

1528{
1529 UINT r, i, count;
1530 MSIRECORD *prec = NULL;
1531
1532 r = MSI_DatabaseGetPrimaryKeys(db, table, &prec);
1533 if (r != ERROR_SUCCESS)
1534 return r;
1535
1537 *numlabels = count + 1;
1538 *labels = msi_alloc((*numlabels)*sizeof(LPWSTR));
1539 if (!*labels)
1540 {
1542 goto end;
1543 }
1544
1545 (*labels)[0] = strdupW(table);
1546 for (i=1; i<=count; i++ )
1547 {
1548 (*labels)[i] = strdupW(MSI_RecordGetString(prec, i));
1549 }
1550
1551end:
1552 msiobj_release( &prec->hdr );
1553 return r;
1554}

Referenced by msi_get_merge_table().

◆ msi_import_stream_filename()

static LPWSTR msi_import_stream_filename ( LPCWSTR  path,
LPCWSTR  name 
)
static

Definition at line 622 of file database.c.

623{
624 DWORD len;
626
627 len = lstrlenW(path) + lstrlenW(name) + 1;
628 fullname = msi_alloc(len*sizeof(WCHAR));
629 if (!fullname)
630 return NULL;
631
633
634 /* chop off extension from path */
635 ptr = wcsrchr(fullname, '.');
636 if (!ptr)
637 {
639 return NULL;
640 }
641 *ptr++ = '\\';
642 lstrcpyW( ptr, name );
643 return fullname;
644}
#define wcsrchr
Definition: compat.h:16
const char * fullname
Definition: shader.c:1766

Referenced by construct_record().

◆ MSI_OpenDatabaseW()

UINT MSI_OpenDatabaseW ( LPCWSTR  szDBPath,
LPCWSTR  szPersist,
MSIDATABASE **  pdb 
)

Definition at line 140 of file database.c.

141{
142 IStorage *stg = NULL;
143 HRESULT r;
144 MSIDATABASE *db = NULL;
147 UINT mode;
148 STATSTG stat;
149 BOOL created = FALSE, patch = FALSE;
151
152 TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );
153
154 if( !pdb )
156
157 save_path = szDBPath;
158 if ( IS_INTMSIDBOPEN(szPersist) )
159 {
160 mode = LOWORD(szPersist);
161 }
162 else
163 {
164 if (!CopyFileW( szDBPath, szPersist, FALSE ))
165 return ERROR_OPEN_FAILED;
166
167 szDBPath = szPersist;
169 created = TRUE;
170 }
171
173 {
174 TRACE("Database is a patch\n");
175 mode &= ~MSI_OPEN_PATCHFILE;
176 patch = TRUE;
177 }
178
179 if( mode == MSI_OPEN_READONLY )
180 {
181 r = StgOpenStorage( szDBPath, NULL,
183 }
184 else if( mode == MSI_OPEN_CREATE )
185 {
186 r = StgCreateDocfile( szDBPath,
188
189 if( SUCCEEDED(r) )
190 r = db_initialize( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase );
191 created = TRUE;
192 }
193 else if( mode == MSI_OPEN_CREATEDIRECT )
194 {
195 r = StgCreateDocfile( szDBPath,
197
198 if( SUCCEEDED(r) )
199 r = db_initialize( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase );
200 created = TRUE;
201 }
202 else if( mode == MSI_OPEN_TRANSACT )
203 {
204 r = StgOpenStorage( szDBPath, NULL,
206 }
207 else if( mode == MSI_OPEN_DIRECT )
208 {
209 r = StgOpenStorage( szDBPath, NULL,
211 }
212 else
213 {
214 ERR("unknown flag %x\n",mode);
216 }
217
218 if( FAILED( r ) || !stg )
219 {
220 WARN("open failed r = %#lx for %s\n", r, debugstr_w(szDBPath));
222 }
223
224 r = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
225 if( FAILED( r ) )
226 {
227 FIXME("Failed to stat storage\n");
228 goto end;
229 }
230
231 if ( !IsEqualGUID( &stat.clsid, &CLSID_MsiDatabase ) &&
232 !IsEqualGUID( &stat.clsid, &CLSID_MsiPatch ) &&
233 !IsEqualGUID( &stat.clsid, &CLSID_MsiTransform ) )
234 {
235 ERR("storage GUID is not a MSI database GUID %s\n",
236 debugstr_guid(&stat.clsid) );
237 goto end;
238 }
239
240 if ( patch && !IsEqualGUID( &stat.clsid, &CLSID_MsiPatch ) )
241 {
242 ERR("storage GUID is not the MSI patch GUID %s\n",
243 debugstr_guid(&stat.clsid) );
245 goto end;
246 }
247
250 if( !db )
251 {
252 FIXME("Failed to allocate a handle\n");
253 goto end;
254 }
255
256 if (!wcschr( save_path, '\\' ))
257 {
259 lstrcatW( path, L"\\" );
261 }
262 else
264
265 db->path = strdupW( path );
268
269 if( TRACE_ON( msi ) )
270 enum_stream_names( stg );
271
272 db->storage = stg;
273 db->mode = mode;
274 if (created)
275 db->deletefile = strdupW( szDBPath );
276 list_init( &db->tables );
277 list_init( &db->transforms );
278
280 if( !db->strings )
281 goto end;
282
284
285 msiobj_addref( &db->hdr );
286 IStorage_AddRef( stg );
287 *pdb = db;
288
289end:
290 if( db )
291 msiobj_release( &db->hdr );
292 if( stg )
293 IStorage_Release( stg );
294
295 return ret;
296}
#define stat
Definition: acwin.h:99
static struct @1550 save_path[MOVE_LIST_SIZE]
#define FIXME(fmt,...)
Definition: debug.h:111
static PDB pdb
Definition: db.cpp:172
#define wcschr
Definition: compat.h:17
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define TRACE_ON(x)
Definition: compat.h:75
#define MAX_PATH
Definition: compat.h:34
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
static VOID MSI_CloseDatabase(MSIOBJECTHDR *arg)
Definition: database.c:86
#define IS_INTMSIDBOPEN(x)
Definition: database.c:53
static HRESULT db_initialize(IStorage *stg, const GUID *clsid)
Definition: database.c:104
void * alloc_msiobject(UINT type, UINT size, msihandledestructor destroy)
Definition: handle.c:201
void msiobj_addref(MSIOBJECTHDR *info)
Definition: handle.c:217
HRESULT WINAPI StgOpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8755
HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8636
GLenum mode
Definition: glext.h:6217
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define debugstr_guid
Definition: kernel32.h:35
#define MSI_INITIAL_MEDIA_TRANSFORM_DISKID
Definition: msipriv.h:84
#define MSIHANDLETYPE_DATABASE
Definition: msipriv.h:722
#define MSI_OPEN_DIRECT
Definition: msipriv.h:101
#define MSI_OPEN_CREATEDIRECT
Definition: msipriv.h:103
#define MSI_OPEN_TRANSACT
Definition: msipriv.h:100
#define MSI_OPEN_CREATE
Definition: msipriv.h:102
#define MSI_OPEN_READONLY
Definition: msipriv.h:99
#define MSI_INITIAL_MEDIA_TRANSFORM_OFFSET
Definition: msipriv.h:83
string_table * msi_load_string_table(IStorage *stg, UINT *bytes_per_strref) DECLSPEC_HIDDEN
Definition: string.c:478
void enum_stream_names(IStorage *stg) DECLSPEC_HIDDEN
Definition: table.c:204
#define MSI_OPEN_PATCHFILE
Definition: msipriv.h:104
#define STGM_CREATE
Definition: objbase.h:926
#define STGM_DIRECT
Definition: objbase.h:914
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_TRANSACTED
Definition: objbase.h:915
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923
#define STGM_SHARE_DENY_WRITE
Definition: objbase.h:922
#define STGM_READ
Definition: objbase.h:917
#define LOWORD(l)
Definition: pedump.c:82
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
Definition: stat.h:55
UINT media_transform_disk_id
Definition: msipriv.h:117
UINT bytes_per_strref
Definition: msipriv.h:111
MSIOBJECTHDR hdr
Definition: msipriv.h:108
struct list tables
Definition: msipriv.h:118
UINT media_transform_offset
Definition: msipriv.h:116
#define ERROR_OPEN_FAILED
Definition: winerror.h:184

Referenced by MSI_ApplicablePatchW(), msi_apply_patch_package(), msi_apply_registered_patch(), MSI_OpenPackageW(), MsiGetSummaryInformationW(), and MsiOpenDatabaseW().

◆ msi_parse_line()

static void msi_parse_line ( LPWSTR line,
LPWSTR **  entries,
DWORD num_entries,
DWORD len 
)
static

Definition at line 380 of file database.c.

381{
382 LPWSTR ptr = *line, save;
383 DWORD i, count = 1, chars_left = *len;
384
385 *entries = NULL;
386
387 /* stay on this line */
388 while (chars_left && *ptr != '\n')
389 {
390 /* entries are separated by tabs */
391 if (*ptr == '\t')
392 count++;
393
394 ptr++;
395 chars_left--;
396 }
397
398 *entries = msi_alloc(count * sizeof(LPWSTR));
399 if (!*entries)
400 return;
401
402 /* store pointers into the data */
403 chars_left = *len;
404 for (i = 0, ptr = *line; i < count; i++)
405 {
406 while (chars_left && *ptr == '\r')
407 {
408 ptr++;
409 chars_left--;
410 }
411 save = ptr;
412
413 while (chars_left && *ptr != '\t' && *ptr != '\n' && *ptr != '\r')
414 {
415 if (!*ptr) *ptr = '\n'; /* convert embedded nulls to \n */
416 if (ptr > *line && *ptr == '\x19' && *(ptr - 1) == '\x11')
417 {
418 *ptr = '\n';
419 *(ptr - 1) = '\r';
420 }
421 ptr++;
422 chars_left--;
423 }
424
425 /* NULL-separate the data */
426 if (*ptr == '\n' || *ptr == '\r')
427 {
428 while (chars_left && (*ptr == '\n' || *ptr == '\r'))
429 {
430 *(ptr++) = 0;
431 chars_left--;
432 }
433 }
434 else if (*ptr)
435 {
436 *(ptr++) = 0;
437 chars_left--;
438 }
439 (*entries)[i] = save;
440 }
441
442 /* move to the next line if there's more, else EOF */
443 *line = ptr;
444 *len = chars_left;
445 if (num_entries)
446 *num_entries = count;
447}
Definition: parser.c:49

Referenced by MSI_DatabaseImport().

◆ msi_read_text_archive()

static LPWSTR msi_read_text_archive ( LPCWSTR  path,
DWORD len 
)
static

Definition at line 350 of file database.c.

351{
352 HANDLE file;
353 LPSTR data = NULL;
354 LPWSTR wdata = NULL;
355 DWORD read, size = 0;
356
359 return NULL;
360
362 if (!(data = msi_alloc( size ))) goto done;
363
364 if (!ReadFile( file, data, size, &read, NULL ) || read != size) goto done;
365
366 while (!data[size - 1]) size--;
368 if ((wdata = msi_alloc( (*len + 1) * sizeof(WCHAR) )))
369 {
370 MultiByteToWideChar( CP_ACP, 0, data, size, wdata, *len );
371 wdata[*len] = 0;
372 }
373
374done:
375 CloseHandle( file );
376 msi_free( data );
377 return wdata;
378}
#define read
Definition: acwin.h:96
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define MultiByteToWideChar
Definition: compat.h:110
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
char * LPSTR
Definition: xmlstorage.h:182

Referenced by MSI_DatabaseImport().

◆ MsiDatabaseExportA()

UINT WINAPI MsiDatabaseExportA ( MSIHANDLE  handle,
const char szTable,
const char szFolder,
const char szFilename 
)

Definition at line 1158 of file database.c.

1159{
1160 WCHAR *path = NULL, *file = NULL, *table = NULL;
1162
1163 TRACE( "%lu %s %s %s\n", handle, debugstr_a(szTable), debugstr_a(szFolder), debugstr_a(szFilename) );
1164
1165 if( szTable )
1166 {
1167 table = strdupAtoW( szTable );
1168 if( !table )
1169 goto end;
1170 }
1171
1172 if( szFolder )
1173 {
1174 path = strdupAtoW( szFolder );
1175 if( !path )
1176 goto end;
1177 }
1178
1179 if( szFilename )
1180 {
1181 file = strdupAtoW( szFilename );
1182 if( !file )
1183 goto end;
1184 }
1185
1187
1188end:
1189 msi_free( table );
1190 msi_free( path );
1191 msi_free( file );
1192
1193 return r;
1194}
static WCHAR * strdupAtoW(const char *str)
Definition: main.c:65
UINT WINAPI MsiDatabaseExportW(MSIHANDLE handle, const WCHAR *szTable, const WCHAR *szFolder, const WCHAR *szFilename)
Definition: database.c:1143
#define debugstr_a
Definition: kernel32.h:31

Referenced by test_forcecodepage(), test_invalid_functions(), and test_msiexport().

◆ MsiDatabaseExportW()

UINT WINAPI MsiDatabaseExportW ( MSIHANDLE  handle,
const WCHAR szTable,
const WCHAR szFolder,
const WCHAR szFilename 
)

Definition at line 1143 of file database.c.

1144{
1145 MSIDATABASE *db;
1146 UINT r;
1147
1148 TRACE( "%lu %s %s %s\n", handle, debugstr_w(szTable), debugstr_w(szFolder), debugstr_w(szFilename) );
1149
1151 return ERROR_INVALID_HANDLE;
1152
1153 r = MSI_DatabaseExport( db, szTable, szFolder, szFilename );
1154 msiobj_release( &db->hdr );
1155 return r;
1156}
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
static UINT MSI_DatabaseExport(MSIDATABASE *db, LPCWSTR table, LPCWSTR folder, LPCWSTR file)
Definition: database.c:1046
void * msihandle2msiinfo(MSIHANDLE handle, UINT type)
Definition: handle.c:158

Referenced by MsiDatabaseExportA().

◆ MsiDatabaseImportA()

UINT WINAPI MsiDatabaseImportA ( MSIHANDLE  handle,
const char szFolder,
const char szFilename 
)

Definition at line 853 of file database.c.

854{
855 WCHAR *path = NULL, *file = NULL;
857
858 TRACE( "%lu %s %s\n", handle, debugstr_a(szFolder), debugstr_a(szFilename) );
859
860 if( szFolder )
861 {
862 path = strdupAtoW( szFolder );
863 if( !path )
864 goto end;
865 }
866
867 if( szFilename )
868 {
869 file = strdupAtoW( szFilename );
870 if( !file )
871 goto end;
872 }
873
875
876end:
877 msi_free( path );
878 msi_free( file );
879
880 return r;
881}
UINT WINAPI MsiDatabaseImportW(MSIHANDLE handle, const WCHAR *szFolder, const WCHAR *szFilename)
Definition: database.c:838

Referenced by add_table_to_db(), create_database(), create_database_wordcount(), test_binary_import(), test_controlevent(), test_dbmerge(), test_embedded_nulls(), test_externalui_message(), test_forcecodepage(), test_invalid_functions(), test_msiimport(), test_quotes(), and test_top_level_action().

◆ MsiDatabaseImportW()

UINT WINAPI MsiDatabaseImportW ( MSIHANDLE  handle,
const WCHAR szFolder,
const WCHAR szFilename 
)

Definition at line 838 of file database.c.

839{
840 MSIDATABASE *db;
841 UINT r;
842
843 TRACE( "%lu %s %s\n", handle, debugstr_w(szFolder), debugstr_w(szFilename) );
844
847
848 r = MSI_DatabaseImport( db, szFolder, szFilename );
849 msiobj_release( &db->hdr );
850 return r;
851}
static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
Definition: database.c:733

Referenced by MsiDatabaseImportA(), and test_int_widths().

◆ MsiDatabaseMergeA()

UINT WINAPI MsiDatabaseMergeA ( MSIHANDLE  hDatabase,
MSIHANDLE  hDatabaseMerge,
const char szTableName 
)

Definition at line 1196 of file database.c.

1197{
1198 UINT r;
1199 WCHAR *table;
1200
1201 TRACE("%lu, %lu, %s\n", hDatabase, hDatabaseMerge, debugstr_a(szTableName) );
1202
1203 table = strdupAtoW(szTableName);
1204 r = MsiDatabaseMergeW(hDatabase, hDatabaseMerge, table);
1205
1206 msi_free(table);
1207 return r;
1208}
UINT WINAPI MsiDatabaseMergeW(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge, const WCHAR *szTableName)
Definition: database.c:1835

Referenced by test_dbmerge(), and test_invalid_functions().

◆ MsiDatabaseMergeW()

UINT WINAPI MsiDatabaseMergeW ( MSIHANDLE  hDatabase,
MSIHANDLE  hDatabaseMerge,
const WCHAR szTableName 
)

Definition at line 1835 of file database.c.

1836{
1837 struct list tabledata = LIST_INIT(tabledata);
1838 struct list *item, *cursor;
1839 MSIDATABASE *db, *merge;
1841 BOOL conflicts;
1842 UINT r;
1843
1844 TRACE( "%lu, %lu, %s\n", hDatabase, hDatabaseMerge, debugstr_w(szTableName) );
1845
1846 if (szTableName && !*szTableName)
1847 return ERROR_INVALID_TABLE;
1848
1851 if (!db || !merge)
1852 {
1854 goto done;
1855 }
1856
1857 r = gather_merge_data(db, merge, &tabledata);
1858 if (r != ERROR_SUCCESS)
1859 goto done;
1860
1861 conflicts = FALSE;
1863 {
1864 if (table->numconflicts)
1865 {
1866 conflicts = TRUE;
1867
1868 r = update_merge_errors(db, szTableName, table->name,
1869 table->numconflicts);
1870 if (r != ERROR_SUCCESS)
1871 break;
1872 }
1873 else
1874 {
1875 r = merge_table(db, table);
1876 if (r != ERROR_SUCCESS)
1877 break;
1878 }
1879 }
1880
1881 LIST_FOR_EACH_SAFE(item, cursor, &tabledata)
1882 {
1886 }
1887
1888 if (conflicts)
1890
1891done:
1892 msiobj_release(&db->hdr);
1893 msiobj_release(&merge->hdr);
1894 return r;
1895}
static UINT gather_merge_data(MSIDATABASE *db, MSIDATABASE *merge, struct list *tabledata)
Definition: database.c:1757
static UINT merge_table(MSIDATABASE *db, MERGETABLE *table)
Definition: database.c:1776
static UINT update_merge_errors(MSIDATABASE *db, LPCWSTR error, LPWSTR table, DWORD numconflicts)
Definition: database.c:1806
#define LIST_INIT(head)
Definition: queue.h:197
#define ERROR_INVALID_TABLE
Definition: winerror.h:986

Referenced by MsiDatabaseMergeA().

◆ MsiGetDatabaseState()

MSIDBSTATE WINAPI MsiGetDatabaseState ( MSIHANDLE  handle)

Definition at line 1897 of file database.c.

1898{
1900 MSIDATABASE *db;
1901
1902 TRACE( "%lu\n", handle );
1903
1905 return MSIDBSTATE_ERROR;
1906
1907 if (db->mode != MSI_OPEN_READONLY )
1909 msiobj_release( &db->hdr );
1910
1911 return ret;
1912}
enum tagMSIDBSTATE MSIDBSTATE
@ MSIDBSTATE_READ
Definition: msiquery.h:144
@ MSIDBSTATE_ERROR
Definition: msiquery.h:143
@ MSIDBSTATE_WRITE
Definition: msiquery.h:145

Referenced by test_invalid_functions().

◆ MsiOpenDatabaseA()

UINT WINAPI MsiOpenDatabaseA ( LPCSTR  szDBPath,
LPCSTR  szPersist,
MSIHANDLE phDB 
)

Definition at line 317 of file database.c.

318{
320 LPWSTR szwDBPath = NULL, szwPersist = NULL;
321
322 TRACE("%s %s %p\n", debugstr_a(szDBPath), debugstr_a(szPersist), phDB);
323
324 if( szDBPath )
325 {
326 szwDBPath = strdupAtoW( szDBPath );
327 if( !szwDBPath )
328 goto end;
329 }
330
331 if( !IS_INTMSIDBOPEN(szPersist) )
332 {
333 szwPersist = strdupAtoW( szPersist );
334 if( !szwPersist )
335 goto end;
336 }
337 else
338 szwPersist = (LPWSTR)(DWORD_PTR)szPersist;
339
340 r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );
341
342end:
343 if( !IS_INTMSIDBOPEN(szPersist) )
344 msi_free( szwPersist );
345 msi_free( szwDBPath );
346
347 return r;
348}
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
Definition: database.c:298
uint32_t DWORD_PTR
Definition: typedefs.h:65

Referenced by test_states().

◆ MsiOpenDatabaseW()

UINT WINAPI MsiOpenDatabaseW ( LPCWSTR  szDBPath,
LPCWSTR  szPersist,
MSIHANDLE phDB 
)

Definition at line 298 of file database.c.

299{
300 MSIDATABASE *db;
301 UINT ret;
302
303 TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB);
304
305 ret = MSI_OpenDatabaseW( szDBPath, szPersist, &db );
306 if( ret == ERROR_SUCCESS )
307 {
308 *phDB = alloc_msihandle( &db->hdr );
309 if (! *phDB)
311 msiobj_release( &db->hdr );
312 }
313
314 return ret;
315}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
Definition: database.c:140
MSIHANDLE alloc_msihandle(MSIOBJECTHDR *obj)
Definition: handle.c:111

Referenced by create_database(), create_database_wordcount(), create_db(), create_package_db(), generate_transform(), get_patch_product_codes(), helper_createpackage(), InstallerImpl_OpenDatabase(), MsiOpenDatabaseA(), MsiVerifyPackageW(), set_admin_summary_info(), set_suminfo(), test_access(), test_binary(), test_binary_import(), test_carriagereturn(), test_collation(), test_createtable(), test_customaction1(), test_dbmerge(), test_dbtopackage(), test_defaultdatabase(), test_deleterow(), test_droptable(), test_embedded_nulls(), test_fieldzero(), test_forcecodepage(), test_icon_table(), test_int_widths(), test_integers(), test_longstrings(), test_msibadqueries(), test_msidatabase(), test_msiexport(), test_MsiGetProductProperty(), test_MsiGetSourcePath(), test_msiimport(), test_msiinsert(), test_MsiOpenDatabase(), test_msipackage(), test_noquotes(), test_packagecoltypes(), test_quotes(), test_rows_order(), test_select_column_names(), test_shortlongsource(), test_simple_patch(), test_special_tables(), test_states(), test_storages_table(), test_streamtable(), test_stringtable(), test_suminfo(), test_suminfo_import(), test_summary_binary(), test_tables_order(), test_try_transform(), test_update(), test_viewfetch_wraparound(), test_viewmodify(), test_viewmodify_assign(), test_viewmodify_delete(), test_viewmodify_delete_temporary(), test_viewmodify_refresh(), test_viewmodify_update(), and test_where_viewmodify().

◆ s_remote_DatabaseGetPrimaryKeys()

UINT __cdecl s_remote_DatabaseGetPrimaryKeys ( MSIHANDLE  db,
LPCWSTR  table,
struct wire_record **  rec 
)

Definition at line 1919 of file database.c.

1920{
1923 *rec = NULL;
1924 if (!r)
1925 *rec = marshal_record(handle);
1927 return r;
1928}
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
struct wire_record * marshal_record(MSIHANDLE handle) DECLSPEC_HIDDEN
Definition: record.c:1109
UINT WINAPI MsiDatabaseGetPrimaryKeysW(MSIHANDLE hdb, const WCHAR *table, MSIHANDLE *phRec)
Definition: msiquery.c:1080
unsigned long MSIHANDLE
Definition: winemsi.idl:27

◆ s_remote_DatabaseGetSummaryInformation()

UINT __cdecl s_remote_DatabaseGetSummaryInformation ( MSIHANDLE  db,
UINT  updatecount,
MSIHANDLE suminfo 
)

Definition at line 1930 of file database.c.

1931{
1932 return MsiGetSummaryInformationW(db, NULL, updatecount, suminfo);
1933}
static const CHAR suminfo[]
Definition: db.c:2206
UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, const WCHAR *szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle)
Definition: suminfo.c:514

◆ s_remote_DatabaseIsTablePersistent()

MSICONDITION __cdecl s_remote_DatabaseIsTablePersistent ( MSIHANDLE  db,
LPCWSTR  table 
)

Definition at line 1914 of file database.c.

1915{
1917}
MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(MSIHANDLE hDatabase, const WCHAR *szTableName)
Definition: msiquery.c:1167

◆ s_remote_DatabaseOpenView()

UINT __cdecl s_remote_DatabaseOpenView ( MSIHANDLE  db,
LPCWSTR  query,
MSIHANDLE view 
)

Definition at line 1935 of file database.c.

1936{
1937 return MsiDatabaseOpenViewW(db, query, view);
1938}
UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, LPCWSTR szQuery, MSIHANDLE *phView)
Definition: msiquery.c:236

◆ update_merge_errors()

static UINT update_merge_errors ( MSIDATABASE db,
LPCWSTR  error,
LPWSTR  table,
DWORD  numconflicts 
)
static

Definition at line 1806 of file database.c.

1808{
1809 UINT r;
1810 MSIQUERY *view;
1811
1812 if (!TABLE_Exists(db, error))
1813 {
1814 r = MSI_OpenQuery(db, &view, L"CREATE TABLE `%s` (`Table` CHAR(255) NOT NULL, `NumRowMergeConflicts` SHORT "
1815 "NOT NULL PRIMARY KEY `Table`)" , error);
1816 if (r != ERROR_SUCCESS)
1817 return r;
1818
1820 msiobj_release(&view->hdr);
1821 if (r != ERROR_SUCCESS)
1822 return r;
1823 }
1824
1825 r = MSI_OpenQuery(db, &view, L"INSERT INTO `%s` (`Table`, `NumRowMergeConflicts`) VALUES ('%s', %d)", error,
1826 table, numconflicts);
1827 if (r != ERROR_SUCCESS)
1828 return r;
1829
1831 msiobj_release(&view->hdr);
1832 return r;
1833}
#define error(str)
Definition: mkdosfs.c:1605

Referenced by MsiDatabaseMergeW().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msi  )