30 #include "wine/unicode.h" 75 if (*
p !=
'{' || !
q)
goto error;
80 ret->product_code_from[
len] = 0;
87 ret->version_from[
len] = 0;
91 if (*
p !=
'{' || !
q)
goto error;
96 ret->product_code_to[
len] = 0;
107 if (*
p !=
'{' || !
q)
goto error;
112 ret->upgrade_code[
len] = 0;
123 static const UINT supported_flags =
128 UINT r, valid_flags = 0, wanted_flags = 0;
129 WCHAR *
template, *product, *
p;
135 WARN(
"no summary information!\n");
139 wanted_flags &= 0xffff;
140 TRACE(
"validation flags 0x%04x\n", wanted_flags);
145 if (wanted_flags & ~supported_flags)
147 FIXME(
"unsupported validation flags 0x%04x\n", wanted_flags);
153 WARN(
"no template property!\n");
160 WARN(
"no product property!\n");
185 if (!product_code_installed)
192 if (!
strcmpW(
desc->product_code_from, product_code_installed ))
204 if (!product_version_installed)
213 if (major_installed ==
major)
218 msi_free( product_version_installed );
225 if (!product_version_installed)
234 if (major_installed ==
major && minor_installed ==
minor)
236 msi_free( product_version_installed );
242 if (!upgrade_code_installed)
248 if (!
strcmpW(
desc->upgrade_code, upgrade_code_installed ))
256 TRACE(
"applicable transform\n");
281 IStorage_Release( stg );
299 ERR(
"no product code to check\n");
368 'S',
'E',
'L',
'E',
'C',
'T',
' ',
'`',
'S',
'o',
'u',
'r',
'c',
'e',
'`',
' ',
'F',
'R',
'O',
'M',
' ',
369 '`',
'M',
'e',
'd',
'i',
'a',
'`',
' ',
'W',
'H',
'E',
'R',
'E',
' ',
'`',
'S',
'o',
'u',
'r',
'c',
'e',
'`',
' ',
370 'I',
'S',
' ',
'N',
'O',
'T',
' ',
'N',
'U',
'L',
'L',0};
419 pos->count =
pos->max = 0;
444 'S',
'E',
'L',
'E',
'C',
'T',
' ',
'*',
' ',
'F',
'R',
'O',
'M',
' ',
'P',
'a',
't',
'c',
'h',
' ',
445 'W',
'H',
'E',
'R',
'E',
' ',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
' ',
'<',
'=',
' ',
'?',
' ',
446 'O',
'R',
'D',
'E',
'R',
' ',
'B',
'Y',
' ',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',0};
482 'S',
'E',
'L',
'E',
'C',
'T',
' ',
'*',
' ',
'F',
'R',
'O',
'M',
' ',
'F',
'i',
'l',
'e',
' ',
483 'W',
'H',
'E',
'R',
'E',
' ',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
' ',
'<',
'=',
' ',
'?',
' ',
484 'O',
'R',
'D',
'E',
'R',
' ',
'B',
'Y',
' ',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',0};
544 static const WCHAR delete_query[] = {
545 'D',
'E',
'L',
'E',
'T',
'E',
' ',
'F',
'R',
'O',
'M',
' ',
'`',
'P',
'a',
't',
'c',
'h',
'`',
' ',
546 'W',
'H',
'E',
'R',
'E',
' ',
'`',
'F',
'i',
'l',
'e',
'_',
'`',
' ',
'=',
' ',
'?',
' ',
547 'A',
'N',
'D',
' ',
'`',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
'`',
' ',
'=',
' ',
'?',0};
548 static const WCHAR insert_query[] = {
549 'I',
'N',
'S',
'E',
'R',
'T',
' ',
'I',
'N',
'T',
'O',
' ',
'`',
'P',
'a',
't',
'c',
'h',
'`',
' ',
550 '(',
'`',
'F',
'i',
'l',
'e',
'_',
'`',
',',
'`',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
'`',
',',
551 '`',
'P',
'a',
't',
'c',
'h',
'S',
'i',
'z',
'e',
'`',
',',
'`',
'A',
't',
't',
'r',
'i',
'b',
'u',
't',
'e',
's',
'`',
',',
552 '`',
'H',
'e',
'a',
'd',
'e',
'r',
'`',
',',
'`',
'S',
't',
'r',
'e',
'a',
'm',
'R',
'e',
'f',
'_',
'`',
')',
' ',
553 'V',
'A',
'L',
'U',
'E',
'S',
' ',
'(',
'?',
',',
'?',
',',
'?',
',',
'?',
',',
'?',
',',
'?',
')',0};
562 MSIQUERY *delete_view, *insert_view;
593 static const WCHAR file_query[] = {
594 'S',
'E',
'L',
'E',
'C',
'T',
' ',
'*',
' ',
'F',
'R',
'O',
'M',
' ',
'`',
'F',
'i',
'l',
'e',
'`',
' ',
595 'W',
'H',
'E',
'R',
'E',
' ',
'`',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
'`',
' ',
'>',
'=',
' ',
'?',
' ',
596 'A',
'N',
'D',
' ',
'`',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
'`',
' ',
'<',
'=',
' ',
'?',
' ',
597 'O',
'R',
'D',
'E',
'R',
' ',
'B',
'Y',
' ',
'`',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
'`',0};
598 static const WCHAR patch_query[] = {
599 'S',
'E',
'L',
'E',
'C',
'T',
' ',
'*',
'F',
'R',
'O',
'M',
' ',
'`',
'P',
'a',
't',
'c',
'h',
'`',
' ',
600 'W',
'H',
'E',
'R',
'E',
' ',
'`',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
'`',
' ',
'>',
'=',
' ',
'?',
' ',
601 'A',
'N',
'D',
' ',
'`',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
'`',
' ',
'<',
'=',
' ',
'?',
' ',
602 'O',
'R',
'D',
'E',
'R',
' ',
'B',
'Y',
' ',
'`',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
'`',0};
654 'S',
'E',
'L',
'E',
'C',
'T',
' ',
'*',
' ',
'F',
'R',
'O',
'M',
' ',
'`',
'M',
'e',
'd',
'i',
'a',
'`',
' ',
655 'W',
'H',
'E',
'R',
'E',
' ',
'`',
'S',
'o',
'u',
'r',
'c',
'e',
'`',
' ',
'I',
'S',
' ',
'N',
'O',
'T',
' ',
'N',
'U',
'L',
'L',
' ',
656 'A',
'N',
'D',
' ',
'`',
'C',
'a',
'b',
'i',
'n',
'e',
't',
'`',
' ',
'I',
'S',
' ',
'N',
'O',
'T',
' ',
'N',
'U',
'L',
'L',
' ',
657 'O',
'R',
'D',
'E',
'R',
' ',
'B',
'Y',
' ',
'`',
'D',
'i',
's',
'k',
'I',
'd',
'`',0};
672 static const WCHAR delete_query[] = {
673 'D',
'E',
'L',
'E',
'T',
'E',
' ',
'F',
'R',
'O',
'M',
' ',
'`',
'M',
'e',
'd',
'i',
'a',
'`',
' ',
674 'W',
'H',
'E',
'R',
'E',
' ',
'`',
'D',
'i',
's',
'k',
'I',
'd',
'`',
'=',
'?',0};
675 static const WCHAR insert_query[] = {
676 'I',
'N',
'S',
'E',
'R',
'T',
' ',
'I',
'N',
'T',
'O',
' ',
'`',
'M',
'e',
'd',
'i',
'a',
'`',
' ',
677 '(',
'`',
'D',
'i',
's',
'k',
'I',
'd',
'`',
',',
'`',
'L',
'a',
's',
't',
'S',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
'`',
',',
678 '`',
'D',
'i',
's',
'k',
'P',
'r',
'o',
'm',
'p',
't',
'`',
',',
'`',
'C',
'a',
'b',
'i',
'n',
'e',
't',
'`',
',',
679 '`',
'V',
'o',
'l',
'u',
'm',
'e',
'L',
'a',
'b',
'e',
'l',
'`',
',',
'`',
'S',
'o',
'u',
'r',
'c',
'e',
'`',
')',
' ',
680 'V',
'A',
'L',
'U',
'E',
'S',
' ',
'(',
'?',
',',
'?',
',',
'?',
',',
'?',
',',
'?',
',',
'?',
')',0};
684 struct list media_list;
694 TRACE(
"query failed %u\n",
r);
701 TRACE(
"disk_id %u\n", disk_id);
711 media->disk_id = disk_id;
723 MSIQUERY *delete_view, *insert_view;
740 TRACE(
"disk id %u\n", disk_id);
741 TRACE(
"last sequence %u\n",
media->last_sequence);
815 last_sequence +=
pos->min;
821 ERR(
"Failed to set offsets, expect breakage (%u)\n",
r);
826 ERR(
"Failed to update Media table entry, expect breakage (%u)\n",
r);
842 'S',
'E',
'L',
'E',
'C',
'T',
' ',
'`',
'V',
'a',
'l',
'u',
'e',
'`',
' ',
'F',
'R',
'O',
'M',
' ',
843 '`',
'M',
's',
'i',
'P',
'a',
't',
'c',
'h',
'M',
'e',
't',
'a',
'd',
'a',
't',
'a',
'`',
' ',
844 'W',
'H',
'E',
'R',
'E',
' ',
'`',
'C',
'o',
'm',
'p',
'a',
'n',
'y',
'`',
' ',
'I',
'S',
' ',
845 'N',
'U',
'L',
'L',
' ',
'A',
'N',
'D',
' ',
'`',
'P',
'r',
'o',
'p',
'e',
'r',
't',
'y',
'`',
'=',
846 '\'',
'A',
'l',
'l',
'o',
'w',
'R',
'e',
'm',
'o',
'v',
'a',
'l',
'\'',0};
865 FIXME(
"check other criteria\n" );
914 static const WCHAR dotmsp[] = {
'.',
'm',
's',
'p',0};
938 TRACE(
"patch not applicable\n");
972 LPWSTR patch_list, *patches;
990 static const WCHAR szTransforms[] = {
'T',
'R',
'A',
'N',
'S',
'F',
'O',
'R',
'M',
'S',0};
991 LPWSTR xform_list, *xforms;
999 if (xforms[
i][0] ==
':')
1045 ERR(
"failed to get patch filename %u\n",
r);
1064 ERR(
"failed to parse patch summary %u\n",
r);
1080 ERR(
"failed to apply patch %u\n",
r);
LPWSTR msi_suminfo_dup_string(MSISUMMARYINFO *si, UINT uiProperty) DECLSPEC_HIDDEN
UINT msi_table_apply_transform(MSIDATABASE *db, IStorage *stg) DECLSPEC_HIDDEN
#define MSIDBOPEN_READONLY
void msi_free_patchinfo(MSIPATCHINFO *patch)
BOOL WINAPI PathIsRelativeW(LPCWSTR lpszPath)
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
static UINT msi_parse_patch_summary(MSISUMMARYINFO *si, MSIPATCHINFO **patch)
UINT msi_check_patch_applicable(MSIPACKAGE *package, MSISUMMARYINFO *si)
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
#define MSIDBOPEN_PATCHFILE
#define MSI_INITIAL_MEDIA_TRANSFORM_DISKID
#define STGM_SHARE_EXCLUSIVE
UINT MSI_ViewModify(MSIQUERY *, MSIMODIFY, MSIRECORD *) DECLSPEC_HIDDEN
static WCHAR * strdupW(const WCHAR *src)
GLdouble GLdouble GLdouble r
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
GLuint GLuint GLsizei count
UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
UINT MSI_ViewExecute(MSIQUERY *, MSIRECORD *) DECLSPEC_HIDDEN
static UINT patch_set_media_source_prop(MSIPACKAGE *package)
static UINT msi_apply_patch_db(MSIPACKAGE *package, MSIDATABASE *patch_db, MSIPATCHINFO *patch)
#define MSI_INITIAL_MEDIA_TRANSFORM_OFFSET
static BOOL match_language(MSIPACKAGE *package, LANGID langid)
UINT msi_apply_transforms(MSIPACKAGE *package)
static const WCHAR INSTALLPROPERTY_LOCALPACKAGEW[]
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
static UINT patch_add_media(MSIPACKAGE *package, IStorage *storage, MSIPATCHINFO *patch)
static void patch_offset_get_filepatches(MSIDATABASE *db, UINT last_sequence, struct patch_offset_list *pos)
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
UINT MSI_RecordSetInteger(MSIRECORD *, UINT, int) DECLSPEC_HIDDEN
LPWSTR msi_get_suminfo_product(IStorage *stg) DECLSPEC_HIDDEN
static UINT patch_update_file_sequence(MSIDATABASE *db, const struct patch_offset_list *pos, MSIQUERY *view, MSIRECORD *rec)
static void patch_offset_get_files(MSIDATABASE *db, UINT last_sequence, struct patch_offset_list *pos)
#define ERROR_FUNCTION_FAILED
UINT MSI_ViewFetch(MSIQUERY *, MSIRECORD **) DECLSPEC_HIDDEN
static const WCHAR szUpgradeCode[]
static const WCHAR desc[]
static void free_transform_desc(struct transform_desc *desc)
#define ERROR_PATCH_PACKAGE_INVALID
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
static const WCHAR patch_media_query[]
UINT msi_get_suminfo(IStorage *stg, UINT uiUpdateCount, MSISUMMARYINFO **si) DECLSPEC_HIDDEN
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
void msi_parse_version_string(LPCWSTR verStr, PDWORD ms, PDWORD ls)
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
#define ERROR_INSTALL_PACKAGE_INVALID
static const WCHAR szProductCode[]
GLdouble GLdouble GLdouble GLdouble q
int msiobj_release(MSIOBJECTHDR *info)
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
static struct patch_offset_list * patch_offset_list_create(void)
#define memcpy(s1, s2, n)
static UINT check_transform_applicable(MSIPACKAGE *package, IStorage *transform)
static UINT msi_apply_patch_package(MSIPACKAGE *package, const WCHAR *file)
static DWORD is_uninstallable(MSIDATABASE *db)
WINE_UNICODE_INLINE WCHAR * strrchrW(const WCHAR *str, WCHAR ch)
int MSI_RecordGetInteger(MSIRECORD *, UINT) DECLSPEC_HIDDEN
UINT msi_apply_registered_patch(MSIPACKAGE *package, LPCWSTR patch_code)
static unsigned __int64 next
WINE_DEFAULT_DEBUG_CHANNEL(msi)
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
WCHAR ** msi_split_string(const WCHAR *str, WCHAR sep)
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
static struct transform_desc * parse_transform_desc(const WCHAR *str)
WCHAR * msi_dup_record_field(MSIRECORD *row, INT index) DECLSPEC_HIDDEN
static UINT patch_set_offsets(MSIDATABASE *db, MSIPATCHINFO *patch)
UINT msi_apply_patches(MSIPACKAGE *package)
static UINT apply_substorage_transform(MSIPACKAGE *package, MSIDATABASE *patch_db, LPCWSTR name)
UINT msi_set_property(MSIDATABASE *, const WCHAR *, const WCHAR *, int) DECLSPEC_HIDDEN
UINT msi_create_empty_local_file(LPWSTR path, LPCWSTR suffix) DECLSPEC_HIDDEN
UINT media_transform_disk_id
static BOOL msi_free(void *mem)
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
INT msi_suminfo_get_int32(MSISUMMARYINFO *si, UINT uiProperty) DECLSPEC_HIDDEN
static IOleDocumentView * view
GLuint GLenum GLenum transform
static UINT patch_update_filepatch_sequence(MSIDATABASE *db, const struct patch_offset_list *pos, MSIQUERY *view, MSIRECORD *rec)
static const WCHAR szProductVersion[]
static const WCHAR szPatch[]
static void patch_offset_list_free(struct patch_offset_list *pos)
UINT media_transform_offset
WINE_UNICODE_INLINE int atoiW(const WCHAR *str)
UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode, LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCWSTR szProperty, LPWSTR lpValue, DWORD *pcchValue)
UINT MSI_DatabaseApplyTransformW(MSIDATABASE *db, LPCWSTR szTransformFile, int iErrorCond) DECLSPEC_HIDDEN
static UINT patch_offset_modify_db(MSIDATABASE *db, struct patch_offset_list *pos)
LPWSTR msi_dup_property(MSIDATABASE *db, LPCWSTR prop) DECLSPEC_HIDDEN
static UINT patch_file(MSIPACKAGE *package, MSIFILEPATCH *patch)
UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY **) DECLSPEC_HIDDEN