ReactOS 0.4.15-dev-8052-gc0e3179
patch.c File Reference
#include <stdio.h>
#include <windows.h>
#include <msiquery.h>
#include <msidefs.h>
#include <msi.h>
#include <wtypes.h>
#include "wine/test.h"
Include dependency graph for patch.c:

Go to the source code of this file.

Classes

struct  msi_table
 
struct  table_data
 

Macros

#define _WIN32_MSI   300
 
#define COBJMACROS
 
#define ADD_TABLE(x)   { #x".idt", x##_dat, sizeof(x##_dat) }
 
#define GET_PROC(mod, func)
 
#define create_file(name, size)   create_file_data( name, name, size )
 

Functions

static UINT (WINAPI *pMsiApplyPatchA)(LPCSTR
 
static void init_function_pointers (void)
 
static BOOL is_process_limited (void)
 
static BOOL get_program_files_dir (char *buf, char *buf2)
 
static void create_file_data (const char *filename, const char *data, DWORD size)
 
static BOOL delete_pf (const char *rel_path, BOOL is_file)
 
static DWORD get_pf_file_size (const char *filename)
 
static void write_file (const char *filename, const char *data, DWORD data_size)
 
static void set_suminfo (const WCHAR *filename)
 
static void create_database (const char *filename, const struct msi_table *tables, UINT num_tables)
 
static void write_tables (IStorage *stg, const struct table_data *tables, UINT num_tables)
 
static void create_patch (const char *filename)
 
static void test_simple_patch (void)
 
static void test_MsiOpenDatabase (void)
 
static UINT find_entry (MSIHANDLE hdb, const char *table, const char *entry)
 
static UINT find_entryW (MSIHANDLE hdb, const WCHAR *table, const WCHAR *entry)
 
static INT get_integer (MSIHANDLE hdb, UINT field, const char *query)
 
static charget_string (MSIHANDLE hdb, UINT field, const char *query)
 
static void test_system_tables (void)
 
static void test_patch_registration (void)
 
 START_TEST (patch)
 

Variables

static LPCSTR
 
static INSTALLTYPE
 
static MSIINSTALLCONTEXT
 
static LPSTR
 
static DWORD *static DWORD
 
static DWORD *static MSIINSTALLCONTEXT LPDWORD
 
static const charmsifile = "winetest-patch.msi"
 
static const charmspfile = "winetest-patch.msp"
 
static const WCHAR msifileW [] = L"winetest-patch.msi"
 
static const WCHAR mspfileW [] = L"winetest-patch.msp"
 
static char CURR_DIR [MAX_PATH]
 
static char PROG_FILES_DIR [MAX_PATH]
 
static char COMMON_FILES_DIR [MAX_PATH]
 
static const char property_dat []
 
static const char media_dat []
 
static const char file_dat []
 
static const char directory_dat []
 
static const char component_dat []
 
static const char feature_dat []
 
static const char feature_comp_dat []
 
static const char install_exec_seq_dat []
 
static const char condition_dat []
 
static const struct msi_table tables []
 
static const WCHAR p_name0 [] = { 0x4840, 0x3b3f, 0x43f2, 0x4438, 0x45b1, 0 }
 
static const WCHAR p_name1 [] = { 0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0 }
 
static const WCHAR p_name2 [] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }
 
static const WCHAR p_name3 [] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }
 
static const WCHAR p_name4 [] = { 0x3a8c, 0x47cb, 0x45b0, 0x45ec, 0x45a8, 0x4837, 0}
 
static const WCHAR p_name5 [] = { 0x4840, 0x4596, 0x3e6c, 0x45e4, 0x42e6, 0x421c, 0x4634, 0x4468, 0x4226, 0 }
 
static const WCHAR p_name6 []
 
static const WCHAR p_name7 []
 
static const WCHAR p_name8 []
 
static const WCHAR p_data0 []
 
static const WCHAR p_data1 []
 
static const char p_data2 []
 
static const WCHAR p_data3 []
 
static const char p_data4 []
 
static const WCHAR p_data5 []
 
static const char p_data6 []
 
static const struct table_data table_patch_data []
 
static const WCHAR t1_name0 [] = { 0x4840, 0x430f, 0x422f, 0 }
 
static const WCHAR t1_name1 [] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }
 
static const WCHAR t1_name2 [] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }
 
static const WCHAR t1_name3 []
 
static const WCHAR t1_data0 []
 
static const char t1_data1 []
 
static const WCHAR t1_data2 []
 
static const char t1_data3 []
 
static const struct table_data table_transform1_data []
 
static const WCHAR t2_name0 [] = { 0x4840, 0x430f, 0x422f, 0 }
 
static const WCHAR t2_name1 [] = { 0x4840, 0x4216, 0x4327, 0x4824, 0 }
 
static const WCHAR t2_name2 [] = { 0x4840, 0x3b3f, 0x43f2, 0x4438, 0x45b1, 0 }
 
static const WCHAR t2_name3 [] = { 0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0 }
 
static const WCHAR t2_name4 [] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }
 
static const WCHAR t2_name5 [] = { 0x4840, 0x4119, 0x41b7, 0x3e6b, 0x41a4, 0x412e, 0x422a, 0 }
 
static const WCHAR t2_name6 []
 
static const WCHAR t2_name7 [] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }
 
static const WCHAR t2_name8 [] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }
 
static const WCHAR t2_name9 []
 
static const WCHAR t2_name10 []
 
static const WCHAR t2_name11 [] = { 0x4840, 0x448c, 0x44f0, 0x4472, 0x4468, 0x4837, 0 }
 
static const WCHAR t2_name12 [] = { 0x4840, 0x420f, 0x45e4, 0x4578, 0x4828, 0 }
 
static const WCHAR t2_data0 []
 
static const WCHAR t2_data1 []
 
static const WCHAR t2_data2 []
 
static const WCHAR t2_data3 []
 
static const WCHAR t2_data4 []
 
static const WCHAR t2_data5 []
 
static const WCHAR t2_data6 []
 
static const char t2_data7 []
 
static const WCHAR t2_data8 []
 
static const char t2_data9 []
 
static const WCHAR t2_data10 []
 
static const WCHAR t2_data11 []
 
static const WCHAR t2_data12 []
 
static const struct table_data table_transform2_data []
 

Macro Definition Documentation

◆ _WIN32_MSI

#define _WIN32_MSI   300

Definition at line 21 of file patch.c.

◆ ADD_TABLE

#define ADD_TABLE (   x)    { #x".idt", x##_dat, sizeof(x##_dat) }

Definition at line 139 of file patch.c.

◆ COBJMACROS

#define COBJMACROS

Definition at line 22 of file patch.c.

◆ create_file

#define create_file (   name,
  size 
)    create_file_data( name, name, size )

Definition at line 230 of file patch.c.

◆ GET_PROC

#define GET_PROC (   mod,
  func 
)
Value:
p ## func = (void *)GetProcAddress( mod, #func ); \
if (!p ## func) \
trace( "GetProcAddress(%s) failed\n", #func );
#define GetProcAddress(x, y)
Definition: compat.h:753
GLenum func
Definition: glext.h:6028
GLfloat GLfloat p
Definition: glext.h:8902
static int mod
Definition: i386-dis.c:1288

Function Documentation

◆ create_database()

static void create_database ( const char filename,
const struct msi_table tables,
UINT  num_tables 
)
static

Definition at line 316 of file patch.c.

317{
318 MSIHANDLE hdb;
319 UINT r, i;
321 int len;
322
323 len = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 );
324 if (!(filenameW = malloc( len * sizeof(WCHAR) ))) return;
326
328 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
329
330 /* import the tables into the database */
331 for (i = 0; i < num_tables; i++)
332 {
333 const struct msi_table *table = &tables[i];
334
335 write_file( table->filename, table->data, (table->size - 1) * sizeof(char) );
336
337 r = MsiDatabaseImportA( hdb, CURR_DIR, table->filename );
338 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
339
340 DeleteFileA( table->filename );
341 }
342
343 r = MsiDatabaseCommit( hdb );
344 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
345
346 MsiCloseHandle( hdb );
348 free( filenameW );
349}
#define ok(value,...)
Definition: atltest.h:57
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define CP_ACP
Definition: compat.h:109
#define MultiByteToWideChar
Definition: compat.h:110
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
UINT WINAPI MsiDatabaseImportA(MSIHANDLE handle, const char *szFolder, const char *szFilename)
Definition: database.c:853
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
Definition: database.c:298
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLenum GLsizei len
Definition: glext.h:6722
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
const char * filename
Definition: ioapi.h:137
static const WCHAR filenameW[]
Definition: amstream.c:41
static void set_suminfo(const WCHAR *filename)
Definition: patch.c:274
static void write_file(const char *filename, const char *data, DWORD data_size)
Definition: patch.c:265
static char CURR_DIR[MAX_PATH]
Definition: patch.c:45
static const struct msi_table tables[]
Definition: patch.c:141
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:963
#define MSIDBOPEN_CREATE
Definition: msiquery.h:69
unsigned int UINT
Definition: ndis.h:50
BYTE * data
unsigned long MSIHANDLE
Definition: winemsi.idl:27
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ create_file_data()

static void create_file_data ( const char filename,
const char data,
DWORD  size 
)
static

Definition at line 212 of file patch.c.

213{
214 HANDLE file;
215 DWORD written;
216
219 return;
220
221 WriteFile( file, data, strlen( data ), &written, NULL );
222 if (size)
223 {
226 }
227 CloseHandle( file );
228}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CloseHandle
Definition: compat.h:739
#define FILE_BEGIN
Definition: compat.h:761
#define SetFilePointer
Definition: compat.h:743
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
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 long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
#define CREATE_ALWAYS
Definition: disk.h:72
#define GENERIC_WRITE
Definition: nt_native.h:90
Definition: fci.c:127

◆ create_patch()

static void create_patch ( const char filename)
static

Definition at line 695 of file patch.c.

696{
697 IStorage *stg = NULL, *stg1 = NULL, *stg2 = NULL;
699 HRESULT r;
700 int len;
702
703 const CLSID CLSID_MsiPatch = {0xc1086, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46}};
704 const CLSID CLSID_MsiTransform = {0xc1082, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46}};
705
706 len = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 );
707 filenameW = malloc( len * sizeof(WCHAR) );
709
710 r = StgCreateDocfile( filenameW, mode, 0, &stg );
711 free( filenameW );
712 ok( r == S_OK, "failed to create storage %#lx\n", r );
713 if (!stg)
714 return;
715
716 r = IStorage_SetClass( stg, &CLSID_MsiPatch );
717 ok( r == S_OK, "failed to set storage type %#lx\n", r );
718
720
721 r = IStorage_CreateStorage( stg, p_name7, mode, 0, 0, &stg1 );
722 ok( r == S_OK, "failed to create substorage %#lx\n", r );
723
724 r = IStorage_SetClass( stg1, &CLSID_MsiTransform );
725 ok( r == S_OK, "failed to set storage type %#lx\n", r );
726
728 IStorage_Release( stg1 );
729
730 r = IStorage_CreateStorage( stg, p_name8, mode, 0, 0, &stg2 );
731 ok( r == S_OK, "failed to create substorage %#lx\n", r );
732
733 r = IStorage_SetClass( stg2, &CLSID_MsiTransform );
734 ok( r == S_OK, "failed to set storage type %#lx\n", r );
735
737 IStorage_Release( stg2 );
738 IStorage_Release( stg );
739}
#define ARRAY_SIZE(A)
Definition: main.h:33
HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8636
GLenum mode
Definition: glext.h:6217
#define S_OK
Definition: intsafe.h:52
static void write_tables(void)
Definition: mkdosfs.c:1629
static const struct table_data table_transform1_data[]
Definition: patch.c:518
static const struct table_data table_transform2_data[]
Definition: patch.c:657
static const struct table_data table_patch_data[]
Definition: patch.c:444
static const WCHAR p_name8[]
Definition: patch.c:366
static const WCHAR p_name7[]
Definition: patch.c:364
#define STGM_CREATE
Definition: objbase.h:926
#define STGM_DIRECT
Definition: objbase.h:914
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923

Referenced by test_MsiOpenDatabase(), test_patch_registration(), test_simple_patch(), and test_system_tables().

◆ delete_pf()

static BOOL delete_pf ( const char rel_path,
BOOL  is_file 
)
static

Definition at line 232 of file patch.c.

233{
234 char path[MAX_PATH];
235
237 strcat( path, "\\" );
238 strcat( path, rel_path );
239
240 if (is_file)
241 return DeleteFileA( path );
242 else
243 return RemoveDirectoryA( path );
244}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define MAX_PATH
Definition: compat.h:34
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
static char PROG_FILES_DIR[MAX_PATH]
Definition: patch.c:46

Referenced by test_simple_patch().

◆ find_entry()

static UINT find_entry ( MSIHANDLE  hdb,
const char table,
const char entry 
)
static

Definition at line 979 of file patch.c.

980{
981 static const char fmt[] = "SELECT * FROM `%s` WHERE `Name` = '%s'";
982 char query[0x100];
983 UINT r;
984 MSIHANDLE hview, hrec;
985
987 r = MsiDatabaseOpenViewA( hdb, query, &hview );
988 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
989
990 r = MsiViewExecute( hview, 0 );
991 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
992
993 r = MsiViewFetch( hview, &hrec );
994 MsiViewClose( hview );
995 MsiCloseHandle( hview );
996 MsiCloseHandle( hrec );
997 return r;
998}
uint32_t entry
Definition: isohybrid.c:63
#define sprintf(buf, format,...)
Definition: sprintf.c:55
UINT WINAPI MsiViewClose(MSIHANDLE hView)
Definition: msiquery.c:469
UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
Definition: msiquery.c:518
UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb, const char *szQuery, MSIHANDLE *phView)
Definition: msiquery.c:88
UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
Definition: msiquery.c:404
Definition: dsound.c:943

Referenced by test_system_tables().

◆ find_entryW()

static UINT find_entryW ( MSIHANDLE  hdb,
const WCHAR table,
const WCHAR entry 
)
static

Definition at line 1000 of file patch.c.

1001{
1002 WCHAR query[0x100];
1003 MSIHANDLE hview, hrec;
1004 UINT r;
1005
1006 wsprintfW( query, L"SELECT * FROM `%s` WHERE `Name` = '%s'", table, entry );
1007 r = MsiDatabaseOpenViewW( hdb, query, &hview );
1008 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1009
1010 r = MsiViewExecute( hview, 0 );
1011 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1012
1013 r = MsiViewFetch( hview, &hrec );
1014 MsiViewClose( hview );
1015 MsiCloseHandle( hview );
1016 MsiCloseHandle( hrec );
1017 return r;
1018}
UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb, LPCWSTR szQuery, MSIHANDLE *phView)
Definition: msiquery.c:236
#define L(x)
Definition: ntvdm.h:50
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)

Referenced by test_system_tables().

◆ get_integer()

static INT get_integer ( MSIHANDLE  hdb,
UINT  field,
const char query 
)
static

Definition at line 1020 of file patch.c.

1021{
1022 UINT r;
1023 INT ret = -1;
1024 MSIHANDLE hview, hrec;
1025
1026 r = MsiDatabaseOpenViewA( hdb, query, &hview );
1027 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1028
1029 r = MsiViewExecute( hview, 0 );
1030 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1031
1032 r = MsiViewFetch( hview, &hrec );
1033 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1034 if (r == ERROR_SUCCESS)
1035 {
1036 UINT r_tmp;
1037 ret = MsiRecordGetInteger( hrec, field );
1038 MsiCloseHandle( hrec );
1039
1040 r_tmp = MsiViewFetch( hview, &hrec );
1041 ok( r_tmp == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r);
1042 }
1043
1044 MsiViewClose( hview );
1045 MsiCloseHandle( hview );
1046 return ret;
1047}
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
int WINAPI MsiRecordGetInteger(MSIHANDLE handle, UINT iField)
Definition: record.c:237
Definition: parser.c:44
int32_t INT
Definition: typedefs.h:58
int ret

Referenced by test_system_tables().

◆ get_pf_file_size()

static DWORD get_pf_file_size ( const char filename)
static

Definition at line 246 of file patch.c.

247{
248 char path[MAX_PATH];
249 HANDLE file;
250 DWORD size;
251
253 strcat( path, "\\");
254 strcat( path, filename );
255
258 return INVALID_FILE_SIZE;
259
261 CloseHandle( file );
262 return size;
263}
#define OPEN_EXISTING
Definition: compat.h:775
#define GENERIC_READ
Definition: compat.h:135
#define FILE_SHARE_READ
Definition: compat.h:136
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
#define INVALID_FILE_SIZE
Definition: winbase.h:548

Referenced by test_simple_patch().

◆ get_program_files_dir()

static BOOL get_program_files_dir ( char buf,
char buf2 
)
static

Definition at line 187 of file patch.c.

188{
189 HKEY hkey;
190 DWORD type, size;
191
192 if (RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", &hkey ))
193 return FALSE;
194
195 size = MAX_PATH;
196 if (RegQueryValueExA( hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)buf, &size ) &&
197 RegQueryValueExA( hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size ))
198 {
199 RegCloseKey( hkey );
200 return FALSE;
201 }
202 size = MAX_PATH;
203 if (RegQueryValueExA( hkey, "CommonFilesDir", 0, &type, (LPBYTE)buf2, &size ))
204 {
205 RegCloseKey( hkey );
206 return FALSE;
207 }
208 RegCloseKey( hkey );
209 return TRUE;
210}
#define RegCloseKey(hKey)
Definition: registry.h:49
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3234
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
unsigned char * LPBYTE
Definition: typedefs.h:53
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by START_TEST().

◆ get_string()

static char * get_string ( MSIHANDLE  hdb,
UINT  field,
const char query 
)
static

Definition at line 1049 of file patch.c.

1050{
1051 UINT r;
1052 static char ret[MAX_PATH];
1053 MSIHANDLE hview, hrec;
1054
1055 ret[0] = '\0';
1056
1057 r = MsiDatabaseOpenViewA( hdb, query, &hview );
1058 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1059
1060 r = MsiViewExecute( hview, 0 );
1061 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1062
1063 r = MsiViewFetch( hview, &hrec );
1064 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1065 if (r == ERROR_SUCCESS)
1066 {
1068 r = MsiRecordGetStringA( hrec, field, ret, &size );
1069 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
1070 MsiCloseHandle( hrec );
1071
1072 r = MsiViewFetch( hview, &hrec );
1073 ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r);
1074 }
1075
1076 MsiViewClose( hview );
1077 MsiCloseHandle( hview );
1078 return ret;
1079}
UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, UINT iField, char *szValue, DWORD *pcchValue)
Definition: record.c:403

Referenced by test_system_tables().

◆ init_function_pointers()

static void init_function_pointers ( void  )
static

Definition at line 154 of file patch.c.

155{
156 HMODULE hmsi = GetModuleHandleA( "msi.dll" );
157
158#define GET_PROC( mod, func ) \
159 p ## func = (void *)GetProcAddress( mod, #func ); \
160 if (!p ## func) \
161 trace( "GetProcAddress(%s) failed\n", #func );
162
163 GET_PROC( hmsi, MsiApplyPatchA );
166
167#undef GET_PROC
168}
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
UINT WINAPI MsiGetPatchInfoExA(LPCSTR szPatchCode, LPCSTR szProductCode, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCSTR szProperty, LPSTR lpValue, DWORD *pcchValue)
Definition: msi.c:1592
UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage, INSTALLTYPE eInstallType, LPCSTR szCommandLine)
Definition: msi.c:288
UINT WINAPI MsiEnumPatchesExA(const char *szProductCode, const char *szUserSid, DWORD dwContext, DWORD dwFilter, DWORD dwIndex, char *szPatchCode, char *szTargetProductCode, MSIINSTALLCONTEXT *pdwTargetProductContext, char *szTargetUserSid, DWORD *pcchTargetUserSid)
Definition: registry.c:1618
#define GET_PROC(mod, func)

Referenced by START_TEST().

◆ is_process_limited()

static BOOL is_process_limited ( void  )
static

Definition at line 170 of file patch.c.

171{
173
175 {
176 BOOL ret;
178 DWORD size;
179
182 return (ret && type == TokenElevationTypeLimited);
183 }
184 return FALSE;
185}
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
#define GetCurrentProcess()
Definition: compat.h:759
unsigned int BOOL
Definition: ntddk_ex.h:94
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 token
Definition: glfuncs.h:210
enum _TOKEN_ELEVATION_TYPE TOKEN_ELEVATION_TYPE
@ TokenElevationTypeLimited
Definition: winnt_old.h:2488
@ TokenElevationTypeDefault
Definition: winnt_old.h:2486
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenElevationType
Definition: setypes.h:983

Referenced by test_patch_registration(), test_simple_patch(), and test_system_tables().

◆ set_suminfo()

static void set_suminfo ( const WCHAR filename)
static

Definition at line 274 of file patch.c.

275{
276 UINT r;
277 MSIHANDLE hsi, hdb;
278
280 ok( r == ERROR_SUCCESS, "failed to open database %u\n", r );
281
282 r = MsiGetSummaryInformationA( hdb, NULL, 7, &hsi );
283 ok( r == ERROR_SUCCESS, "failed to open summaryinfo %u\n", r );
284
285 r = MsiSummaryInfoSetPropertyA( hsi, 2, VT_LPSTR, 0, NULL, "Installation Database" );
286 ok( r == ERROR_SUCCESS, "failed to set summary info %u\n", r );
287
288 r = MsiSummaryInfoSetPropertyA( hsi, 3, VT_LPSTR, 0, NULL, "Installation Database" );
289 ok( r == ERROR_SUCCESS, "failed to set summary info %u\n", r );
290
291 r = MsiSummaryInfoSetPropertyA( hsi, 4, VT_LPSTR, 0, NULL, "WineHQ" );
292 ok( r == ERROR_SUCCESS, "failed to set summary info %u\n", r );
293
294 r = MsiSummaryInfoSetPropertyA( hsi, 7, VT_LPSTR, 0, NULL, ";1033" );
295 ok( r == ERROR_SUCCESS, "failed to set summary info %u\n", r );
296
297 r = MsiSummaryInfoSetPropertyA( hsi, 9, VT_LPSTR, 0, NULL, "{E528DDD6-4801-4BEC-BBB6-C5EE0FD097E9}" );
298 ok( r == ERROR_SUCCESS, "failed to set summary info %u\n", r );
299
300 r = MsiSummaryInfoSetPropertyA( hsi, 14, VT_I4, 100, NULL, NULL );
301 ok( r == ERROR_SUCCESS, "failed to set summary info %u\n", r );
302
303 r = MsiSummaryInfoSetPropertyA( hsi, 15, VT_I4, 0, NULL, NULL );
304 ok( r == ERROR_SUCCESS, "failed to set summary info %u\n", r );
305
306 r = MsiSummaryInfoPersist( hsi );
307 ok( r == ERROR_SUCCESS, "failed to persist suminfo %u\n", r );
308
309 r = MsiCloseHandle( hsi );
310 ok( r == ERROR_SUCCESS, "failed to close suminfo %u\n", r );
311
312 r = MsiCloseHandle( hdb );
313 ok( r == ERROR_SUCCESS, "failed to close database %u\n", r );
314}
@ VT_LPSTR
Definition: compat.h:2324
@ VT_I4
Definition: compat.h:2298
UINT WINAPI MsiSummaryInfoSetPropertyA(MSIHANDLE handle, UINT uiProperty, UINT uiDataType, INT iValue, FILETIME *pftValue, const char *szValue)
Definition: suminfo.c:937
UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase, const char *szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle)
Definition: suminfo.c:584
UINT WINAPI MsiSummaryInfoPersist(MSIHANDLE handle)
Definition: suminfo.c:1222
#define MSIDBOPEN_DIRECT
Definition: msiquery.h:68

Referenced by create_database().

◆ START_TEST()

START_TEST ( patch  )

Definition at line 1376 of file patch.c.

1377{
1378 DWORD len;
1379 char temp_path[MAX_PATH], prev_path[MAX_PATH];
1380
1382
1383 GetCurrentDirectoryA( MAX_PATH, prev_path );
1386
1388 len = strlen( CURR_DIR );
1389
1390 if (len && (CURR_DIR[len - 1] == '\\'))
1391 CURR_DIR[len - 1] = 0;
1392
1394
1399
1400 SetCurrentDirectoryA( prev_path );
1401}
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2206
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
static void test_system_tables(void)
Definition: patch.c:1081
static BOOL get_program_files_dir(char *buf, char *buf2)
Definition: patch.c:187
static void init_function_pointers(void)
Definition: patch.c:154
static char COMMON_FILES_DIR[MAX_PATH]
Definition: patch.c:47
static void test_simple_patch(void)
Definition: patch.c:741
static void test_MsiOpenDatabase(void)
Definition: patch.c:937
static void test_patch_registration(void)
Definition: patch.c:1273
char temp_path[MAX_PATH]
Definition: mspatcha.c:123

◆ test_MsiOpenDatabase()

static void test_MsiOpenDatabase ( void  )
static

Definition at line 937 of file patch.c.

938{
939 UINT r;
940 MSIHANDLE hdb;
941
943 ok(r == ERROR_SUCCESS, "failed to open database %u\n", r);
944
945 r = MsiDatabaseCommit( hdb );
946 ok(r == ERROR_SUCCESS, "failed to commit database %u\n", r);
947 MsiCloseHandle( hdb );
948
950 ok(r == ERROR_OPEN_FAILED, "expected ERROR_OPEN_FAILED, got %u\n", r);
952
954 ok(r == ERROR_SUCCESS , "failed to open database %u\n", r);
955
956 r = MsiDatabaseCommit( hdb );
957 ok(r == ERROR_SUCCESS, "failed to commit database %u\n", r);
958 MsiCloseHandle( hdb );
959
961 ok(r == ERROR_SUCCESS, "failed to open database %u\n", r);
962 MsiCloseHandle( hdb );
964
967
969 ok(r == ERROR_OPEN_FAILED, "failed to open database %u\n", r );
970
972 ok(r == ERROR_SUCCESS, "failed to open database %u\n", r );
973 MsiCloseHandle( hdb );
974
977}
static const WCHAR msifileW[]
Definition: patch.c:42
static void create_patch(const char *filename)
Definition: patch.c:695
static const char * mspfile
Definition: patch.c:41
static const WCHAR mspfileW[]
Definition: patch.c:43
static const char * msifile
Definition: patch.c:40
#define create_database(name, tables, num_tables)
Definition: utils.h:42
#define MSIDBOPEN_PATCHFILE
Definition: msiquery.h:79
#define MSIDBOPEN_READONLY
Definition: msiquery.h:66
#define ERROR_OPEN_FAILED
Definition: winerror.h:184

Referenced by START_TEST().

◆ test_patch_registration()

static void test_patch_registration ( void  )
static

Definition at line 1273 of file patch.c.

1274{
1275 UINT r;
1276 DWORD size;
1277 char buffer[MAX_PATH], patch_code[39];
1278
1279 if (!pMsiApplyPatchA || !pMsiGetPatchInfoExA || !pMsiEnumPatchesExA)
1280 {
1281 win_skip("required functions not available\n");
1282 return;
1283 }
1284 if (is_process_limited())
1285 {
1286 skip("process is limited\n");
1287 return;
1288 }
1289
1290 CreateDirectoryA( "msitest", NULL );
1291 create_file( "msitest\\patch.txt", 1000 );
1292
1295
1297
1298 r = MsiInstallProductA( msifile, "DISABLE_FEATURE=1" );
1299 if (r != ERROR_SUCCESS)
1300 {
1301 skip("Product installation failed with error code %d\n", r);
1302 goto cleanup;
1303 }
1304
1306 ok( r == ERROR_SUCCESS || broken( r == ERROR_PATCH_PACKAGE_INVALID ), /* version 2.0 */
1307 "expected ERROR_SUCCESS, got %u\n", r );
1308
1310 {
1311 win_skip("Windows Installer < 3.0 detected\n");
1312 goto uninstall;
1313 }
1314
1315 buffer[0] = 0;
1316 size = sizeof(buffer);
1317 r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
1318 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
1321 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1322 ok( buffer[0], "buffer empty\n" );
1323
1324 buffer[0] = 0;
1325 size = sizeof(buffer);
1326 r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
1327 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
1330 ok( r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r );
1331
1332 buffer[0] = 0;
1333 size = sizeof(buffer);
1334 r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
1335 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
1338 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1339 ok( !buffer[0], "got %s\n", buffer );
1340
1341 r = pMsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
1343 0, patch_code, NULL, NULL, NULL, NULL );
1344 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1345 ok( !strcmp( patch_code, "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}" ), "wrong patch code\n" );
1346
1347 r = pMsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
1349 0, patch_code, NULL, NULL, NULL, NULL );
1350 ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );
1351
1352 r = pMsiEnumPatchesExA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
1354 0, patch_code, NULL, NULL, NULL, NULL );
1355 ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );
1356
1357uninstall:
1358 r = MsiInstallProductA( msifile, "REMOVE=ALL" );
1359 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1360
1361 buffer[0] = 0;
1362 size = sizeof(buffer);
1363 r = pMsiGetPatchInfoExA( "{0F96CDC0-4CDF-4304-B283-7B9264889EF7}",
1364 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
1367 ok( r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r );
1368
1369cleanup:
1372 DeleteFileA( "msitest\\patch.txt" );
1373 RemoveDirectoryA( "msitest" );
1374}
#define broken(x)
Definition: _sntprintf.h:21
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define skip(...)
Definition: atltest.h:64
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
Definition: msi.c:200
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2284
GLuint buffer
Definition: glext.h:5915
#define create_file(name, size)
Definition: patch.c:230
static BOOL is_process_limited(void)
Definition: patch.c:170
@ MSIPATCHSTATE_APPLIED
Definition: msi.h:54
#define INSTALLPROPERTY_LOCALPACKAGEA
Definition: msi.h:342
@ INSTALLTYPE_DEFAULT
Definition: msi.h:189
@ MSIINSTALLCONTEXT_MACHINE
Definition: msi.h:200
@ MSIINSTALLCONTEXT_USERUNMANAGED
Definition: msi.h:199
@ MSIINSTALLCONTEXT_USERMANAGED
Definition: msi.h:198
@ INSTALLUILEVEL_NONE
Definition: msi.h:66
#define win_skip
Definition: test.h:163
#define ERROR_UNKNOWN_PRODUCT
Definition: winerror.h:963
#define ERROR_PATCH_PACKAGE_INVALID
Definition: winerror.h:994

Referenced by START_TEST().

◆ test_simple_patch()

static void test_simple_patch ( void  )
static

Definition at line 741 of file patch.c.

742{
743 UINT r;
744 DWORD size;
745 char path[MAX_PATH], install_source[MAX_PATH], buffer[32];
746 const char *query;
747 WCHAR pathW[MAX_PATH];
748 MSIHANDLE hpackage, hdb, hview, hrec;
749
750 if (!pMsiApplyPatchA)
751 {
752 win_skip("MsiApplyPatchA is not available\n");
753 return;
754 }
755 if (is_process_limited())
756 {
757 skip("process is limited\n");
758 return;
759 }
760
761 CreateDirectoryA( "msitest", NULL );
762 create_file( "msitest\\patch.txt", 1000 );
763
766
768
769 r = MsiInstallProductA( msifile, "DISABLE_FEATURE=1" );
770 if (r != ERROR_SUCCESS)
771 {
772 skip("Product installation failed with error code %u\n", r);
773 goto cleanup;
774 }
775
776 size = get_pf_file_size( "msitest\\patch.txt" );
777 ok( size == 1000, "expected 1000, got %lu\n", size );
778
779 size = sizeof(install_source);
780 r = MsiGetProductInfoA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
781 "InstallSource", install_source, &size );
782 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
783
784 strcpy( path, CURR_DIR );
785 strcat( path, "\\" );
786 strcat( path, msifile );
787
788 r = MsiOpenPackageA( path, &hpackage );
789 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
790
791 hdb = MsiGetActiveDatabase( hpackage );
792 ok( hdb, "failed to get database handle\n" );
793
794 query = "SELECT * FROM `Property` where `Property` = 'PATCHNEWPACKAGECODE'";
795 r = MsiDatabaseOpenViewA( hdb, query, &hview );
796 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
797
798 r = MsiViewExecute( hview, 0 );
799 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
800
801 r = MsiViewFetch( hview, &hrec );
802 ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );
803
804 MsiCloseHandle( hrec );
805 MsiViewClose( hview );
806 MsiCloseHandle( hview );
807
808 query = "SELECT * FROM `Property` WHERE `Property` = 'PATCHNEWSUMMARYSUBJECT' "
809 "AND `Value` = 'Installer Database'";
810 r = MsiDatabaseOpenViewA( hdb, query, &hview );
811 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
812
813 r = MsiViewExecute( hview, 0 );
814 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
815
816 r = MsiViewFetch( hview, &hrec );
817 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
818
819 MsiCloseHandle( hrec );
820 MsiViewClose( hview );
821 MsiCloseHandle( hview );
822
823 buffer[0] = 0;
824 size = sizeof(buffer);
825 r = MsiGetPropertyA( hpackage, "PATCHNEWSUMMARYSUBJECT", buffer, &size );
826 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
827 ok( !strcmp( buffer, "Installer Database" ), "expected \'Installer Database\', got \'%s\'\n", buffer );
828
829 MsiCloseHandle( hdb );
830 MsiCloseHandle( hpackage );
831
833 ok( r == ERROR_SUCCESS || broken( r == ERROR_PATCH_PACKAGE_INVALID ), /* version 2.0 */
834 "expected ERROR_SUCCESS, got %u\n", r );
835
837 {
838 win_skip("Windows Installer < 3.0 detected\n");
839 goto uninstall;
840 }
841
842 size = get_pf_file_size( "msitest\\patch.txt" );
843 ok( size == 1002, "expected 1002, got %lu\n", size );
844 size = get_pf_file_size( "msitest\\file.txt" );
845 ok( size == 1000, "expected 1000, got %lu\n", size );
846
847 /* show that MsiOpenPackage applies registered patches */
848 r = MsiOpenPackageA( path, &hpackage );
849 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
850
851 hdb = MsiGetActiveDatabase( hpackage );
852 ok( hdb, "failed to get database handle\n" );
853
854 query = "SELECT * FROM `Property` where `Property` = 'PATCHNEWPACKAGECODE'";
855 r = MsiDatabaseOpenViewA( hdb, query, &hview );
856 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
857
858 r = MsiViewExecute( hview, 0 );
859 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
860
861 r = MsiViewFetch( hview, &hrec );
862 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
863
864 MsiCloseHandle( hrec );
865 MsiViewClose( hview );
866 MsiCloseHandle( hview );
867
868 query = "SELECT * FROM `Property` WHERE `Property` = 'PATCHNEWSUMMARYSUBJECT' "
869 "AND `Value` = 'Installation Database'";
870 r = MsiDatabaseOpenViewA( hdb, query, &hview );
871 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
872
873 r = MsiViewExecute( hview, 0 );
874 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
875
876 r = MsiViewFetch( hview, &hrec );
877 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
878
879 MsiCloseHandle( hrec );
880 MsiViewClose( hview );
881 MsiCloseHandle( hview );
882
883 buffer[0] = 0;
884 size = sizeof(buffer);
885 r = MsiGetPropertyA( hpackage, "PATCHNEWSUMMARYSUBJECT", buffer, &size );
886 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
887 ok( !strcmp( buffer, "Installation Database" ), "expected \'Installation Database\', got \'%s\'\n", buffer );
888
889 MsiCloseHandle( hdb );
890 MsiCloseHandle( hpackage );
891
892 /* show that patches are not committed to the local package database */
893 size = sizeof(path);
894 r = MsiGetProductInfoA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
895 "LocalPackage", path, &size );
896 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
897
898 MultiByteToWideChar( CP_ACP, 0, path, -1, pathW, MAX_PATH );
899 r = MsiOpenDatabaseW( pathW, MSIDBOPEN_READONLY, &hdb );
900 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
901
902 r = MsiDatabaseOpenViewA( hdb, query, &hview );
903 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
904
905 r = MsiViewExecute( hview, 0 );
906 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
907
908 r = MsiViewFetch( hview, &hrec );
909 ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );
910
911 MsiCloseHandle( hrec );
912 MsiViewClose( hview );
913 MsiCloseHandle( hview );
914 MsiCloseHandle( hdb );
915
916uninstall:
917 size = sizeof(path);
918 r = MsiGetProductInfoA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}",
919 "InstallSource", path, &size );
920 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
921 ok( !strcasecmp( path, install_source ), "wrong path %s\n", path );
922
923 r = MsiInstallProductA( msifile, "REMOVE=ALL" );
924 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
925
926 ok( !delete_pf( "msitest\\patch.txt", TRUE ), "file not removed\n" );
927 ok( !delete_pf( "msitest\\file.txt", TRUE ), "file not removed\n" );
928 ok( !delete_pf( "msitest", FALSE ), "directory not removed\n" );
929
930cleanup:
933 DeleteFileA( "msitest\\patch.txt" );
934 RemoveDirectoryA( "msitest" );
935}
UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, LPSTR szBuffer, LPDWORD pcchValueBuf)
Definition: msi.c:1256
UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
Definition: package.c:1669
MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
Definition: package.c:1674
UINT WINAPI MsiGetPropertyA(MSIHANDLE hinst, const char *name, char *buf, DWORD *sz)
Definition: package.c:2313
#define strcasecmp
Definition: fake.h:9
static DWORD get_pf_file_size(const char *filename)
Definition: patch.c:246
static BOOL delete_pf(const char *rel_path, BOOL is_file)
Definition: patch.c:232

Referenced by START_TEST().

◆ test_system_tables()

static void test_system_tables ( void  )
static

Definition at line 1081 of file patch.c.

1082{
1083 static const char patchsource[] = "MSPSRC0F96CDC04CDF4304B2837B9264889EF7";
1084 UINT r;
1085 char *cr;
1086 const char *query;
1087 MSIHANDLE hproduct, hdb, hview, hrec;
1088
1089 if (!pMsiApplyPatchA)
1090 {
1091 win_skip("MsiApplyPatchA is not available\n");
1092 return;
1093 }
1094 if (is_process_limited())
1095 {
1096 skip("process is limited\n");
1097 return;
1098 }
1099
1100 CreateDirectoryA( "msitest", NULL );
1101 create_file( "msitest\\patch.txt", 1000 );
1102
1105
1107
1108 r = MsiInstallProductA( msifile, "DISABLE_FEATURE=1" );
1109 if (r != ERROR_SUCCESS)
1110 {
1111 skip("Product installation failed with error code %d\n", r);
1112 goto cleanup;
1113 }
1114
1115 r = MsiOpenProductA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}", &hproduct );
1116 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1117
1118 hdb = MsiGetActiveDatabase( hproduct );
1119 ok( hdb, "failed to get database handle\n" );
1120
1121 r = find_entry( hdb, "_Streams", "\5SummaryInformation" );
1122 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1123
1124 query = "SELECT * FROM `_Storages`";
1125 r = MsiDatabaseOpenViewA( hdb, query, &hview );
1126 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1127
1128 r = MsiViewExecute( hview, 0 );
1129 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1130
1131 r = MsiViewFetch( hview, &hrec );
1132 ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );
1133
1134 r = find_entry( hdb, "_Tables", "Directory" );
1135 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1136
1137 r = find_entry( hdb, "_Tables", "File" );
1138 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1139
1140 r = find_entry( hdb, "_Tables", "Component" );
1141 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1142
1143 r = find_entry( hdb, "_Tables", "Feature" );
1144 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1145
1146 r = find_entry( hdb, "_Tables", "FeatureComponents" );
1147 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1148
1149 r = find_entry( hdb, "_Tables", "Property" );
1150 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1151
1152 r = find_entry( hdb, "_Tables", "InstallExecuteSequence" );
1153 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1154
1155 r = find_entry( hdb, "_Tables", "Media" );
1156 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1157
1158 r = get_integer( hdb, 1, "SELECT * FROM `Media` WHERE `VolumeLabel`=\'DISK1\'");
1159 ok( r == 1, "Got %u\n", r );
1160
1161 r = find_entry( hdb, "_Tables", "_Property" );
1162 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1163
1164 MsiCloseHandle( hrec );
1165 MsiViewClose( hview );
1166 MsiCloseHandle( hview );
1167 MsiCloseHandle( hdb );
1168 MsiCloseHandle( hproduct );
1169
1171 ok( r == ERROR_SUCCESS || broken( r == ERROR_PATCH_PACKAGE_INVALID ), /* version 2.0 */
1172 "expected ERROR_SUCCESS, got %u\n", r );
1173
1175 {
1176 win_skip("Windows Installer < 3.0 detected\n");
1177 goto uninstall;
1178 }
1179
1180 r = MsiOpenProductA( "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}", &hproduct );
1181 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1182
1183 hdb = MsiGetActiveDatabase( hproduct );
1184 ok( hdb, "failed to get database handle\n" );
1185
1186 r = find_entry( hdb, "_Streams", "\5SummaryInformation" );
1187 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1188
1189 r = find_entryW( hdb, L"_Streams", L"\x3a8c\x47cb\x45b0\x45ec\x45a8\x4837" );
1190 ok( r == ERROR_NO_MORE_ITEMS, "failed to find entry %u\n", r );
1191
1192 query = "SELECT * FROM `_Storages`";
1193 r = MsiDatabaseOpenViewA( hdb, query, &hview );
1194 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1195
1196 r = MsiViewExecute( hview, 0 );
1197 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1198
1199 r = MsiViewFetch( hview, &hrec );
1200 ok( r == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %u\n", r );
1201
1202 r = find_entry( hdb, "_Tables", "Directory" );
1203 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1204
1205 r = find_entry( hdb, "_Tables", "File" );
1206 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1207
1208 r = find_entry( hdb, "_Tables", "Component" );
1209 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1210
1211 r = find_entry( hdb, "_Tables", "Feature" );
1212 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1213
1214 r = find_entry( hdb, "_Tables", "FeatureComponents" );
1215 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1216
1217 r = find_entry( hdb, "_Tables", "Property" );
1218 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1219
1220 r = find_entry( hdb, "_Tables", "InstallExecuteSequence" );
1221 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1222
1223 r = find_entry( hdb, "_Tables", "Media" );
1224 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1225
1226 r = find_entry( hdb, "_Tables", "_Property" );
1227 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1228
1229 r = find_entry( hdb, "_Tables", "MsiPatchHeaders" );
1230 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1231
1232 r = find_entry( hdb, "_Tables", "Patch" );
1233 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1234
1235 r = find_entry( hdb, "_Tables", "PatchPackage" );
1236 ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
1237
1238 cr = get_string( hdb, 6, "SELECT * FROM `Media` WHERE `Source` IS NOT NULL");
1239 todo_wine ok( !strcmp(cr, patchsource), "Expected \"%s\", got \"%s\"\n", patchsource, cr );
1240
1241 r = get_integer( hdb, 1, "SELECT * FROM `Media` WHERE `Source` IS NOT NULL");
1242 todo_wine ok( r == 100, "Got %u\n", r );
1243
1244 r = get_integer( hdb, 2, "SELECT * FROM `Media` WHERE `Source` IS NOT NULL");
1245 todo_wine ok( r == 10001, "Got %u\n", r );
1246
1247 r = get_integer( hdb, 1, "SELECT * FROM `Media` WHERE `VolumeLabel`=\'DISK1\'");
1248 ok( r == 1, "Got %u\n", r );
1249
1250 cr = get_string( hdb, 4, "SELECT * FROM `Media` WHERE `Source` IS NOT NULL");
1251 ok( !strcmp(cr, "#CAB_msitest"), "Expected \"#CAB_msitest\", got \"%s\"\n", cr );
1252
1253 r = get_integer( hdb, 8, "SELECT * FROM `File` WHERE `File` = 'patch.txt'");
1254 ok( r == 10000, "Got %u\n", r );
1255
1256 MsiCloseHandle( hrec );
1257 MsiViewClose( hview );
1258 MsiCloseHandle( hview );
1259 MsiCloseHandle( hdb );
1260 MsiCloseHandle( hproduct );
1261
1262uninstall:
1263 r = MsiInstallProductA( msifile, "REMOVE=ALL" );
1264 ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
1265
1266cleanup:
1269 DeleteFileA( "msitest\\patch.txt" );
1270 RemoveDirectoryA( "msitest" );
1271}
UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
Definition: msi.c:82
#define todo_wine
Definition: custom.c:79
static INT get_integer(MSIHANDLE hdb, UINT field, const char *query)
Definition: patch.c:1020
static char * get_string(MSIHANDLE hdb, UINT field, const char *query)
Definition: patch.c:1049
static UINT find_entry(MSIHANDLE hdb, const char *table, const char *entry)
Definition: patch.c:979
static UINT find_entryW(MSIHANDLE hdb, const WCHAR *table, const WCHAR *entry)
Definition: patch.c:1000

Referenced by START_TEST().

◆ UINT()

static UINT ( WINAPI pMsiApplyPatchA)
static

◆ write_file()

static void write_file ( const char filename,
const char data,
DWORD  data_size 
)
static

Definition at line 265 of file patch.c.

266{
267 DWORD size;
270 WriteFile( file, data, data_size, &size, NULL );
271 CloseHandle( file );
272}
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137

Referenced by create_database().

◆ write_tables()

static void write_tables ( IStorage stg,
const struct table_data tables,
UINT  num_tables 
)
static

Definition at line 673 of file patch.c.

674{
675 IStream *stm;
676 DWORD i, count;
677 HRESULT r;
678
679 for (i = 0; i < num_tables; i++)
680 {
681 r = IStorage_CreateStream( stg, tables[i].name, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
682 if (FAILED( r ))
683 {
684 ok( 0, "failed to create stream %#lx\n", r );
685 continue;
686 }
687
688 r = IStream_Write( stm, tables[i].data, tables[i].size, &count );
689 if (FAILED( r ) || count != tables[i].size)
690 ok( 0, "failed to write stream\n" );
691 IStream_Release( stm );
692 }
693}
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define FAILED(hr)
Definition: intsafe.h:51
#define STGM_WRITE
Definition: objbase.h:918
Definition: name.c:39

Variable Documentation

◆ COMMON_FILES_DIR

char COMMON_FILES_DIR[MAX_PATH]
static

Definition at line 47 of file patch.c.

Referenced by START_TEST().

◆ component_dat

const char component_dat[]
static
Initial value:
=
"Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
"s72\tS38\ts72\ti2\tS255\tS72\n"
"Component\tComponent\n"
"patch\t{4B79D87E-6D28-4FD3-92D6-CD9B26AF64F1}\tMSITESTDIR\t0\t\tpatch.txt\n"
"disable\t{BDDBA0EE-0031-4591-ADC0-33308175AC19}\tMSITESTDIR\t0\t\tdisable.txt\n"

Definition at line 85 of file patch.c.

◆ condition_dat

const char condition_dat[]
static
Initial value:
=
"Feature_\tLevel\tCondition\n"
"s38\ti2\tS255\n"
"Condition\tFeature_\tLevel\n"
"disable\t0\tDISABLE_FEATURE\n"

Definition at line 126 of file patch.c.

◆ CURR_DIR

char CURR_DIR[MAX_PATH]
static

Definition at line 45 of file patch.c.

Referenced by create_database(), START_TEST(), and test_simple_patch().

◆ directory_dat

const char directory_dat[]
static
Initial value:
=
"Directory\tDirectory_Parent\tDefaultDir\n"
"s72\tS72\tl255\n"
"Directory\tDirectory\n"
"MSITESTDIR\tProgramFilesFolder\tmsitest\n"
"ProgramFilesFolder\tTARGETDIR\t.\n"
"TARGETDIR\t\tSourceDir"

Definition at line 77 of file patch.c.

◆ DWORD

DWORD *static DWORD

Definition at line 37 of file patch.c.

◆ feature_comp_dat

const char feature_comp_dat[]
static
Initial value:
=
"Feature_\tComponent_\n"
"s38\ts72\n"
"FeatureComponents\tFeature_\tComponent_\n"
"patch\tpatch\n"
"disable\tdisable\n"

Definition at line 99 of file patch.c.

◆ feature_dat

const char feature_dat[]
static
Initial value:
=
"Feature\tFeature_Parent\tTitle\tDescription\tDisplay\tLevel\tDirectory_\tAttributes\n"
"s38\tS38\tL64\tL255\tI2\ti2\tS72\ti2\n"
"Feature\tFeature\n"
"patch\t\t\tpatch feature\t1\t1\tMSITESTDIR\t0\n"
"disable\t\t\tdisabled feature\t1\t1\tMSITESTDIR\t0\n"

Definition at line 92 of file patch.c.

◆ file_dat

const char file_dat[]
static
Initial value:
=
"File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
"s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
"File\tFile\n"
"patch.txt\tpatch\tpatch.txt\t1000\t\t\t0\t1\n"
"disable.txt\tdisable\tdisable.txt\t1000\t\t\t0\t1\n"

Definition at line 70 of file patch.c.

◆ install_exec_seq_dat

const char install_exec_seq_dat[]
static
Initial value:
=
"Action\tCondition\tSequence\n"
"s72\tS255\tI2\n"
"InstallExecuteSequence\tAction\n"
"LaunchConditions\t\t100\n"
"CostInitialize\t\t800\n"
"FileCost\t\t900\n"
"CostFinalize\t\t1000\n"
"InstallValidate\t\t1400\n"
"InstallInitialize\t\t1500\n"
"ProcessComponents\t\t1600\n"
"RemoveFiles\t\t1700\n"
"InstallFiles\t\t2000\n"
"RegisterUser\t\t3000\n"
"RegisterProduct\t\t3100\n"
"PublishFeatures\t\t5100\n"
"PublishProduct\t\t5200\n"
"UnpublishFeatures\t\t5300\n"
"InstallFinalize\t\t6000\n"

Definition at line 106 of file patch.c.

◆ INSTALLTYPE

Definition at line 34 of file patch.c.

◆ LPCSTR

DWORD *static LPCSTR

Definition at line 34 of file patch.c.

◆ LPDWORD

Definition at line 38 of file patch.c.

◆ LPSTR

Definition at line 36 of file patch.c.

◆ media_dat

const char media_dat[]
static
Initial value:
=
"DiskId\tLastSequence\tDiskPrompt\tCabinet\tVolumeLabel\tSource\n"
"i2\ti4\tL64\tS255\tS32\tS72\n"
"Media\tDiskId\n"
"1\t1\t\t\tDISK1\t\n"

Definition at line 64 of file patch.c.

◆ msifile

const char* msifile = "winetest-patch.msi"
static

◆ msifileW

const WCHAR msifileW[] = L"winetest-patch.msi"
static

Definition at line 42 of file patch.c.

Referenced by test_MsiOpenDatabase().

◆ MSIINSTALLCONTEXT

Definition at line 35 of file patch.c.

◆ mspfile

const char* mspfile = "winetest-patch.msp"
static

◆ mspfileW

const WCHAR mspfileW[] = L"winetest-patch.msp"
static

Definition at line 43 of file patch.c.

Referenced by test_MsiOpenDatabase().

◆ p_data0

const WCHAR p_data0[]
static
Initial value:
= {
0x0001, 0x0001, 0x0001, 0x0001, 0x8001, 0x8002, 0x8003, 0x8004,
0x0002, 0x0003, 0x0004, 0x0005, 0xad00, 0xbd26, 0x8d00, 0x9502
}

Definition at line 370 of file patch.c.

◆ p_data1

const WCHAR p_data1[]
static
Initial value:
= {
0x0001
}

Definition at line 374 of file patch.c.

◆ p_data2

const char p_data2[]
static
Initial value:
= {
"MsiPatchSequencePatchFamilyProductCodeSequenceAttributes1.1.19388.37230913B8D18FBB64CACA239C74C11E3FA74"
}

Definition at line 377 of file patch.c.

◆ p_data3

const WCHAR p_data3[]
static
Initial value:
= {
0, 0,
16, 5,
11, 1,
11, 1,
8, 1,
10, 1,
15, 1,
32, 1,
}

Definition at line 380 of file patch.c.

◆ p_data4

const char p_data4[]
static
Initial value:
= {
0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0xea, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87,
0x3c, 0xd4, 0xb8, 0x20, 0x00, 0x70, 0x61, 0x74, 0x63, 0x68, 0x2e,
0x74, 0x78, 0x74, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xea, 0x03, 0x00,
0x00, 0x00, 0x00, 0xcb, 0x50, 0x17, 0x7e, 0x20, 0x00, 0x66, 0x69,
0x6c, 0x65, 0x2e, 0x74, 0x78, 0x74, 0x00, 0xb0, 0xb2, 0xb2, 0x25,
0x2d, 0x00, 0xd2, 0x07, 0x43, 0x4b, 0xcb, 0x2d, 0xce, 0x2c, 0x49,
0x2d, 0x2e, 0x89, 0x29, 0x48, 0x2c, 0x49, 0xce, 0x48, 0x4d, 0xd1,
0x2b, 0xa9, 0x28, 0x51, 0x18, 0x05, 0xa3, 0x60, 0x14, 0x0c, 0x37,
0x90, 0x8b, 0x9c, 0xd3, 0x41, 0xf9, 0x9c, 0x61, 0x14, 0x8c, 0x82,
0x51, 0x30, 0xdc, 0x00, 0x00
}

Definition at line 391 of file patch.c.

◆ p_data5

const WCHAR p_data5[]
static
Initial value:
= {
0x0007, 0x0000, 0x0006, 0x8000
}

Definition at line 407 of file patch.c.

◆ p_data6

const char p_data6[]
static
Initial value:
= {
0xfe, 0xff, 0x00, 0x00, 0x05, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x85, 0x9f, 0xf2, 0xf9,
0x4f, 0x68, 0x10, 0xab, 0x91, 0x08, 0x00, 0x2b, 0x27, 0xb3, 0xd9,
0x30, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
0x00, 0x09, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x90,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00,
0x00, 0x27, 0x00, 0x00, 0x00, 0x7b, 0x30, 0x46, 0x39, 0x36, 0x43,
0x44, 0x43, 0x30, 0x2d, 0x34, 0x43, 0x44, 0x46, 0x2d, 0x34, 0x33,
0x30, 0x34, 0x2d, 0x42, 0x32, 0x38, 0x33, 0x2d, 0x37, 0x42, 0x39,
0x32, 0x36, 0x34, 0x38, 0x38, 0x39, 0x45, 0x46, 0x37, 0x7d, 0x00,
0x00, 0x1e, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x7b, 0x39,
0x31, 0x33, 0x42, 0x38, 0x44, 0x31, 0x38, 0x2d, 0x46, 0x42, 0x42,
0x36, 0x2d, 0x34, 0x43, 0x41, 0x43, 0x2d, 0x41, 0x32, 0x33, 0x39,
0x2d, 0x43, 0x37, 0x34, 0x43, 0x31, 0x31, 0x45, 0x33, 0x46, 0x41,
0x37, 0x34, 0x7d, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x00,
0x00, 0x00, 0x3a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x6f,
0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x3b, 0x3a, 0x23,
0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x6f, 0x75, 0x70, 0x67,
0x72, 0x61, 0x64, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00,
0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x50, 0x61, 0x74, 0x63, 0x68,
0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x00,
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
}

Definition at line 410 of file patch.c.

◆ p_name0

const WCHAR p_name0[] = { 0x4840, 0x3b3f, 0x43f2, 0x4438, 0x45b1, 0 }
static

Definition at line 354 of file patch.c.

◆ p_name1

const WCHAR p_name1[] = { 0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0 }
static

Definition at line 355 of file patch.c.

◆ p_name2

const WCHAR p_name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }
static

Definition at line 356 of file patch.c.

◆ p_name3

const WCHAR p_name3[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }
static

Definition at line 357 of file patch.c.

◆ p_name4

const WCHAR p_name4[] = { 0x3a8c, 0x47cb, 0x45b0, 0x45ec, 0x45a8, 0x4837, 0}
static

Definition at line 358 of file patch.c.

◆ p_name5

const WCHAR p_name5[] = { 0x4840, 0x4596, 0x3e6c, 0x45e4, 0x42e6, 0x421c, 0x4634, 0x4468, 0x4226, 0 }
static

Definition at line 359 of file patch.c.

◆ p_name6

const WCHAR p_name6[]
static
Initial value:
= { 0x0005, 0x0053, 0x0075, 0x006d, 0x006d, 0x0061, 0x0072,
0x0079, 0x0049, 0x006e, 0x0066, 0x006f, 0x0072, 0x006d,
0x0061, 0x0074, 0x0069, 0x006f, 0x006e, 0 }

Definition at line 360 of file patch.c.

◆ p_name7

const WCHAR p_name7[]
static
Initial value:
= { 0x0074, 0x0061, 0x0072, 0x0067, 0x0065, 0x0074, 0x0054, 0x006f, 0x0075, 0x0070,
0x0067, 0x0072, 0x0061, 0x0064, 0x0065, 0x0064, 0 }

Definition at line 364 of file patch.c.

Referenced by create_patch().

◆ p_name8

const WCHAR p_name8[]
static
Initial value:
= { 0x0023, 0x0074, 0x0061, 0x0072, 0x0067, 0x0065, 0x0074, 0x0054, 0x006f, 0x0075,
0x0070, 0x0067, 0x0072, 0x0061, 0x0064, 0x0065, 0x0064, 0 }

Definition at line 366 of file patch.c.

Referenced by create_patch().

◆ PROG_FILES_DIR

char PROG_FILES_DIR[MAX_PATH]
static

Definition at line 46 of file patch.c.

Referenced by delete_pf(), get_pf_file_size(), and START_TEST().

◆ property_dat

const char property_dat[]
static
Initial value:
=
"Property\tValue\n"
"s72\tl0\n"
"Property\tProperty\n"
"Manufacturer\tWineHQ\n"
"ProductCode\t{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}\n"
"UpgradeCode\t{A2E3D643-4E2C-477F-A309-F76F552D5F43}\n"
"ProductLanguage\t1033\n"
"ProductName\tmsitest\n"
"ProductVersion\t1.1.1\n"
"PATCHNEWSUMMARYSUBJECT\tInstaller Database\n"
"MSIFASTINSTALL\t1\n"

Definition at line 51 of file patch.c.

◆ t1_data0

const WCHAR t1_data0[]
static
Initial value:
= {
0x0008, 0x0001, 0x03ea, 0x8000
}

Definition at line 461 of file patch.c.

◆ t1_data1

const char t1_data1[]
static
Initial value:
= {
"patch.txt"
}

Definition at line 464 of file patch.c.

◆ t1_data2

const WCHAR t1_data2[]
static
Initial value:
= {
0, 0,
9, 1,
}

Definition at line 467 of file patch.c.

◆ t1_data3

const char t1_data3[]
static

Definition at line 472 of file patch.c.

◆ t1_name0

const WCHAR t1_name0[] = { 0x4840, 0x430f, 0x422f, 0 }
static

Definition at line 454 of file patch.c.

◆ t1_name1

const WCHAR t1_name1[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }
static

Definition at line 455 of file patch.c.

◆ t1_name2

const WCHAR t1_name2[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }
static

Definition at line 456 of file patch.c.

◆ t1_name3

const WCHAR t1_name3[]
static
Initial value:
= { 0x0005, 0x0053, 0x0075, 0x006d, 0x006d, 0x0061, 0x0072,
0x0079, 0x0049, 0x006e, 0x0066, 0x006f, 0x0072, 0x006d,
0x0061, 0x0074, 0x0069, 0x006f, 0x006e, 0 }

Definition at line 457 of file patch.c.

◆ t2_data0

const WCHAR t2_data0[]
static
Initial value:
= {
0x00c0, 0x0001, 0x9000, 0x83e8, 0x0801, 0x0002, 0x0003, 0x0002,
0x03e8, 0x8000, 0x0000, 0x0000, 0x9000, 0x83e9
}

Definition at line 543 of file patch.c.

◆ t2_data1

const WCHAR t2_data1[]
static
Initial value:
= {
0x0601, 0x8002, 0x03e9, 0x8000, 0x0000, 0x000d, 0x0000, 0x000e
}

Definition at line 547 of file patch.c.

◆ t2_data10

const WCHAR t2_data10[]
static
Initial value:
= {
0x0201, 0x0006, 0x0003
}

Definition at line 646 of file patch.c.

◆ t2_data11

const WCHAR t2_data11[]
static
Initial value:
= {
0x0601, 0x0003, 0x0004, 0x0005, 0x8000, 0x0000, 0x0002
}

Definition at line 649 of file patch.c.

◆ t2_data12

const WCHAR t2_data12[]
static
Initial value:
= {
0x0801, 0x0006, 0x0000, 0x0000, 0x0007, 0x8001, 0x8001, 0x0005,
0x8000
}

Definition at line 652 of file patch.c.

◆ t2_data2

const WCHAR t2_data2[]
static
Initial value:
= {
0x0401, 0x000f, 0x0000, 0x0010, 0xad48, 0x0401, 0x000f, 0x0000,
0x0011, 0xa502, 0x0401, 0x000f, 0x0000, 0x0012, 0x8104, 0x0401,
0x000f, 0x0000, 0x0013, 0x8502, 0x0401, 0x000f, 0x0000, 0x0014,
0x9900, 0x0401, 0x000f, 0x0000, 0x0015, 0x9d48, 0x0401, 0x0016,
0x0000, 0x0017, 0xad26, 0x0401, 0x0016, 0x0000, 0x0018, 0x8502,
0x0401, 0x001a, 0x0000, 0x001b, 0xad26, 0x0401, 0x001a, 0x0000,
0x0014, 0x8900
}

Definition at line 550 of file patch.c.

◆ t2_data3

const WCHAR t2_data3[]
static
Initial value:
= {
0x0101, 0x000f, 0x0101, 0x0016, 0x0101, 0x001a
}

Definition at line 559 of file patch.c.

◆ t2_data4

const WCHAR t2_data4[]
static
Initial value:
= {
0x0002, 0x0008, 0x0009, 0x0201, 0x000a, 0x000b
}

Definition at line 562 of file patch.c.

◆ t2_data5

const WCHAR t2_data5[]
static
Initial value:
= {
0x0201, 0x0019, 0x8002
}

Definition at line 565 of file patch.c.

◆ t2_data6

const WCHAR t2_data6[]
static
Initial value:
= {
0x0301, 0x000c, 0x0000, 0x87d1
}

Definition at line 568 of file patch.c.

◆ t2_data7

const char t2_data7[]
static
Initial value:
= {
"patch.txtfile.txtfile{327d9640-674f-4b9f-8b8a-547a0f6f8518}MSITESTDIRnewnew featurePATCHNEWSUMMARYSUBJECT"
"Installation DatabasePATCHNEWPACKAGECODE{42A14A82-12F8-4E6D-970E-1B4EE7BE28B0}PatchFiles#CAB_msitestprop"
"PatchFile_SequencePatchSizeAttributesHeaderStreamRef_PatchPackagePatchIdMedia_"
"{0F96CDC0-4CDF-4304-B283-7B9264889EF7}MsiPatchHeadersStreamRef"
}

Definition at line 571 of file patch.c.

◆ t2_data8

const WCHAR t2_data8[]
static

Definition at line 577 of file patch.c.

◆ t2_data9

const char t2_data9[]
static

Definition at line 608 of file patch.c.

◆ t2_name0

const WCHAR t2_name0[] = { 0x4840, 0x430f, 0x422f, 0 }
static

Definition at line 525 of file patch.c.

◆ t2_name1

const WCHAR t2_name1[] = { 0x4840, 0x4216, 0x4327, 0x4824, 0 }
static

Definition at line 526 of file patch.c.

◆ t2_name10

const WCHAR t2_name10[]
static
Initial value:
= { 0x4840, 0x420f, 0x45e4, 0x4578, 0x3b28, 0x4432, 0x44b3,
0x4231, 0x45f1, 0x4836, 0 }

Definition at line 538 of file patch.c.

◆ t2_name11

const WCHAR t2_name11[] = { 0x4840, 0x448c, 0x44f0, 0x4472, 0x4468, 0x4837, 0 }
static

Definition at line 540 of file patch.c.

◆ t2_name12

const WCHAR t2_name12[] = { 0x4840, 0x420f, 0x45e4, 0x4578, 0x4828, 0 }
static

Definition at line 541 of file patch.c.

◆ t2_name2

const WCHAR t2_name2[] = { 0x4840, 0x3b3f, 0x43f2, 0x4438, 0x45b1, 0 }
static

Definition at line 527 of file patch.c.

◆ t2_name3

const WCHAR t2_name3[] = { 0x4840, 0x3f7f, 0x4164, 0x422f, 0x4836, 0 }
static

Definition at line 528 of file patch.c.

◆ t2_name4

const WCHAR t2_name4[] = { 0x4840, 0x4559, 0x44f2, 0x4568, 0x4737, 0 }
static

Definition at line 529 of file patch.c.

◆ t2_name5

const WCHAR t2_name5[] = { 0x4840, 0x4119, 0x41b7, 0x3e6b, 0x41a4, 0x412e, 0x422a, 0 }
static

Definition at line 530 of file patch.c.

◆ t2_name6

const WCHAR t2_name6[]
static
Initial value:
= { 0x4840, 0x4452, 0x45f6, 0x43e4, 0x3baf, 0x423b, 0x4626,
0x4237, 0x421c, 0x4634, 0x4468, 0x4226, 0 }

Definition at line 531 of file patch.c.

◆ t2_name7

const WCHAR t2_name7[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3b6a, 0x45e4, 0x4824, 0 }
static

Definition at line 533 of file patch.c.

◆ t2_name8

const WCHAR t2_name8[] = { 0x4840, 0x3f3f, 0x4577, 0x446c, 0x3e6a, 0x44b2, 0x482f, 0 }
static

Definition at line 534 of file patch.c.

◆ t2_name9

const WCHAR t2_name9[]
static
Initial value:
= { 0x0005, 0x0053, 0x0075, 0x006d, 0x006d, 0x0061, 0x0072,
0x0079, 0x0049, 0x006e, 0x0066, 0x006f, 0x0072, 0x006d,
0x0061, 0x0074, 0x0069, 0x006f, 0x006e, 0 }

Definition at line 535 of file patch.c.

◆ table_patch_data

const struct table_data table_patch_data[]
static
Initial value:
= {
{ p_name0, p_data0, sizeof p_data0 },
{ p_name1, p_data1, sizeof p_data1 },
{ p_name2, p_data2, sizeof p_data2 - 1 },
{ p_name3, p_data3, sizeof p_data3 },
{ p_name4, p_data4, sizeof p_data4 },
{ p_name5, p_data5, sizeof p_data5 },
{ p_name6, p_data6, sizeof p_data6 }
}
static const WCHAR p_name6[]
Definition: patch.c:360
static const char p_data6[]
Definition: patch.c:410
static const WCHAR p_data3[]
Definition: patch.c:380
static const char p_data4[]
Definition: patch.c:391
static const WCHAR p_data0[]
Definition: patch.c:370
static const WCHAR p_data1[]
Definition: patch.c:374
static const WCHAR p_name4[]
Definition: patch.c:358
static const char p_data2[]
Definition: patch.c:377
static const WCHAR p_name5[]
Definition: patch.c:359
static const WCHAR p_data5[]
Definition: patch.c:407
static const WCHAR p_name1[]
Definition: patch.c:355
static const WCHAR p_name0[]
Definition: patch.c:354
static const WCHAR p_name2[]
Definition: patch.c:356
static const WCHAR p_name3[]
Definition: patch.c:357

Definition at line 444 of file patch.c.

Referenced by create_patch().

◆ table_transform1_data

const struct table_data table_transform1_data[]
static
Initial value:
= {
{ t1_name0, t1_data0, sizeof t1_data0 },
{ t1_name1, t1_data1, sizeof t1_data1 - 1 },
{ t1_name2, t1_data2, sizeof t1_data2 },
{ t1_name3, t1_data3, sizeof t1_data3 }
}
static const WCHAR t1_data0[]
Definition: patch.c:461
static const WCHAR t1_name2[]
Definition: patch.c:456
static const WCHAR t1_name3[]
Definition: patch.c:457
static const char t1_data1[]
Definition: patch.c:464
static const WCHAR t1_name1[]
Definition: patch.c:455
static const WCHAR t1_data2[]
Definition: patch.c:467
static const char t1_data3[]
Definition: patch.c:472
static const WCHAR t1_name0[]
Definition: patch.c:454

Definition at line 518 of file patch.c.

Referenced by create_patch().

◆ table_transform2_data

const struct table_data table_transform2_data[]
static
Initial value:
= {
{ t2_name0, t2_data0, sizeof t2_data0 },
{ t2_name1, t2_data1, sizeof t2_data1 },
{ t2_name2, t2_data2, sizeof t2_data2 },
{ t2_name3, t2_data3, sizeof t2_data3 },
{ t2_name4, t2_data4, sizeof t2_data4 },
{ t2_name5, t2_data5, sizeof t2_data5 },
{ t2_name6, t2_data6, sizeof t2_data6 },
{ t2_name7, t2_data7, sizeof t2_data7 - 1 },
{ t2_name8, t2_data8, sizeof t2_data8 },
{ t2_name9, t2_data9, sizeof t2_data9 },
}
static const WCHAR t2_name12[]
Definition: patch.c:541
static const WCHAR t2_data10[]
Definition: patch.c:646
static const WCHAR t2_data4[]
Definition: patch.c:562
static const WCHAR t2_data8[]
Definition: patch.c:577
static const WCHAR t2_data2[]
Definition: patch.c:550
static const WCHAR t2_data11[]
Definition: patch.c:649
static const WCHAR t2_name11[]
Definition: patch.c:540
static const char t2_data7[]
Definition: patch.c:571
static const WCHAR t2_name7[]
Definition: patch.c:533
static const WCHAR t2_name3[]
Definition: patch.c:528
static const WCHAR t2_name1[]
Definition: patch.c:526
static const WCHAR t2_data3[]
Definition: patch.c:559
static const WCHAR t2_name9[]
Definition: patch.c:535
static const WCHAR t2_data6[]
Definition: patch.c:568
static const WCHAR t2_name10[]
Definition: patch.c:538
static const WCHAR t2_data5[]
Definition: patch.c:565
static const WCHAR t2_name4[]
Definition: patch.c:529
static const WCHAR t2_name8[]
Definition: patch.c:534
static const WCHAR t2_name6[]
Definition: patch.c:531
static const WCHAR t2_name2[]
Definition: patch.c:527
static const WCHAR t2_name5[]
Definition: patch.c:530
static const WCHAR t2_name0[]
Definition: patch.c:525
static const WCHAR t2_data1[]
Definition: patch.c:547
static const char t2_data9[]
Definition: patch.c:608
static const WCHAR t2_data0[]
Definition: patch.c:543
static const WCHAR t2_data12[]
Definition: patch.c:652

Definition at line 657 of file patch.c.

Referenced by create_patch().

◆ tables

const struct msi_table tables[]
static
Initial value:
=
{
ADD_TABLE( component ),
ADD_TABLE( feature_comp ),
ADD_TABLE( install_exec_seq ),
}
__u8 media
Definition: mkdosfs.c:9
#define ADD_TABLE(x)
Definition: patch.c:139
INTERNETFEATURELIST feature
Definition: misc.c:1719

Definition at line 141 of file patch.c.

Referenced by create_database(), test_MsiOpenDatabase(), test_patch_registration(), test_simple_patch(), test_system_tables(), and write_tables().