36 #include "msiserver.h" 53 #define IS_INTMSIDBOPEN(x) (((ULONG_PTR)(x) >> 16) == 0) 61 IStorage_Release(
t->stg );
82 IStorage_AddRef( stg );
95 IStorage_Release( db->
storage );
108 hr = IStorage_SetClass( stg,
clsid );
111 WARN(
"failed to set class id %#lx\n",
hr);
119 WARN(
"failed to create _Tables stream %#lx\n",
hr);
126 WARN(
"failed to initialize string table %#lx\n",
hr);
130 hr = IStorage_Commit( stg, 0 );
133 WARN(
"failed to commit changes %#lx\n",
hr);
167 szDBPath = szPersist;
174 TRACE(
"Database is a patch\n");
190 r =
db_initialize( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase );
199 r =
db_initialize( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase );
224 r = IStorage_Stat( stg, &
stat, STATFLAG_NONAME );
227 FIXME(
"Failed to stat storage\n");
235 ERR(
"storage GUID is not a MSI database GUID %s\n",
242 ERR(
"storage GUID is not the MSI patch GUID %s\n",
252 FIXME(
"Failed to allocate a handle\n");
286 IStorage_AddRef( stg );
293 IStorage_Release( stg );
388 while (chars_left && *
ptr !=
'\n')
406 while (chars_left && *
ptr ==
'\r')
413 while (chars_left && *
ptr !=
'\t' && *
ptr !=
'\n' && *
ptr !=
'\r')
426 if (*
ptr ==
'\n' || *
ptr ==
'\r')
428 while (chars_left && (*
ptr ==
'\n' || *
ptr ==
'\r'))
439 (*entries)[
i] = save;
446 *num_entries =
count;
475 for (
i = 0;
i < num_columns;
i++)
480 if (
i == num_columns - 1)
516 WARN(
"invalid int width %lu\n",
len);
555 for (
i = 0,
size = 1;
i < num_keys;
i++)
562 for (
i = 0,
ptr = keys;
i < num_keys;
i++)
588 LPWSTR prelude, columns_sql, postlude;
594 if (!prelude || !columns_sql || !postlude)
655 for (
i = 0;
i < num_columns;
i++)
659 case 'L':
case 'l':
case 'S':
case 's':
681 ERR(
"Unhandled column type: %c\n",
types[
i][0]);
692 int num_columns,
int num_records,
712 for (
i = 0;
i < num_records;
i++)
736 DWORD len,
i, num_labels, num_types, num_columns, num_records = 0;
765 if (num_columns == 1 && !columns[0][0] && num_labels == 1 && !labels[0][0] &&
766 num_types == 2 && !
wcscmp(
types[1],
L"_ForceCodepage" ))
772 if (num_columns != num_types)
797 records = temp_records;
800 if (!
wcscmp(labels[0],
L"_SummaryInformation"))
831 for (
i = 0;
i < num_records;
i++)
929 DWORD sz, read_size, write_size;
958 read_size =
sizeof(
buffer);
959 while (read_size ==
sizeof(
buffer))
1009 sep = (
i <
count) ?
"\t" :
"\r\n";
1023 static const char fmt[] =
"\r\n\r\n%u\t_ForceCodepage\r\n";
1035 static const char header[] =
"PropertyId\tValue\r\n" 1037 "_SummaryInformation\tPropertyId\r\n";
1201 TRACE(
"%lu, %lu, %s\n", hDatabase, hDatabaseMerge,
debugstr_a(szTableName) );
1241 if (((type1[0] ==
'l') || (type1[0] ==
's')) &&
1242 ((type2[0] ==
'l') || (type2[0] ==
's')))
1245 if (((type1[0] ==
'L') || (type1[0] ==
'S')) &&
1246 ((type2[0] ==
'L') || (type2[0] ==
'S')))
1249 return !
wcscmp( type1, type2 );
1283 dbrec = mergerec =
NULL;
1404 ERR(
"failed to get string!\n");
1437 setptr =
L"`%s` = %s ";
1439 setptr =
L"`%s` = %s AND ";
1494 table->numconflicts++;
1511 if (!mergerow->
data)
1537 *numlabels =
count + 1;
1578 *numcolumns =
count;
1633 for (
i = 0;
i <
table->numlabels;
i++)
1641 for (
i = 0;
i <
table->numcolumns;
i++)
1649 for (
i = 0;
i <
table->numtypes;
i++)
1693 table->numconflicts = 0;
1741 data->curview = mergeview;
1758 struct list *tabledata)
1770 data.tabledata = tabledata;
1814 r =
MSI_OpenQuery(db, &
view,
L"CREATE TABLE `%s` (`Table` CHAR(255) NOT NULL, `NumRowMergeConflicts` SHORT " 1815 "NOT NULL PRIMARY KEY `Table`)" ,
error);
1826 table, numconflicts);
1844 TRACE(
"%lu, %lu, %s\n", hDatabase, hDatabaseMerge,
debugstr_w(szTableName) );
1846 if (szTableName && !*szTableName)
1864 if (
table->numconflicts)
1869 table->numconflicts);
void msiobj_addref(MSIOBJECTHDR *info)
#define ERROR_INVALID_PARAMETER
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
struct wire_record * marshal_record(MSIHANDLE handle) DECLSPEC_HIDDEN
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
MSIRECORD * MSI_CloneRecord(MSIRECORD *) DECLSPEC_HIDDEN
static LPWSTR msi_build_createsql_postlude(LPWSTR *primary_keys, DWORD num_keys)
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
static HRESULT db_initialize(IStorage *stg, const GUID *clsid)
MSICONDITION WINAPI MsiDatabaseIsTablePersistentW(MSIHANDLE hDatabase, const WCHAR *szTableName)
UINT MSI_ViewGetColumnInfo(MSIQUERY *, MSICOLINFO, MSIRECORD **) DECLSPEC_HIDDEN
struct _tagMERGEDATA MERGEDATA
static UINT merge_table(MSIDATABASE *db, MERGETABLE *table)
static UINT msi_export_summaryinformation(MSIDATABASE *db, HANDLE handle)
UINT TABLE_CreateView(MSIDATABASE *db, LPCWSTR name, MSIVIEW **view) DECLSPEC_HIDDEN
UINT WINAPI MsiOpenDatabaseA(LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
#define MSI_INITIAL_MEDIA_TRANSFORM_DISKID
#define ERROR_NO_MORE_ITEMS
UINT WINAPI MsiDatabaseExportA(MSIHANDLE handle, const char *szTable, const char *szFolder, const char *szFilename)
#define STGM_SHARE_EXCLUSIVE
ACPI_SIZE strlen(const char *String)
static UINT msi_export_forcecodepage(HANDLE handle, UINT codepage)
UINT MSI_ViewModify(MSIQUERY *, MSIMODIFY, MSIRECORD *) DECLSPEC_HIDDEN
GLsizei const GLchar ** path
static WCHAR * strdupW(const WCHAR *src)
GLdouble GLdouble GLdouble r
UINT __cdecl s_remote_DatabaseGetPrimaryKeys(MSIHANDLE db, LPCWSTR table, struct wire_record **rec)
GLuint GLuint GLsizei count
UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
static UINT merge_diff_row(MSIRECORD *rec, LPVOID param)
UINT WINAPI MsiDatabaseGetPrimaryKeysW(MSIHANDLE hdb, const WCHAR *table, MSIHANDLE *phRec)
#define ERROR_INVALID_HANDLE
UINT MSI_RecordGetStringW(MSIRECORD *, UINT, LPWSTR, LPDWORD) DECLSPEC_HIDDEN
UINT MSI_ViewExecute(MSIQUERY *, MSIRECORD *) DECLSPEC_HIDDEN
BOOL MSI_RecordsAreEqual(MSIRECORD *, MSIRECORD *) DECLSPEC_HIDDEN
static UINT msi_get_table_labels(MSIDATABASE *db, LPCWSTR table, LPWSTR **labels, DWORD *numlabels)
#define GetCurrentDirectoryW(x, y)
GLsizei GLenum GLenum * types
__WINE_SERVER_LIST_INLINE void list_add_head(struct list *list, struct list *elem)
#define ERROR_DATATYPE_MISMATCH
const struct column * columns
UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase, const WCHAR *szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle)
#define ERROR_NOT_ENOUGH_MEMORY
#define INVALID_HANDLE_VALUE
UINT write_stream_data(IStorage *stg, LPCWSTR stname, LPCVOID data, UINT sz, BOOL bTable) DECLSPEC_HIDDEN
DWORD WINAPI GetLastError(VOID)
static LPWSTR create_diff_row_query(MSIDATABASE *merge, MSIQUERY *view, LPWSTR table, MSIRECORD *rec)
void enum_stream_names(IStorage *stg) DECLSPEC_HIDDEN
GLenum GLsizei GLenum GLenum const GLvoid * table
static void msi_free(void *mem)
static UINT msi_export_field(HANDLE handle, MSIRECORD *row, UINT field)
string_table * msi_load_string_table(IStorage *stg, UINT *bytes_per_strref) DECLSPEC_HIDDEN
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define cmp(status, error)
#define MSIHANDLETYPE_DATABASE
#define MSI_INITIAL_MEDIA_TRANSFORM_OFFSET
#define MSI_OPEN_CREATEDIRECT
static UINT update_merge_errors(MSIDATABASE *db, LPCWSTR error, LPWSTR table, DWORD numconflicts)
#define IS_INTMSIDBOPEN(x)
static BOOL merge_type_match(LPCWSTR type1, LPCWSTR type2)
static void * msi_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2)
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
UINT MSI_RecordGetStringA(MSIRECORD *, UINT, LPSTR, LPDWORD) DECLSPEC_HIDDEN
UINT MSI_DatabaseGetPrimaryKeys(MSIDATABASE *, LPCWSTR, MSIRECORD **) DECLSPEC_HIDDEN
UINT WINAPIV MSI_OpenQuery(MSIDATABASE *, MSIQUERY **, LPCWSTR,...) DECLSPEC_HIDDEN
__WINE_SERVER_LIST_INLINE struct list * list_head(const struct list *list)
static const CHAR suminfo[]
BOOL TABLE_Exists(MSIDATABASE *db, LPCWSTR name) DECLSPEC_HIDDEN
#define sprintf(buf, format,...)
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
void * alloc_msiobject(UINT type, UINT size, msihandledestructor destroy)
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
#define ERROR_WRITE_FAULT
UINT MSI_RecordSetInteger(MSIRECORD *, UINT, int) DECLSPEC_HIDDEN
VOID msi_destroy_stringtable(string_table *st) DECLSPEC_HIDDEN
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
#define ERROR_FUNCTION_FAILED
UINT MSI_ViewFetch(MSIQUERY *, MSIRECORD **) DECLSPEC_HIDDEN
UINT MSI_RecordSetStreamFromFileW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
_STLP_MOVE_TO_STD_NAMESPACE _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result)
static void free_transforms(MSIDATABASE *db)
static UINT merge_verify_primary_keys(MSIDATABASE *db, MSIDATABASE *mergedb, LPCWSTR table)
#define MSI_OPEN_READONLY
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
static UINT msi_export_row(MSIRECORD *row, void *arg)
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
UINT WINAPI MsiDatabaseMergeA(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge, const char *szTableName)
static UINT msi_export_record(struct row_export_info *row_export_info, MSIRECORD *row, UINT start)
static LPWSTR msi_read_text_archive(LPCWSTR path, DWORD *len)
UINT WINAPI MsiDatabaseMergeW(MSIHANDLE hDatabase, MSIHANDLE hDatabaseMerge, const WCHAR *szTableName)
static UINT construct_record(DWORD num_columns, LPWSTR *types, LPWSTR *data, LPWSTR path, MSIRECORD **rec)
void free_cached_tables(MSIDATABASE *db) DECLSPEC_HIDDEN
MSIDBSTATE WINAPI MsiGetDatabaseState(MSIHANDLE handle)
UINT MSI_ViewClose(MSIQUERY *) DECLSPEC_HIDDEN
void append_storage_to_db(MSIDATABASE *db, IStorage *stg)
UINT __cdecl s_remote_DatabaseGetSummaryInformation(MSIHANDLE db, UINT updatecount, MSIHANDLE *suminfo)
static VOID MSI_CloseDatabase(MSIOBJECTHDR *arg)
UINT WINAPI MsiDatabaseImportW(MSIHANDLE handle, const WCHAR *szFolder, const WCHAR *szFilename)
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
static UINT MSI_DatabaseExport(MSIDATABASE *db, LPCWSTR table, LPCWSTR folder, LPCWSTR file)
static UINT merge_diff_tables(MSIRECORD *rec, LPVOID param)
UINT __cdecl s_remote_DatabaseOpenView(MSIHANDLE db, LPCWSTR query, MSIHANDLE *view)
MSICONDITION __cdecl s_remote_DatabaseIsTablePersistent(MSIHANDLE db, LPCWSTR table)
#define MAX_STREAM_NAME_LEN
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
struct _tagMERGEROW MERGEROW
static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
HRESULT WINAPI StgOpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
static UINT msi_export_stream(const WCHAR *folder, const WCHAR *table, MSIRECORD *row, UINT field, UINT start)
static LPWSTR msi_build_createsql_columns(LPWSTR *columns_data, LPWSTR *types, DWORD num_columns)
static LPWSTR msi_build_createsql_prelude(LPWSTR table)
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
static UINT msi_get_query_types(MSIQUERY *query, LPWSTR **types, DWORD *numtypes)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
static LPWSTR get_key_value(MSIQUERY *view, LPCWSTR key, MSIRECORD *rec)
int msiobj_release(MSIOBJECTHDR *info)
struct _tagMERGETABLE MERGETABLE
static UINT msi_get_query_columns(MSIQUERY *query, LPWSTR **columns, DWORD *numcolumns)
HRESULT msi_init_string_table(IStorage *stg) DECLSPEC_HIDDEN
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
#define FILE_ATTRIBUTE_NORMAL
enum tagMSIDBSTATE MSIDBSTATE
static UINT msi_add_table_to_db(MSIDATABASE *db, LPWSTR *columns, LPWSTR *types, LPWSTR *labels, DWORD num_labels, DWORD num_columns)
HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
static UINT msi_get_merge_table(MSIDATABASE *db, LPCWSTR name, MERGETABLE **ptable)
UINT msi_add_suminfo(MSIDATABASE *db, LPWSTR **records, int num_records, int num_columns) DECLSPEC_HIDDEN
int _cdecl swprintf(const WCHAR *,...)
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
#define ERROR_INVALID_TABLE
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
UINT(* delete)(struct tagMSIVIEW *)
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
UINT msi_set_string_table_codepage(string_table *st, UINT codepage) DECLSPEC_HIDDEN
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
#define ERROR_OPEN_FAILED
WCHAR * msi_dup_record_field(MSIRECORD *row, INT index) DECLSPEC_HIDDEN
static void free_merge_table(MERGETABLE *table)
static UINT gather_merge_data(MSIDATABASE *db, MSIDATABASE *merge, struct list *tabledata)
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
MSIHANDLE alloc_msihandle(MSIOBJECTHDR *obj)
#define ReadFile(a, b, c, d, e)
#define MSI_OPEN_TRANSACT
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
#define MultiByteToWideChar
UINT MSI_RecordReadStream(MSIRECORD *, UINT, char *, LPDWORD) DECLSPEC_HIDDEN
UINT media_transform_disk_id
UINT WINAPI MsiDatabaseExportW(MSIHANDLE handle, const WCHAR *szTable, const WCHAR *szFolder, const WCHAR *szFilename)
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)
UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, LPCWSTR szQuery, MSIHANDLE *phView)
UINT msi_export_suminfo(MSIDATABASE *db, HANDLE handle) DECLSPEC_HIDDEN
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
static IOleDocumentView * view
UINT WINAPI MsiDatabaseImportA(MSIHANDLE handle, const char *szFolder, const char *szFilename)
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
#define ERROR_ALREADY_EXISTS
GLuint GLuint GLsizei GLenum type
#define STGM_SHARE_DENY_WRITE
void * msihandle2msiinfo(MSIHANDLE handle, UINT type)
static void free_streams(MSIDATABASE *db)
UINT MSI_IterateRecords(MSIQUERY *, LPDWORD, record_func, LPVOID) DECLSPEC_HIDDEN
static LPWSTR msi_import_stream_filename(LPCWSTR path, LPCWSTR name)
WINE_DEFAULT_DEBUG_CHANNEL(msi)
static WCHAR * strdupAtoW(const char *str)
static void merge_free_rows(MERGETABLE *table)
#define MSI_OPEN_PATCHFILE
UINT media_transform_offset
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
UINT msi_get_string_table_codepage(const string_table *st) DECLSPEC_HIDDEN
UINT MSI_RecordGetFieldCount(const MSIRECORD *rec) DECLSPEC_HIDDEN
static void msi_parse_line(LPWSTR *line, LPWSTR **entries, DWORD *num_entries, DWORD *len)
static UINT merge_verify_colnames(MSIQUERY *dbview, MSIQUERY *mergeview)
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
static struct @1508 save_path[MOVE_LIST_SIZE]
UINT(* insert_row)(struct tagMSIVIEW *view, MSIRECORD *record, UINT row, BOOL temporary)
UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY **) DECLSPEC_HIDDEN
GLuint const GLchar * name