ReactOS 0.4.15-dev-7677-g8209aa5
msi.c File Reference
#include <stdio.h>
#include <windows.h>
#include <msi.h>
#include <msiquery.h>
#include <msidefs.h>
#include <sddl.h>
#include <fci.h>
#include <shellapi.h>
#include <objidl.h>
#include "wine/test.h"
#include "utils.h"
Include dependency graph for msi.c:

Go to the source code of this file.

Macros

#define _WIN32_MSI   300
 
#define COBJMACROS
 
#define GUID_SIZE   (39)
 
#define SQUASHED_GUID_SIZE   (33)
 
#define GET_PROC(dll, func)
 
#define MEDIA_SIZE   0x7FFFFFFF
 
#define FOLDER_THRESHOLD   900000
 
#define HASHSIZE   sizeof(MSIFILEHASHINFO)
 
#define INIT_USERINFO()
 

Functions

static LONG (WINAPI *pRegDeleteKeyExA)(HKEY
 
static BOOL (WINAPI *pIsWow64Process)(HANDLE
 
static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)(LPCSTR
 
static UINT (WINAPI *pMsiGetFileHashA)(LPCSTR
 
static void init_functionpointers (void)
 
static BOOL add_cabinet_storage (LPCSTR db, LPCSTR cabinet)
 
static UINT set_summary_info (MSIHANDLE hdb, LPSTR prodcode)
 
static MSIHANDLE create_package_db (LPSTR prodcode)
 
static void test_usefeature (void)
 
static LONG delete_key (HKEY key, LPCSTR subkey, REGSAM access)
 
static void test_null (void)
 
static void test_getcomponentpath (void)
 
static void create_test_files (void)
 
static void delete_test_files (void)
 
static void test_MsiGetFileHash (void)
 
static BOOL squash_guid (LPCWSTR in, LPWSTR out)
 
static void create_test_guid (LPSTR prodcode, LPSTR squashed)
 
static charget_user_sid (void)
 
static void test_MsiQueryProductState (void)
 
static void encode_base85_guid (GUID *guid, LPWSTR str)
 
static void compose_base85_guid (LPSTR component, LPSTR comp_base85, LPSTR squashed)
 
static void test_MsiQueryFeatureState (void)
 
static void test_MsiQueryComponentState (void)
 
static void test_MsiGetComponentPath (void)
 
static void test_MsiGetComponentPathEx (void)
 
static void test_MsiProvideComponent (void)
 
static void test_MsiProvideQualifiedComponentEx (void)
 
static void test_MsiGetProductCode (void)
 
static void test_MsiEnumClients (void)
 
static void get_version_info (LPSTR path, LPSTR *vercheck, LPDWORD verchecksz, LPSTR *langcheck, LPDWORD langchecksz)
 
static void test_MsiGetFileVersion (void)
 
static void test_MsiGetProductInfo (void)
 
static void test_MsiGetProductInfoEx (void)
 
static void test_MsiGetUserInfo (void)
 
static void test_MsiOpenProduct (void)
 
static void test_MsiEnumPatchesEx_usermanaged (LPCSTR usersid, LPCSTR expectedsid)
 
static void test_MsiEnumPatchesEx_userunmanaged (LPCSTR usersid, LPCSTR expectedsid)
 
static void test_MsiEnumPatchesEx_machine (void)
 
static void test_MsiEnumPatchesEx (void)
 
static void test_MsiEnumPatches (void)
 
static void test_MsiGetPatchInfoEx (void)
 
static void test_MsiGetPatchInfo (void)
 
static void test_MsiEnumProducts (void)
 
static void test_MsiGetFileSignatureInformation (void)
 
static void test_MsiEnumProductsEx (void)
 
static void test_MsiEnumComponents (void)
 
static void test_MsiEnumComponentsEx (void)
 
static void test_MsiConfigureProductEx (void)
 
static void test_MsiSetFeatureAttributes (void)
 
static void test_MsiGetFeatureInfo (void)
 
static INT CALLBACK handler_a (LPVOID context, UINT type, LPCSTR msg)
 
static INT CALLBACK handler_w (LPVOID context, UINT type, LPCWSTR msg)
 
static INT CALLBACK handler_record (LPVOID context, UINT type, MSIHANDLE record)
 
static void test_MsiSetInternalUI (void)
 
static void test_MsiSetExternalUI (void)
 
static void test_lastusedsource (void)
 
static void test_setpropertyfolder (void)
 
static void test_sourcedir_props (void)
 
static void test_concurrentinstall (void)
 
static void test_command_line_parsing (void)
 
 START_TEST (msi)
 

Variables

static BOOL is_wow64
 
static const char msifile [] = "winetest.msi"
 
static const WCHAR msifileW [] = L"winetest.msi"
 
static LPCSTR
 
static REGSAM
 
static DWORD
 
static PBOOL
 
static LPSTR
 
static DWORD *static MSIINSTALLCONTEXT
 
static DWORD *static LPDWORD
 
static LPCWSTR
 
static LPWSTR
 
static PMSIFILEHASHINFO
 
static DWORD *static CHAR [39]
 
static LPVOID
 
static PINSTALLUI_HANDLER_RECORD
 
static const char directory_dat []
 
static const char component_dat []
 
static const char feature_dat []
 
static const char feature_comp_dat []
 
static const char file_dat []
 
static const char install_exec_seq_dat []
 
static const char media_dat []
 
static const char property_dat []
 
static const char ci2_property_dat []
 
static const char mcp_component_dat []
 
static const char mcp_feature_dat []
 
static const char mcp_feature_comp_dat []
 
static const char mcp_file_dat []
 
static const char lus_component_dat []
 
static const char lus_feature_dat []
 
static const char lus_file_dat []
 
static const char lus_feature_comp_dat []
 
static const char lus_install_exec_seq_dat []
 
static const char lus0_media_dat []
 
static const char lus1_media_dat []
 
static const char lus2_media_dat []
 
static const char spf_custom_action_dat []
 
static const char spf_install_exec_seq_dat []
 
static const char spf_install_ui_seq_dat []
 
static const char spf_directory_dat []
 
static const char spf_component_dat []
 
static const char spf2_install_exec_seq_dat []
 
static const char spf2_custom_action_dat []
 
static const char shortcut_dat []
 
static const char sd_file_dat []
 
static const char sd_feature_dat []
 
static const char sd_feature_comp_dat []
 
static const char sd_component_dat []
 
static const char sd_install_ui_seq_dat []
 
static const char sd_install_exec_seq_dat []
 
static const char sd_custom_action_dat []
 
static const char ci_install_exec_seq_dat []
 
static const char ci_custom_action_dat []
 
static const char ci_component_dat []
 
static const char ci2_component_dat []
 
static const char ci2_feature_comp_dat []
 
static const char ci2_file_dat []
 
static const char cl_custom_action_dat []
 
static const char cl_install_exec_seq_dat []
 
static const msi_table tables []
 
static const msi_table mcp_tables []
 
static const msi_table lus0_tables []
 
static const msi_table lus1_tables []
 
static const msi_table lus2_tables []
 
static const msi_table spf_tables []
 
static const msi_table spf2_tables []
 
static const msi_table sd_tables []
 
static const msi_table ci_tables []
 
static const msi_table ci2_tables []
 
static const msi_table cl_tables []
 
struct {
   LPCSTR   data
 
   DWORD   size
 
   MSIFILEHASHINFO   hash
 
hash_data []
 
static const char table_enc85 []
 

Macro Definition Documentation

◆ _WIN32_MSI

#define _WIN32_MSI   300

Definition at line 21 of file msi.c.

◆ COBJMACROS

#define COBJMACROS

Definition at line 22 of file msi.c.

◆ FOLDER_THRESHOLD

#define FOLDER_THRESHOLD   900000

Definition at line 119 of file msi.c.

◆ GET_PROC

#define GET_PROC (   dll,
  func 
)
Value:
p ## func = (void *)GetProcAddress(dll, #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 HMODULE dll
Definition: str.c:188

◆ GUID_SIZE

#define GUID_SIZE   (39)

Definition at line 37 of file msi.c.

◆ HASHSIZE

#define HASHSIZE   sizeof(MSIFILEHASHINFO)

Definition at line 1098 of file msi.c.

◆ INIT_USERINFO

#define INIT_USERINFO ( )
Value:
lstrcpyA(user, "apple"); \
lstrcpyA(org, "orange"); \
lstrcpyA(serial, "banana"); \
usersz = orgsz = serialsz = MAX_PATH;
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define MAX_PATH
Definition: compat.h:34
uint32_t serial
Definition: fsck.fat.h:29
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
static char org[]
Definition: encode.c:7456

Definition at line 8434 of file msi.c.

◆ MEDIA_SIZE

#define MEDIA_SIZE   0x7FFFFFFF

Definition at line 118 of file msi.c.

◆ SQUASHED_GUID_SIZE

#define SQUASHED_GUID_SIZE   (33)

Definition at line 38 of file msi.c.

Function Documentation

◆ add_cabinet_storage()

static BOOL add_cabinet_storage ( LPCSTR  db,
LPCSTR  cabinet 
)
static

Definition at line 121 of file msi.c.

122{
123 WCHAR dbW[MAX_PATH], cabinetW[MAX_PATH];
124 IStorage *stg;
125 IStream *stm;
126 HRESULT hr;
128
129 MultiByteToWideChar(CP_ACP, 0, db, -1, dbW, MAX_PATH);
131 if (FAILED(hr))
132 return FALSE;
133
134 MultiByteToWideChar(CP_ACP, 0, cabinet, -1, cabinetW, MAX_PATH);
135 hr = IStorage_CreateStream(stg, cabinetW, STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
136 if (FAILED(hr))
137 {
138 IStorage_Release(stg);
139 return FALSE;
140 }
141
144 {
145 DWORD count;
146 char buffer[1024];
147 if (ReadFile(handle, buffer, sizeof(buffer), &count, NULL))
148 IStream_Write(stm, buffer, count, &count);
150 }
151
152 IStream_Release(stm);
153 IStorage_Release(stg);
154
155 return TRUE;
156}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define CreateFileW
Definition: compat.h:741
#define MultiByteToWideChar
Definition: compat.h:110
HRESULT WINAPI StgOpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8755
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
#define FAILED(hr)
Definition: intsafe.h:51
#define STGM_DIRECT
Definition: objbase.h:914
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923
#define STGM_WRITE
Definition: objbase.h:918
HRESULT hr
Definition: shlfolder.c:183
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by test_lastusedsource().

◆ BOOL()

static BOOL ( WINAPI pIsWow64Process)
static

◆ compose_base85_guid()

static void compose_base85_guid ( LPSTR  component,
LPSTR  comp_base85,
LPSTR  squashed 
)
static

Definition at line 1601 of file msi.c.

1602{
1603 WCHAR guidW[MAX_PATH];
1604 WCHAR base85W[MAX_PATH];
1605 WCHAR squashedW[MAX_PATH];
1606 GUID guid;
1607 HRESULT hr;
1608 int size;
1609
1610 hr = CoCreateGuid(&guid);
1611 ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
1612
1613 size = StringFromGUID2(&guid, guidW, MAX_PATH);
1614 ok(size == 39, "Expected 39, got %d\n", size);
1615
1616 WideCharToMultiByte(CP_ACP, 0, guidW, size, component, MAX_PATH, NULL, NULL);
1617 encode_base85_guid(&guid, base85W);
1618 WideCharToMultiByte(CP_ACP, 0, base85W, -1, comp_base85, MAX_PATH, NULL, NULL);
1619 squash_guid(guidW, squashedW);
1620 WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
1621}
#define ok(value,...)
Definition: atltest.h:57
#define WideCharToMultiByte
Definition: compat.h:111
HRESULT WINAPI CoCreateGuid(GUID *pguid)
Definition: compobj.c:2206
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
GLsizeiptr size
Definition: glext.h:5919
#define S_OK
Definition: intsafe.h:52
const GUID * guid
static void encode_base85_guid(GUID *guid, LPWSTR str)
Definition: msi.c:1580
BOOL squash_guid(LPCWSTR in, LPWSTR out) DECLSPEC_HIDDEN
Definition: registry.c:74

Referenced by test_MsiEnumClients(), test_MsiGetComponentPath(), test_MsiGetComponentPathEx(), test_MsiGetProductCode(), test_MsiProvideQualifiedComponentEx(), test_MsiQueryComponentState(), and test_MsiQueryFeatureState().

◆ create_package_db()

static MSIHANDLE create_package_db ( LPSTR  prodcode)
static

Definition at line 827 of file msi.c.

828{
829 MSIHANDLE hdb = 0;
830 CHAR query[MAX_PATH + 72];
831 UINT res;
832
834
835 /* create an empty database */
837 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
838 if (res != ERROR_SUCCESS)
839 return hdb;
840
841 res = MsiDatabaseCommit(hdb);
842 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
843
844 set_summary_info(hdb, prodcode);
845
846 res = run_query(hdb, 0,
847 "CREATE TABLE `Directory` ( "
848 "`Directory` CHAR(255) NOT NULL, "
849 "`Directory_Parent` CHAR(255), "
850 "`DefaultDir` CHAR(255) NOT NULL "
851 "PRIMARY KEY `Directory`)");
852 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
853
854 res = run_query(hdb, 0,
855 "CREATE TABLE `Property` ( "
856 "`Property` CHAR(72) NOT NULL, "
857 "`Value` CHAR(255) "
858 "PRIMARY KEY `Property`)");
859 ok(res == ERROR_SUCCESS , "Failed to create directory table\n");
860
861 sprintf(query, "INSERT INTO `Property` "
862 "(`Property`, `Value`) "
863 "VALUES( 'ProductCode', '%s' )", prodcode);
864 res = run_query(hdb, 0, query);
865 ok(res == ERROR_SUCCESS , "Failed\n");
866
867 res = MsiDatabaseCommit(hdb);
868 ok(res == ERROR_SUCCESS, "Failed to commit database\n");
869
870 return hdb;
871}
static int run_query(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL recurse)
Definition: query.c:311
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
Definition: database.c:298
GLuint res
Definition: glext.h:9613
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const WCHAR msifileW[]
Definition: msi.c:42
static const char msifile[]
Definition: msi.c:41
static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
Definition: msi.c:783
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:963
#define MSIDBOPEN_CREATE
Definition: msiquery.h:69
unsigned int UINT
Definition: ndis.h:50
unsigned long MSIHANDLE
Definition: winemsi.idl:27
char CHAR
Definition: xmlstorage.h:175

◆ create_test_files()

static void create_test_files ( void  )
static

Definition at line 1064 of file msi.c.

1065{
1066 CreateDirectoryA("msitest", NULL);
1067 create_file("msitest\\one.txt", 100);
1068 CreateDirectoryA("msitest\\first", NULL);
1069 create_file("msitest\\first\\two.txt", 100);
1070 CreateDirectoryA("msitest\\second", NULL);
1071 create_file("msitest\\second\\three.txt", 100);
1072
1073 create_file("four.txt", 100);
1074 create_file("five.txt", 100);
1075 create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
1076
1077 create_file("msitest\\filename", 100);
1078 create_file("msitest\\service.exe", 100);
1079
1080 DeleteFileA("four.txt");
1081 DeleteFileA("five.txt");
1082}
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
static void create_cab_file(void)
Definition: files.c:356
#define create_file(name, size)
Definition: asmcache.c:813
#define MEDIA_SIZE
Definition: msi.c:118

Referenced by test_command_line_parsing(), test_MsiProvideComponent(), and test_sourcedir_props().

◆ create_test_guid()

static void create_test_guid ( LPSTR  prodcode,
LPSTR  squashed 
)
static

◆ delete_key()

static LONG delete_key ( HKEY  key,
LPCSTR  subkey,
REGSAM  access 
)
static

Definition at line 912 of file msi.c.

913{
914 if (pRegDeleteKeyExA)
915 return pRegDeleteKeyExA( key, subkey, access, 0 );
916 return RegDeleteKeyA( key, subkey );
917}
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
Definition: copy.c:22

◆ delete_test_files()

static void delete_test_files ( void  )
static

Definition at line 1084 of file msi.c.

1085{
1086 DeleteFileA("msitest.msi");
1087 DeleteFileA("msitest.cab");
1088 DeleteFileA("msitest\\second\\three.txt");
1089 DeleteFileA("msitest\\first\\two.txt");
1090 DeleteFileA("msitest\\one.txt");
1091 DeleteFileA("msitest\\service.exe");
1092 DeleteFileA("msitest\\filename");
1093 RemoveDirectoryA("msitest\\second");
1094 RemoveDirectoryA("msitest\\first");
1095 RemoveDirectoryA("msitest");
1096}
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714

Referenced by test_command_line_parsing(), test_MsiProvideComponent(), and test_sourcedir_props().

◆ encode_base85_guid()

static void encode_base85_guid ( GUID guid,
LPWSTR  str 
)
static

Definition at line 1580 of file msi.c.

1581{
1582 unsigned int x, *p, i;
1583
1584 p = (unsigned int*) guid;
1585 for( i=0; i<4; i++ )
1586 {
1587 x = p[i];
1588 *str++ = table_enc85[x%85];
1589 x = x/85;
1590 *str++ = table_enc85[x%85];
1591 x = x/85;
1592 *str++ = table_enc85[x%85];
1593 x = x/85;
1594 *str++ = table_enc85[x%85];
1595 x = x/85;
1596 *str++ = table_enc85[x%85];
1597 }
1598 *str = 0;
1599}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
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
static const char table_enc85[]
Definition: msi.c:1571
const WCHAR * str

Referenced by compose_base85_guid().

◆ get_user_sid()

static char * get_user_sid ( void  )
static

Definition at line 1247 of file msi.c.

1248{
1249 HANDLE token;
1250 DWORD size = 0;
1252 char *usersid = NULL;
1253
1256
1257 user = malloc(size);
1259 ConvertSidToStringSidA(user->User.Sid, &usersid);
1260 free(user);
1261
1263 return usersid;
1264}
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
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
BOOL WINAPI ConvertSidToStringSidA(PSID Sid, LPSTR *StringSid)
Definition: security.c:3637
#define GetCurrentProcess()
Definition: compat.h:759
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
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenUser
Definition: setypes.h:966

Referenced by test_MsiEnumClients(), test_MsiEnumComponents(), test_MsiEnumComponentsEx(), test_MsiEnumPatches(), test_MsiEnumPatchesEx(), test_MsiEnumProducts(), test_MsiEnumProductsEx(), test_MsiGetComponentPath(), test_MsiGetComponentPathEx(), test_MsiGetPatchInfoEx(), test_MsiGetProductCode(), test_MsiGetProductInfoEx(), test_MsiGetUserInfo(), test_MsiOpenProduct(), test_MsiQueryComponentState(), test_MsiQueryFeatureState(), and test_MsiQueryProductState().

◆ get_version_info()

static void get_version_info ( LPSTR  path,
LPSTR vercheck,
LPDWORD  verchecksz,
LPSTR langcheck,
LPDWORD  langchecksz 
)
static

Definition at line 4079 of file msi.c.

4081{
4082 LPSTR version;
4083 VS_FIXEDFILEINFO *ffi;
4085 UINT len;
4086 USHORT *lang;
4087
4088 version = malloc(size);
4090
4091 VerQueryValueA(version, "\\", (LPVOID *)&ffi, &len);
4092 *vercheck = malloc(MAX_PATH);
4093 sprintf(*vercheck, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
4095 LOWORD(ffi->dwFileVersionLS));
4096 *verchecksz = lstrlenA(*vercheck);
4097
4098 VerQueryValueA(version, "\\VarFileInfo\\Translation", (void **)&lang, &len);
4099 *langcheck = malloc(MAX_PATH);
4100 sprintf(*langcheck, "%d", *lang);
4101 *langchecksz = lstrlenA(*langcheck);
4102
4103 free(version);
4104}
static const WCHAR version[]
Definition: asmname.c:66
DWORD WINAPI GetFileVersionInfoSizeA(LPCSTR filename, LPDWORD handle)
Definition: version.c:619
BOOL WINAPI VerQueryValueA(LPCVOID pBlock, LPCSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:993
BOOL WINAPI GetFileVersionInfoA(LPCSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:853
GLenum GLsizei len
Definition: glext.h:6722
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define LOWORD(l)
Definition: pedump.c:82
unsigned short USHORT
Definition: pedump.c:61
DWORD dwFileVersionLS
Definition: compat.h:903
DWORD dwFileVersionMS
Definition: compat.h:902
#define HIWORD(l)
Definition: typedefs.h:247
static const WCHAR lang[]
Definition: wbemdisp.c:287
char * LPSTR
Definition: xmlstorage.h:182

Referenced by test_MsiGetFileVersion().

◆ handler_a()

static INT CALLBACK handler_a ( LPVOID  context,
UINT  type,
LPCSTR  msg 
)
static

Definition at line 14037 of file msi.c.

14038{
14039 return IDOK;
14040}
#define IDOK
Definition: winuser.h:829

Referenced by test_MsiSetExternalUI().

◆ handler_record()

static INT CALLBACK handler_record ( LPVOID  context,
UINT  type,
MSIHANDLE  record 
)
static

Definition at line 14047 of file msi.c.

14048{
14049 return IDOK;
14050}

Referenced by test_MsiSetExternalUI().

◆ handler_w()

static INT CALLBACK handler_w ( LPVOID  context,
UINT  type,
LPCWSTR  msg 
)
static

Definition at line 14042 of file msi.c.

14043{
14044 return IDOK;
14045}

Referenced by test_MsiSetExternalUI().

◆ init_functionpointers()

static void init_functionpointers ( void  )
static

Definition at line 81 of file msi.c.

82{
83 HMODULE hmsi = GetModuleHandleA("msi.dll");
84 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
85 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
86
87#define GET_PROC(dll, func) \
88 p ## func = (void *)GetProcAddress(dll, #func); \
89 if(!p ## func) \
90 trace("GetProcAddress(%s) failed\n", #func);
91
108
109 GET_PROC(hadvapi32, RegDeleteKeyExA)
111
112#undef GET_PROC
113}
LONG WINAPI RegDeleteKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ REGSAM samDesired, _In_ DWORD Reserved)
Definition: reg.c:1254
#define IsWow64Process
Definition: compat.h:760
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
UINT WINAPI MsiSetExternalUIRecord(INSTALLUI_HANDLER_RECORD handler, DWORD filter, void *context, INSTALLUI_HANDLER_RECORD *prev)
Definition: msi.c:4155
UINT WINAPI MsiGetPatchInfoExA(LPCSTR szPatchCode, LPCSTR szProductCode, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCSTR szProperty, LPSTR lpValue, DWORD *pcchValue)
Definition: msi.c:1592
UINT WINAPI MsiGetFileHashA(const char *szFilePath, DWORD dwOptions, MSIFILEHASHINFO *pHash)
Definition: msi.c:4096
INSTALLSTATE WINAPI MsiGetComponentPathExA(LPCSTR product, LPCSTR comp, LPCSTR usersid, MSIINSTALLCONTEXT ctx, LPSTR buf, LPDWORD buflen)
Definition: msi.c:2866
UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCSTR szComponent, INSTALLSTATE *pdwState)
Definition: msi.c:2057
UINT WINAPI MsiProvideComponentA(const char *product, const char *feature, const char *component, DWORD mode, char *buf, DWORD *buflen)
Definition: msi.c:4204
INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR product, LPCSTR comp, LPSTR buf, LPDWORD buflen)
Definition: msi.c:2904
UINT WINAPI MsiProvideComponentW(const WCHAR *product, const WCHAR *feature, const WCHAR *component, DWORD mode, WCHAR *buf, DWORD *buflen)
Definition: msi.c:4252
INSTALLSTATE WINAPI MsiUseFeatureExA(const char *szProduct, const char *szFeature, DWORD dwInstallMode, DWORD dwReserved)
Definition: msi.c:3309
UINT WINAPI MsiGetProductInfoExA(LPCSTR szProductCode, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCSTR szProperty, LPSTR szValue, LPDWORD pcchValue)
Definition: msi.c:1302
UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
Definition: package.c:1650
UINT WINAPI MsiOpenPackageExW(const WCHAR *szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
Definition: package.c:1612
UINT WINAPI MsiEnumProductsExA(const char *product, const char *usersid, DWORD ctx, DWORD index, char installed_product[GUID_SIZE], MSIINSTALLCONTEXT *installed_ctx, char *sid, DWORD *sid_len)
Definition: registry.c:2117
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
UINT WINAPI MsiEnumComponentsExA(const char *user_sid, DWORD ctx, DWORD index, CHAR guid[39], MSIINSTALLCONTEXT *installed_ctx, char *sid, DWORD *sid_len)
Definition: registry.c:1124
UINT WINAPI MsiSourceListGetInfoA(LPCSTR szProduct, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCSTR szProperty, LPSTR szValue, LPDWORD pcchValue)
Definition: source.c:470
static HINSTANCE hkernel32
Definition: process.c:66
#define GET_PROC(dll, func)

Referenced by START_TEST().

◆ INSTALLSTATE()

static INSTALLSTATE ( WINAPI pMsiGetComponentPathA)
static

◆ LONG()

static LONG ( WINAPI pRegDeleteKeyExA)
static

◆ set_summary_info()

static UINT set_summary_info ( MSIHANDLE  hdb,
LPSTR  prodcode 
)
static

Definition at line 783 of file msi.c.

784{
785 UINT res;
787
788 /* build summary info */
790 ok(res == ERROR_SUCCESS, "Failed to open summaryinfo\n");
791
793 "Installation Database");
794 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
795
797 "Installation Database");
798 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
799
801 "Wine Hackers");
802 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
803
805 ";1033");
806 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
807
809 "{A2078D65-94D6-4205-8DEE-F68D6FD622AA}");
810 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
811
813 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
814
816 ok(res == ERROR_SUCCESS, "Failed to set summary info\n");
817
819 ok(res == ERROR_SUCCESS, "Failed to make summary info persist\n");
820
822 ok(res == ERROR_SUCCESS, "Failed to close suminfo\n");
823
824 return res;
825}
static const CHAR suminfo[]
Definition: db.c:2206
@ VT_LPSTR
Definition: compat.h:2324
@ VT_I4
Definition: compat.h:2298
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
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 PID_REVNUMBER
Definition: suminfo.c:51

Referenced by create_package_db().

◆ squash_guid()

static BOOL squash_guid ( LPCWSTR  in,
LPWSTR  out 
)
static

Definition at line 1193 of file msi.c.

1194{
1195 DWORD i,n=1;
1196 GUID guid;
1197
1198 if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
1199 return FALSE;
1200
1201 for(i=0; i<8; i++)
1202 out[7-i] = in[n++];
1203 n++;
1204 for(i=0; i<4; i++)
1205 out[11-i] = in[n++];
1206 n++;
1207 for(i=0; i<4; i++)
1208 out[15-i] = in[n++];
1209 n++;
1210 for(i=0; i<2; i++)
1211 {
1212 out[17+i*2] = in[n++];
1213 out[16+i*2] = in[n++];
1214 }
1215 n++;
1216 for( ; i<8; i++)
1217 {
1218 out[17+i*2] = in[n++];
1219 out[16+i*2] = in[n++];
1220 }
1221 out[32]=0;
1222 return TRUE;
1223}
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
GLdouble n
Definition: glext.h:7729
GLuint in
Definition: glext.h:9616
static FILE * out
Definition: regtests2xml.c:44

◆ START_TEST()

START_TEST ( msi  )

Definition at line 14584 of file msi.c.

14585{
14586 DWORD len;
14587 char temp_path[MAX_PATH], prev_path[MAX_PATH];
14588
14589#ifdef __REACTOS__
14590 if (!winetest_interactive &&
14591 !strcmp(winetest_platform, "windows"))
14592 {
14593 skip("ROSTESTS-180: Skipping msi_winetest:msi because it hangs on WHS-Testbot. Set winetest_interactive to run it anyway.\n");
14594 return;
14595 }
14596#endif
14597
14599
14600 if (pIsWow64Process)
14601 pIsWow64Process(GetCurrentProcess(), &is_wow64);
14602
14603 GetCurrentDirectoryA(MAX_PATH, prev_path);
14606
14609
14610 if(len && (CURR_DIR[len - 1] == '\\'))
14611 CURR_DIR[len - 1] = 0;
14612
14613 ok(get_system_dirs(), "failed to retrieve system dirs\n");
14614
14616 test_null();
14649 if (pMsiGetComponentPathExA)
14653
14654 SetCurrentDirectoryA(prev_path);
14655}
static char CURR_DIR[MAX_PATH]
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define skip(...)
Definition: atltest.h:64
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
BOOL get_system_dirs(void)
Definition: install.c:2423
static void test_MsiGetComponentPathEx(void)
Definition: msi.c:3050
static void test_MsiGetComponentPath(void)
Definition: msi.c:2503
static void test_MsiGetFileSignatureInformation(void)
Definition: msi.c:13189
static void test_MsiEnumComponents(void)
Definition: msi.c:13409
static void test_MsiGetFeatureInfo(void)
Definition: msi.c:13954
static void test_MsiGetProductInfo(void)
Definition: msi.c:4376
static void test_MsiEnumPatches(void)
Definition: msi.c:11148
static void test_MsiEnumClients(void)
Definition: msi.c:3882
static void test_usefeature(void)
Definition: msi.c:873
static void test_MsiGetPatchInfo(void)
Definition: msi.c:12900
static void test_MsiEnumProductsEx(void)
Definition: msi.c:13232
static void test_MsiSetFeatureAttributes(void)
Definition: msi.c:13872
static void test_MsiQueryFeatureState(void)
Definition: msi.c:1623
static BOOL is_wow64
Definition: msi.c:40
static void test_MsiSetExternalUI(void)
Definition: msi.c:14069
static void test_MsiGetFileVersion(void)
Definition: msi.c:4106
static void test_MsiGetFileHash(void)
Definition: msi.c:1132
static void test_MsiGetUserInfo(void)
Definition: msi.c:8440
static void init_functionpointers(void)
Definition: msi.c:81
static void test_MsiEnumPatchesEx(void)
Definition: msi.c:10887
static void test_MsiOpenProduct(void)
Definition: msi.c:9036
static void test_MsiQueryComponentState(void)
Definition: msi.c:2113
static void test_null(void)
Definition: msi.c:919
static void test_MsiGetProductCode(void)
Definition: msi.c:3603
static void test_MsiProvideComponent(void)
Definition: msi.c:3377
static void test_MsiQueryProductState(void)
Definition: msi.c:1266
static void test_MsiConfigureProductEx(void)
Definition: msi.c:13587
static void test_MsiGetPatchInfoEx(void)
Definition: msi.c:11856
static void test_MsiGetProductInfoEx(void)
Definition: msi.c:5673
static void test_setpropertyfolder(void)
Definition: msi.c:14254
static void test_MsiSetInternalUI(void)
Definition: msi.c:14052
static void test_MsiEnumProducts(void)
Definition: msi.c:13093
static void test_getcomponentpath(void)
Definition: msi.c:1024
static void test_command_line_parsing(void)
Definition: msi.c:14424
static void test_MsiEnumComponentsEx(void)
Definition: msi.c:13482
static void test_concurrentinstall(void)
Definition: msi.c:14372
static void test_sourcedir_props(void)
Definition: msi.c:14309
static void test_MsiProvideQualifiedComponentEx(void)
Definition: msi.c:3463
static void test_lastusedsource(void)
Definition: msi.c:14132
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
const char * winetest_platform
int winetest_interactive

◆ test_command_line_parsing()

static void test_command_line_parsing ( void  )
static

Definition at line 14424 of file msi.c.

14425{
14426 UINT r;
14427 const char *cmd;
14428
14429 if (is_process_limited())
14430 {
14431 skip("process is limited\n");
14432 return;
14433 }
14434
14437
14439
14440 cmd = " ";
14442 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14443
14444 cmd = "=";
14446 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14447
14448 cmd = "==";
14450 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14451
14452 cmd = "one";
14454 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14455
14456 cmd = "=one";
14458 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14459
14460 cmd = "P=";
14462 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14463
14464 cmd = " P=";
14466 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14467
14468 cmd = "P= ";
14470 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14471
14472 cmd = "P=\"";
14474 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14475
14476 cmd = "P=\"\"";
14478 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14479
14480 cmd = "P=\"\"\"";
14482 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14483
14484 cmd = "P=\"\"\"\"";
14486 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14487
14488 cmd = "P=\" ";
14490 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14491
14492 cmd = "P= \"";
14494 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14495
14496 cmd = "P= \"\" ";
14498 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14499
14500 cmd = "P=\" \"";
14502 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14503
14504 cmd = "P=one";
14506 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14507
14508 cmd = "P= one";
14510 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14511
14512 cmd = "P=\"one";
14514 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14515
14516 cmd = "P=one\"";
14518 todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14519
14520 cmd = "P=\"one\"";
14522 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14523
14524 cmd = "P= \"one\" ";
14526 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14527
14528 cmd = "P=\"one\"\"";
14530 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14531
14532 cmd = "P=\"\"one\"";
14534 ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14535
14536 cmd = "P=\"\"one\"\"";
14538 todo_wine ok(r == ERROR_INVALID_COMMAND_LINE, "Expected ERROR_INVALID_COMMAND_LINE, got %u\n", r);
14539
14540 cmd = "P=\"one two\"";
14542 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14543
14544 cmd = "P=\"\"\"one\"\" two\"";
14546 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14547
14548 cmd = "P=\"\"\"one\"\" two\" Q=three";
14550 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14551
14552 cmd = "P=\"\" Q=\"two\"";
14554 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14555
14556 cmd = "P=\"one\" Q=\"two\"";
14558 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14559
14560 cmd = "P=\"one=two\"";
14562 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14563
14564 cmd = "Q=\"\" P=\"one\"";
14566 ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
14567
14568 cmd = "P=\"\"\"one\"\"\" Q=\"two\"";
14570 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14571
14572 cmd = "P=\"one \"\"two\"\"\" Q=\"three\"";
14574 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14575
14576 cmd = "P=\"\"\"one\"\" two\" Q=\"three\"";
14578 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14579
14582}
UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
Definition: msi.c:200
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2284
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static BOOL is_process_limited(void)
Definition: atl.c:113
#define todo_wine
Definition: custom.c:79
static void delete_test_files(void)
Definition: msi.c:1084
static void create_test_files(void)
Definition: msi.c:1064
static const msi_table cl_tables[]
Definition: msi.c:770
#define create_database(name, tables, num_tables)
Definition: utils.h:42
@ INSTALLUILEVEL_NONE
Definition: msi.h:66
Definition: ftp_var.h:139
#define ERROR_INVALID_COMMAND_LINE
Definition: winerror.h:997
#define ERROR_INSTALL_FAILURE
Definition: winerror.h:961

Referenced by START_TEST().

◆ test_concurrentinstall()

static void test_concurrentinstall ( void  )
static

Definition at line 14372 of file msi.c.

14373{
14374 UINT r;
14376
14377 if (is_process_limited())
14378 {
14379 skip("process is limited\n");
14380 return;
14381 }
14382
14383 CreateDirectoryA("msitest", NULL);
14384 CreateDirectoryA("msitest\\msitest", NULL);
14385 create_file("msitest\\maximus", 500);
14386 create_file("msitest\\msitest\\augustus", 500);
14387
14389
14391 lstrcatA(path, "\\msitest\\concurrent.msi");
14393
14395
14398 {
14399 skip("Not enough rights to perform tests\n");
14400 goto error;
14401 }
14402 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
14403 ok(delete_pf("msitest\\augustus", TRUE), "File not installed\n");
14404 ok(delete_pf("msitest\\maximus", TRUE), "File not installed\n");
14405 ok(delete_pf("msitest", FALSE), "Directory not created\n");
14406
14407 r = MsiConfigureProductA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}", INSTALLLEVEL_DEFAULT,
14409 ok(r == ERROR_SUCCESS, "got %u\n", r);
14410
14411 r = MsiConfigureProductA("{FF4AFE9C-6AC2-44F9-A060-9EA6BD16C75E}", INSTALLLEVEL_DEFAULT,
14413 ok(r == ERROR_SUCCESS, "got %u\n", r);
14414
14415error:
14418 DeleteFileA("msitest\\msitest\\augustus");
14419 DeleteFileA("msitest\\maximus");
14420 RemoveDirectoryA("msitest\\msitest");
14421 RemoveDirectoryA("msitest");
14422}
UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
Definition: msi.c:948
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
#define error(str)
Definition: mkdosfs.c:1605
static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
Definition: automation.c:414
static const msi_table ci2_tables[]
Definition: msi.c:758
static const msi_table ci_tables[]
Definition: msi.c:745
@ INSTALLSTATE_ABSENT
Definition: msi.h:45
@ INSTALLLEVEL_DEFAULT
Definition: msi.h:87
@ INSTALLUILEVEL_FULL
Definition: msi.h:69
#define ERROR_INSTALL_PACKAGE_REJECTED
Definition: winerror.h:983

Referenced by START_TEST().

◆ test_getcomponentpath()

static void test_getcomponentpath ( void  )
static

Definition at line 1024 of file msi.c.

1025{
1027 char buffer[0x100];
1028 DWORD sz;
1029
1030 if(!pMsiGetComponentPathA)
1031 return;
1032
1033 r = pMsiGetComponentPathA( NULL, NULL, NULL, NULL );
1034 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1035
1036 r = pMsiGetComponentPathA( "bogus", "bogus", NULL, NULL );
1037 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1038
1039 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", NULL, NULL );
1040 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1041
1042 sz = sizeof buffer;
1043 buffer[0]=0;
1044 r = pMsiGetComponentPathA( "bogus", "{00000000-0000-0000-000000000000}", buffer, &sz );
1045 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1046
1047 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C998E7}",
1048 "{00000000-0000-0000-0000-000000000000}", buffer, &sz );
1049 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1050
1051 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1052 "{00000000-0000-0000-0000-00000000}", buffer, &sz );
1053 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1054
1055 r = pMsiGetComponentPathA( "{00000409-78E1-11D2-B60F-006097C998E7}",
1056 "{029E403D-A86A-1D11-5B5B0006799C897E}", buffer, &sz );
1057 ok( r == INSTALLSTATE_INVALIDARG, "wrong return value\n");
1058
1059 r = pMsiGetComponentPathA( "{00000000-78E1-11D2-B60F-006097C9987e}",
1060 "{00000000-A68A-11d1-5B5B-0006799C897E}", buffer, &sz );
1061 ok( r == INSTALLSTATE_UNKNOWN, "wrong return value\n");
1062}
@ INSTALLSTATE_UNKNOWN
Definition: msi.h:42
@ INSTALLSTATE_INVALIDARG
Definition: msi.h:41
int INSTALLSTATE
Definition: winemsi.idl:31

Referenced by START_TEST().

◆ test_lastusedsource()

static void test_lastusedsource ( void  )
static

Definition at line 14132 of file msi.c.

14133{
14134 static const char prodcode[] = "{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}";
14135 char value[MAX_PATH], path[MAX_PATH];
14136 DWORD size;
14137 UINT r;
14138
14139 if (!pMsiSourceListGetInfoA)
14140 {
14141 win_skip("MsiSourceListGetInfoA is not available\n");
14142 return;
14143 }
14144
14145 CreateDirectoryA("msitest", NULL);
14146 create_file("maximus", 500);
14147 create_cab_file("test1.cab", MEDIA_SIZE, "maximus\0");
14148 DeleteFileA("maximus");
14149
14153
14155
14156 /* no cabinet file */
14157
14158 size = MAX_PATH;
14159 lstrcpyA(value, "aaa");
14160 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14162 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14163 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14164
14165 r = MsiInstallProductA("msifile0.msi", "PUBLISH_PRODUCT=1");
14167 {
14168 skip("Not enough rights to perform tests\n");
14169 goto error;
14170 }
14171 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14172
14174 lstrcatA(path, "\\");
14175
14176 size = MAX_PATH;
14177 lstrcpyA(value, "aaa");
14178 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14180 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14181 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
14182 ok(size == lstrlenA(path), "expected %d, got %lu\n", lstrlenA(path), size);
14183
14184 r = MsiInstallProductA("msifile0.msi", "REMOVE=ALL FULL=1");
14185 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14186
14187 /* separate cabinet file */
14188
14189 size = MAX_PATH;
14190 lstrcpyA(value, "aaa");
14191 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14193 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14194 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14195
14196 r = MsiInstallProductA("msifile1.msi", "PUBLISH_PRODUCT=1");
14197 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14198
14200 lstrcatA(path, "\\");
14201
14202 size = MAX_PATH;
14203 lstrcpyA(value, "aaa");
14204 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14206 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14207 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
14208 ok(size == lstrlenA(path), "expected %d, got %lu\n", lstrlenA(path), size);
14209
14210 r = MsiInstallProductA("msifile1.msi", "REMOVE=ALL FULL=1");
14211 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14212
14213 size = MAX_PATH;
14214 lstrcpyA(value, "aaa");
14215 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14217 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14218 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14219
14220 /* embedded cabinet stream */
14221
14222 add_cabinet_storage("msifile2.msi", "test1.cab");
14223
14224 r = MsiInstallProductA("msifile2.msi", "PUBLISH_PRODUCT=1");
14225 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14226
14227 size = MAX_PATH;
14228 lstrcpyA(value, "aaa");
14229 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14231 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14232 ok(!lstrcmpA(value, path), "expected \"%s\", got \"%s\"\n", path, value);
14233 ok(size == lstrlenA(path), "expected %d, got %lu\n", lstrlenA(path), size);
14234
14235 r = MsiInstallProductA("msifile2.msi", "REMOVE=ALL FULL=1");
14236 ok(r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r);
14237
14238 size = MAX_PATH;
14239 lstrcpyA(value, "aaa");
14240 r = pMsiSourceListGetInfoA(prodcode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
14242 ok(r == ERROR_UNKNOWN_PRODUCT, "expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
14243 ok(!lstrcmpA(value, "aaa"), "expected \"aaa\", got \"%s\"\n", value);
14244
14245error:
14247 DeleteFileA("msitest\\maximus");
14248 RemoveDirectoryA("msitest");
14249 DeleteFileA("msifile0.msi");
14250 DeleteFileA("msifile1.msi");
14251 DeleteFileA("msifile2.msi");
14252}
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
void delete_cab_files(void)
Definition: install.c:3097
static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
Definition: msi.c:121
static const msi_table lus0_tables[]
Definition: msi.c:666
static const msi_table lus2_tables[]
Definition: msi.c:690
static const msi_table lus1_tables[]
Definition: msi.c:678
#define INSTALLPROPERTY_LASTUSEDSOURCEA
Definition: msi.h:404
@ MSICODE_PRODUCT
Definition: msi.h:215
@ MSIINSTALLCONTEXT_USERUNMANAGED
Definition: msi.h:199
#define win_skip
Definition: test.h:160
Definition: pdh_main.c:94
#define ERROR_UNKNOWN_PRODUCT
Definition: winerror.h:963

Referenced by START_TEST().

◆ test_MsiConfigureProductEx()

static void test_MsiConfigureProductEx ( void  )
static

Definition at line 13587 of file msi.c.

13588{
13589 UINT r;
13590 LONG res;
13591 DWORD type, size;
13592 HKEY props, source;
13593 CHAR keypath[MAX_PATH * 2], localpackage[MAX_PATH], packagename[MAX_PATH];
13595
13596 if (is_process_limited())
13597 {
13598 skip("process is limited\n");
13599 return;
13600 }
13601
13602 CreateDirectoryA("msitest", NULL);
13603 create_file_data("msitest\\hydrogen", "hydrogen", 500);
13604 create_file_data("msitest\\helium", "helium", 500);
13605 create_file_data("msitest\\lithium", "lithium", 500);
13606
13608
13609 if (is_wow64)
13611
13613
13614 /* NULL szProduct */
13616 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13618 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13619
13620 /* empty szProduct */
13622 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13624 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13625
13626 /* garbage szProduct */
13628 INSTALLSTATE_DEFAULT, "PROPVAR=42");
13630 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13631
13632 /* guid without brackets */
13633 r = MsiConfigureProductExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D",
13635 "PROPVAR=42");
13637 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
13638
13639 /* guid with brackets */
13640 r = MsiConfigureProductExA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}",
13642 "PROPVAR=42");
13644 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13645
13646 /* same length as guid, but random */
13647 r = MsiConfigureProductExA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93",
13649 "PROPVAR=42");
13651 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13652
13653 /* product not installed yet */
13654 r = MsiConfigureProductExA("{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}",
13656 "PROPVAR=42");
13658 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
13659
13660 /* install the product, per-user unmanaged */
13661 r = MsiInstallProductA(msifile, "INSTALLLEVEL=10 PROPVAR=42");
13663 {
13664 skip("Not enough rights to perform tests\n");
13665 goto error;
13666 }
13667 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13668 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13669 ok(pf_exists("msitest\\helium"), "File not installed\n");
13670 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13671 ok(pf_exists("msitest"), "File not installed\n");
13672
13673 /* product is installed per-user managed, remove it */
13674 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13676 "PROPVAR=42");
13677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13678 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13679 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13680 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13681 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13682
13683 /* product has been removed */
13684 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13686 "PROPVAR=42");
13688 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13689
13690 /* install the product, machine */
13691 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13692 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13693 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13694 ok(pf_exists("msitest\\helium"), "File not installed\n");
13695 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13696 ok(pf_exists("msitest"), "File not installed\n");
13697
13698 /* product is installed machine, remove it */
13699 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13701 "PROPVAR=42");
13702 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13703 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13704 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13705 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13706 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13707
13708 /* product has been removed */
13709 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13711 "PROPVAR=42");
13713 "Expected ERROR_UNKNOWN_PRODUCT, got %u\n", r);
13714
13715 /* install the product, machine */
13716 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13717 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13718 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13719 ok(pf_exists("msitest\\helium"), "File not installed\n");
13720 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13721 ok(pf_exists("msitest"), "File not installed\n");
13722
13724
13725 /* msifile is removed */
13726 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13728 "PROPVAR=42");
13729 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13730 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13731 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13732 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13733 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13734
13736
13737 /* install the product, machine */
13738 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13739 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13740 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13741 ok(pf_exists("msitest\\helium"), "File not installed\n");
13742 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13743 ok(pf_exists("msitest"), "File not installed\n");
13744
13746
13747 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
13748 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
13749 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
13750
13752 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
13753
13754 type = REG_SZ;
13755 size = MAX_PATH;
13756 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
13757 (LPBYTE)localpackage, &size);
13758 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
13759
13760 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13761 (const BYTE *)"C:\\idontexist.msi", 18);
13762 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
13763
13764 /* LocalPackage is used to find the cached msi package */
13765 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13767 "PROPVAR=42");
13769 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
13770 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13771 ok(pf_exists("msitest\\helium"), "File not installed\n");
13772 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13773 ok(pf_exists("msitest"), "File not installed\n");
13774
13777
13778 /* LastUsedSource can be used as a last resort */
13779 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13781 "PROPVAR=42");
13782 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13783 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13784 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13785 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13786 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13787 DeleteFileA( localpackage );
13788
13789 /* install the product, machine */
13790 r = MsiInstallProductA(msifile, "ALLUSERS=1 INSTALLLEVEL=10 PROPVAR=42");
13791 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
13792 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13793 ok(pf_exists("msitest\\helium"), "File not installed\n");
13794 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13795 ok(pf_exists("msitest"), "File not installed\n");
13796
13797 lstrcpyA(keypath, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\");
13798 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
13799 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\InstallProperties");
13800
13802 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
13803
13804 type = REG_SZ;
13805 size = MAX_PATH;
13806 res = RegQueryValueExA(props, "LocalPackage", NULL, &type,
13807 (LPBYTE)localpackage, &size);
13808 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
13809
13810 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13811 (const BYTE *)"C:\\idontexist.msi", 18);
13812 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
13813
13814 lstrcpyA(keypath, "SOFTWARE\\Classes\\Installer\\Products\\");
13815 lstrcatA(keypath, "83374883CBB1401418CAF2AA7CCEDDDC\\SourceList");
13816
13818 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
13819
13820 type = REG_SZ;
13821 size = MAX_PATH;
13822 res = RegQueryValueExA(source, "PackageName", NULL, &type,
13823 (LPBYTE)packagename, &size);
13824 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
13825
13826 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
13827 (const BYTE *)"idontexist.msi", 15);
13828 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
13829
13830 /* SourceList is altered */
13831 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13833 "PROPVAR=42");
13835 "Expected ERROR_INSTALL_SOURCE_ABSENT, got %d\n", r);
13836 ok(pf_exists("msitest\\hydrogen"), "File not installed\n");
13837 ok(pf_exists("msitest\\helium"), "File not installed\n");
13838 ok(pf_exists("msitest\\lithium"), "File not installed\n");
13839 ok(pf_exists("msitest"), "File not installed\n");
13840
13841 /* restore PackageName */
13842 res = RegSetValueExA(source, "PackageName", 0, REG_SZ,
13843 (const BYTE *)packagename, lstrlenA(packagename) + 1);
13844 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
13845
13846 /* restore LocalPackage */
13847 res = RegSetValueExA(props, "LocalPackage", 0, REG_SZ,
13848 (const BYTE *)localpackage, lstrlenA(localpackage) + 1);
13849 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
13850
13851 /* finally remove the product */
13852 r = MsiConfigureProductExA("{38847338-1BBC-4104-81AC-2FAAC7ECDDCD}",
13854 "PROPVAR=42");
13855 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
13856 ok(!delete_pf("msitest\\hydrogen", TRUE), "File not removed\n");
13857 ok(!delete_pf("msitest\\helium", TRUE), "File not removed\n");
13858 ok(!delete_pf("msitest\\lithium", TRUE), "File not removed\n");
13859 ok(!delete_pf("msitest", FALSE), "Directory not removed\n");
13860
13863
13864error:
13865 DeleteFileA("msitest\\hydrogen");
13866 DeleteFileA("msitest\\helium");
13867 DeleteFileA("msitest\\lithium");
13868 RemoveDirectoryA("msitest");
13870}
#define RegCloseKey(hKey)
Definition: registry.h:49
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4828
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3327
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:4038
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState, LPCSTR szCommandLine)
Definition: msi.c:918
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define REG_SZ
Definition: layer.c:22
static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
Definition: asmcache.c:795
static BOOL pf_exists(const char *file)
Definition: custom.c:1406
static const msi_table mcp_tables[]
Definition: msi.c:654
@ INSTALLSTATE_DEFAULT
Definition: msi.h:48
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
long LONG
Definition: pedump.c:60
unsigned char * LPBYTE
Definition: typedefs.h:53
static const WCHAR props[]
Definition: wbemdisp.c:288
#define ERROR_INSTALL_SOURCE_ABSENT
Definition: winerror.h:970
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
unsigned char BYTE
Definition: xxhash.c:193

Referenced by START_TEST().

◆ test_MsiEnumClients()

static void test_MsiEnumClients ( void  )
static

Definition at line 3882 of file msi.c.

3883{
3884 HKEY compkey;
3885 CHAR prodcode[MAX_PATH];
3886 CHAR prod_squashed[MAX_PATH];
3887 CHAR prodcode2[MAX_PATH];
3888 CHAR prod2_squashed[MAX_PATH];
3889 CHAR component[MAX_PATH];
3890 CHAR comp_base85[MAX_PATH];
3891 CHAR comp_squashed[MAX_PATH];
3892 CHAR product[MAX_PATH];
3893 CHAR keypath[MAX_PATH];
3894 LPSTR usersid;
3895 LONG res;
3896 UINT r;
3898
3899 create_test_guid(prodcode, prod_squashed);
3900 create_test_guid(prodcode2, prod2_squashed);
3901 compose_base85_guid(component, comp_base85, comp_squashed);
3902 usersid = get_user_sid();
3903
3904 if (is_wow64)
3906
3907 /* NULL szComponent */
3908 product[0] = '\0';
3909 r = MsiEnumClientsA(NULL, 0, product);
3910 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3911 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3912
3913 /* empty szComponent */
3914 product[0] = '\0';
3915 r = MsiEnumClientsA("", 0, product);
3916 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3917 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3918
3919 /* NULL lpProductBuf */
3920 r = MsiEnumClientsA(component, 0, NULL);
3921 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3922
3923 /* all params correct, component missing */
3924 product[0] = '\0';
3925 r = MsiEnumClientsA(component, 0, product);
3926 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3927 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3928
3929 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
3930 lstrcatA(keypath, "Installer\\UserData\\");
3931 lstrcatA(keypath, usersid);
3932 lstrcatA(keypath, "\\Components\\");
3933 lstrcatA(keypath, comp_squashed);
3934
3935 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
3936 if (res == ERROR_ACCESS_DENIED)
3937 {
3938 skip("Not enough rights to perform tests\n");
3939 LocalFree(usersid);
3940 return;
3941 }
3942 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3943
3944 /* user unmanaged component key exists */
3945 product[0] = '\0';
3946 r = MsiEnumClientsA(component, 0, product);
3947 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
3948 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3949
3950 /* index > 0, no products exist */
3951 product[0] = '\0';
3952 r = MsiEnumClientsA(component, 1, product);
3953 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3954 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3955
3956 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
3957 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3958
3959 /* product value exists */
3960 r = MsiEnumClientsA(component, 0, product);
3961 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3962 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3963
3964 /* try index 0 again */
3965 product[0] = '\0';
3966 r = MsiEnumClientsA(component, 0, product);
3967 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3968 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
3969
3970 /* try index 1, second product value does not exist */
3971 product[0] = '\0';
3972 r = MsiEnumClientsA(component, 1, product);
3973 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
3974 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3975
3976 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
3977 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
3978
3979 /* try index 1, second product value does exist */
3980 product[0] = '\0';
3981 r = MsiEnumClientsA(component, 1, product);
3982 todo_wine
3983 {
3984 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
3985 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
3986 }
3987
3988 /* start the enumeration over */
3989 product[0] = '\0';
3990 r = MsiEnumClientsA(component, 0, product);
3991 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3992 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
3993 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
3994
3995 /* correctly query second product */
3996 product[0] = '\0';
3997 r = MsiEnumClientsA(component, 1, product);
3998 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
3999 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
4000 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
4001
4002 RegDeleteValueA(compkey, prod_squashed);
4003 RegDeleteValueA(compkey, prod2_squashed);
4004 delete_key(compkey, "", access & KEY_WOW64_64KEY);
4005 RegCloseKey(compkey);
4006
4007 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
4008 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
4009 lstrcatA(keypath, comp_squashed);
4010
4011 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
4012 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4013
4014 /* user local component key exists */
4015 product[0] = '\0';
4016 r = MsiEnumClientsA(component, 0, product);
4017 ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
4018 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4019
4020 /* index > 0, no products exist */
4021 product[0] = '\0';
4022 r = MsiEnumClientsA(component, 1, product);
4023 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4024 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4025
4026 res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"C:\\imapath", 10);
4027 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4028
4029 /* product value exists */
4030 product[0] = '\0';
4031 r = MsiEnumClientsA(component, 0, product);
4032 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4033 ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
4034
4035 /* try index 0 again */
4036 product[0] = '\0';
4037 r = MsiEnumClientsA(component, 0, product);
4038 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4039
4040 /* try index 1, second product value does not exist */
4041 product[0] = '\0';
4042 r = MsiEnumClientsA(component, 1, product);
4043 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
4044 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4045
4046 res = RegSetValueExA(compkey, prod2_squashed, 0, REG_SZ, (const BYTE *)"C:\\another", 10);
4047 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
4048
4049 /* try index 1, second product value does exist */
4050 product[0] = '\0';
4051 r = MsiEnumClientsA(component, 1, product);
4052 todo_wine
4053 {
4054 ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
4055 ok(!lstrcmpA(product, ""), "Expected product to be unchanged, got %s\n", product);
4056 }
4057
4058 /* start the enumeration over */
4059 product[0] = '\0';
4060 r = MsiEnumClientsA(component, 0, product);
4061 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4062 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
4063 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
4064
4065 /* correctly query second product */
4066 product[0] = '\0';
4067 r = MsiEnumClientsA(component, 1, product);
4068 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
4069 ok(!lstrcmpA(product, prodcode) || !lstrcmpA(product, prodcode2),
4070 "Expected %s or %s, got %s\n", prodcode, prodcode2, product);
4071
4072 RegDeleteValueA(compkey, prod_squashed);
4073 RegDeleteValueA(compkey, prod2_squashed);
4074 delete_key(compkey, "", access & KEY_WOW64_64KEY);
4075 RegCloseKey(compkey);
4076 LocalFree(usersid);
4077}
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2325
LONG WINAPI RegCreateKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD Reserved, _In_ LPSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_ LPDWORD lpdwDisposition)
Definition: reg.c:1034
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
UINT WINAPI MsiEnumClientsA(const char *szComponent, DWORD index, char *szProduct)
Definition: registry.c:1328
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
Definition: msi.c:1601
static char * get_user_sid(void)
Definition: msi.c:1247
static void create_test_guid(LPSTR prodcode, LPSTR squashed)
Definition: msi.c:1225
#define delete_key(r, p, s)
Definition: reg_test.h:64
#define ERROR_UNKNOWN_COMPONENT
Definition: winerror.h:965

Referenced by START_TEST().

◆ test_MsiEnumComponents()

static void test_MsiEnumComponents ( void  )
static

Definition at line 13409 of file msi.c.

13410{
13411 UINT r;
13412 BOOL found1, found2;
13413 DWORD index;
13414 char comp1[39], comp2[39], guid[39];
13415 char comp_squashed1[33], comp_squashed2[33];
13416 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13418 char *usersid = get_user_sid();
13419 HKEY key1 = NULL, key2 = NULL;
13420
13421 if (is_process_limited())
13422 {
13423 skip("process is limited\n");
13424 return;
13425 }
13426
13427 create_test_guid( comp1, comp_squashed1 );
13428 create_test_guid( comp2, comp_squashed2 );
13429
13431
13432 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13433 strcat( keypath1, "S-1-5-18\\Components\\" );
13434 strcat( keypath1, comp_squashed1 );
13435
13436 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13437 if (r == ERROR_ACCESS_DENIED)
13438 {
13439 skip( "insufficient rights\n" );
13440 goto done;
13441 }
13442 ok( r == ERROR_SUCCESS, "got %u\n", r );
13443
13444 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13445 strcat( keypath2, usersid );
13446 strcat( keypath2, "\\Components\\" );
13447 strcat( keypath2, comp_squashed2 );
13448
13449 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13450 if (r == ERROR_ACCESS_DENIED)
13451 {
13452 skip( "insufficient rights\n" );
13453 goto done;
13454 }
13455
13456 r = MsiEnumComponentsA( 0, NULL );
13457 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13458
13459 index = 0;
13460 guid[0] = 0;
13461 found1 = found2 = FALSE;
13462 while (!MsiEnumComponentsA( index, guid ))
13463 {
13464 if (!strcmp( guid, comp1 )) found1 = TRUE;
13465 if (!strcmp( guid, comp2 )) found2 = TRUE;
13466 ok( guid[0], "empty guid\n" );
13467 if (found1 && found2) break;
13468 guid[0] = 0;
13469 index++;
13470 }
13471 ok( found1, "comp1 not found\n" );
13472 ok( found2, "comp2 not found\n" );
13473
13474done:
13475 delete_key( key1, "", access );
13476 delete_key( key2, "", access );
13477 RegCloseKey( key1 );
13478 RegCloseKey( key2 );
13479 LocalFree( usersid );
13480}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define index(s, c)
Definition: various.h:29
UINT WINAPI MsiEnumComponentsA(DWORD index, char *lpguid)
Definition: registry.c:1099
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint index
Definition: glext.h:6031
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
Definition: glext.h:10608

Referenced by START_TEST().

◆ test_MsiEnumComponentsEx()

static void test_MsiEnumComponentsEx ( void  )
static

Definition at line 13482 of file msi.c.

13483{
13484 UINT r;
13485 BOOL found1, found2;
13486 DWORD len, index;
13488 char comp1[39], comp2[39], guid[39], sid[128];
13489 char comp_squashed1[33], comp_squashed2[33];
13490 char keypath1[MAX_PATH], keypath2[MAX_PATH];
13491 HKEY key1 = NULL, key2 = NULL;
13493 char *usersid = get_user_sid();
13494
13495 if (!pMsiEnumComponentsExA)
13496 {
13497 win_skip( "MsiEnumComponentsExA not implemented\n" );
13498 return;
13499 }
13500 if (is_process_limited())
13501 {
13502 skip("process is limited\n");
13503 return;
13504 }
13505
13506 create_test_guid( comp1, comp_squashed1 );
13507 create_test_guid( comp2, comp_squashed2 );
13508
13510
13511 strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13512 strcat( keypath1, "S-1-5-18\\Components\\" );
13513 strcat( keypath1, comp_squashed1 );
13514
13515 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
13516 if (r == ERROR_ACCESS_DENIED)
13517 {
13518 skip( "insufficient rights\n" );
13519 goto done;
13520 }
13521 ok( r == ERROR_SUCCESS, "got %u\n", r );
13522
13523 strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
13524 strcat( keypath2, usersid );
13525 strcat( keypath2, "\\Components\\" );
13526 strcat( keypath2, comp_squashed2 );
13527
13528 r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
13529 if (r == ERROR_ACCESS_DENIED)
13530 {
13531 skip( "insufficient rights\n" );
13532 goto done;
13533 }
13534 ok( r == ERROR_SUCCESS, "got %u\n", r );
13535 r = RegSetValueExA( key2, comp_squashed2, 0, REG_SZ, (const BYTE *)"c:\\doesnotexist",
13536 sizeof("c:\\doesnotexist"));
13537 ok( r == ERROR_SUCCESS, "got %u\n", r );
13538
13539 index = 0;
13540 guid[0] = 0;
13541 context = 0xdeadbeef;
13542 sid[0] = 0;
13543 len = sizeof(sid);
13544 found1 = found2 = FALSE;
13545 while (!pMsiEnumComponentsExA( "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
13546 {
13547 if (!strcmp( comp1, guid ))
13548 {
13549 ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
13550 ok( !sid[0], "got \"%s\"\n", sid );
13551 ok( !len, "unexpected length %lu\n", len );
13552 found1 = TRUE;
13553 if (found2) break;
13554 }
13555 if (!strcmp( comp2, guid ))
13556 {
13558 ok( sid[0], "empty sid\n" );
13559 ok( len == strlen(sid), "unexpected length %lu\n", len );
13560 found2 = TRUE;
13561 if (found1) break;
13562 }
13563 index++;
13564 guid[0] = 0;
13565 context = 0xdeadbeef;
13566 sid[0] = 0;
13567 len = sizeof(sid);
13568 }
13569 ok( found1, "comp1 not found\n" );
13570 ok( found2, "comp2 not found\n" );
13571
13572 r = pMsiEnumComponentsExA( NULL, 0, 0, NULL, NULL, NULL, NULL );
13573 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13574
13575 r = pMsiEnumComponentsExA( NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, NULL );
13576 ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
13577
13578done:
13579 RegDeleteValueA( key2, comp_squashed2 );
13580 delete_key( key1, "", access );
13581 delete_key( key2, "", access );
13582 RegCloseKey( key1 );
13583 RegCloseKey( key2 );
13584 LocalFree( usersid );
13585}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
FT_UInt sid
Definition: cffcmap.c:139
enum tagMSIINSTALLCONTEXT MSIINSTALLCONTEXT
Definition: action.c:49
@ MSIINSTALLCONTEXT_MACHINE
Definition: msi.h:200
@ MSIINSTALLCONTEXT_ALL
Definition: msi.h:201
Definition: http.c:7252

Referenced by START_TEST().

◆ test_MsiEnumPatches()

static void test_MsiEnumPatches ( void  )
static

Definition at line 11148 of file msi.c.

11149{
11150 CHAR keypath[MAX_PATH], patch[MAX_PATH];
11151 CHAR patchcode[MAX_PATH], patch_squashed[MAX_PATH];
11152 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
11153 CHAR transforms[MAX_PATH];
11154 WCHAR patchW[MAX_PATH], prodcodeW[MAX_PATH], transformsW[MAX_PATH];
11155 HKEY prodkey, patches, udprod;
11156 HKEY userkey, hpatch, udpatch;
11157 DWORD size, data;
11158 LPSTR usersid;
11159 LONG res;
11160 UINT r;
11162
11163 create_test_guid(prodcode, prod_squashed);
11164 create_test_guid(patchcode, patch_squashed);
11165 usersid = get_user_sid();
11166
11167 if (is_wow64)
11169
11170 /* NULL szProduct */
11171 size = MAX_PATH;
11172 lstrcpyA(patch, "apple");
11173 lstrcpyA(transforms, "banana");
11174 r = MsiEnumPatchesA(NULL, 0, patch, transforms, &size);
11176 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11177 ok(!lstrcmpA(patch, "apple"),
11178 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11179 ok(!lstrcmpA(transforms, "banana"),
11180 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11181 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11182
11183 /* empty szProduct */
11184 size = MAX_PATH;
11185 lstrcpyA(patch, "apple");
11186 lstrcpyA(transforms, "banana");
11187 r = MsiEnumPatchesA("", 0, patch, transforms, &size);
11189 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11190 ok(!lstrcmpA(patch, "apple"),
11191 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11192 ok(!lstrcmpA(transforms, "banana"),
11193 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11194 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11195
11196 /* garbage szProduct */
11197 size = MAX_PATH;
11198 lstrcpyA(patch, "apple");
11199 lstrcpyA(transforms, "banana");
11200 r = MsiEnumPatchesA("garbage", 0, patch, transforms, &size);
11202 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11203 ok(!lstrcmpA(patch, "apple"),
11204 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11205 ok(!lstrcmpA(transforms, "banana"),
11206 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11207 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11208
11209 /* guid without brackets */
11210 size = MAX_PATH;
11211 lstrcpyA(patch, "apple");
11212 lstrcpyA(transforms, "banana");
11213 r = MsiEnumPatchesA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", 0, patch,
11214 transforms, &size);
11216 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11217 ok(!lstrcmpA(patch, "apple"),
11218 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11219 ok(!lstrcmpA(transforms, "banana"),
11220 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11221 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11222
11223 /* guid with brackets */
11224 size = MAX_PATH;
11225 lstrcpyA(patch, "apple");
11226 lstrcpyA(transforms, "banana");
11227 r = MsiEnumPatchesA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", 0, patch,
11228 transforms, &size);
11230 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11231 ok(!lstrcmpA(patch, "apple"),
11232 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11233 ok(!lstrcmpA(transforms, "banana"),
11234 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11235 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11236
11237 /* same length as guid, but random */
11238 size = MAX_PATH;
11239 lstrcpyA(patch, "apple");
11240 lstrcpyA(transforms, "banana");
11241 r = MsiEnumPatchesA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", 0, patch,
11242 transforms, &size);
11244 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11245 ok(!lstrcmpA(patch, "apple"),
11246 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11247 ok(!lstrcmpA(transforms, "banana"),
11248 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11249 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11250
11251 /* MSIINSTALLCONTEXT_USERMANAGED */
11252
11253 size = MAX_PATH;
11254 lstrcpyA(patch, "apple");
11255 lstrcpyA(transforms, "banana");
11256 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11258 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11259 ok(!lstrcmpA(patch, "apple"),
11260 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11261 ok(!lstrcmpA(transforms, "banana"),
11262 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11263 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11264
11265 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
11266 lstrcatA(keypath, usersid);
11267 lstrcatA(keypath, "\\Installer\\Products\\");
11268 lstrcatA(keypath, prod_squashed);
11269
11270 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11271 if (res == ERROR_ACCESS_DENIED)
11272 {
11273 skip("Not enough rights to perform tests\n");
11274 LocalFree(usersid);
11275 return;
11276 }
11277 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11278
11279 /* managed product key exists */
11280 size = MAX_PATH;
11281 lstrcpyA(patch, "apple");
11282 lstrcpyA(transforms, "banana");
11283 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11284 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11285 ok(!lstrcmpA(patch, "apple"),
11286 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11287 ok(!lstrcmpA(transforms, "banana"),
11288 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11289 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11290
11291 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11292 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11293
11294 /* patches key exists */
11295 size = MAX_PATH;
11296 lstrcpyA(patch, "apple");
11297 lstrcpyA(transforms, "banana");
11298 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11300 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11301 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11302 ok(!lstrcmpA(patch, "apple"),
11303 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11304 ok(!lstrcmpA(transforms, "banana"),
11305 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11306 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11307
11308 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11309 (const BYTE *)patch_squashed,
11310 lstrlenA(patch_squashed) + 1);
11311 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11312
11313 /* Patches value exists, is not REG_MULTI_SZ */
11314 size = MAX_PATH;
11315 lstrcpyA(patch, "apple");
11316 lstrcpyA(transforms, "banana");
11317 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11319 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11320 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11321 ok(!lstrcmpA(patch, "apple"),
11322 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11323 ok(!lstrcmpA(transforms, "banana"),
11324 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11325 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11326
11327 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11328 (const BYTE *)"a\0b\0c\0\0", 7);
11329 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11330
11331 /* Patches value exists, is not a squashed guid */
11332 size = MAX_PATH;
11333 lstrcpyA(patch, "apple");
11334 lstrcpyA(transforms, "banana");
11335 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11337 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11338 ok(!lstrcmpA(patch, "apple"),
11339 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11340 ok(!lstrcmpA(transforms, "banana"),
11341 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11342 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11343
11344 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11345 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11346 (const BYTE *)patch_squashed,
11347 lstrlenA(patch_squashed) + 2);
11348 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11349
11350 /* Patches value exists */
11351 size = MAX_PATH;
11352 lstrcpyA(patch, "apple");
11353 lstrcpyA(transforms, "banana");
11354 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11356 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11357 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11358 ok(!lstrcmpA(patch, "apple") ||
11359 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11360 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11361 ok(!lstrcmpA(transforms, "banana"),
11362 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11363 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11364
11365 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11366 (const BYTE *)"whatever", 9);
11367 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11368
11369 /* patch squashed value exists */
11370 size = MAX_PATH;
11371 lstrcpyA(patch, "apple");
11372 lstrcpyA(transforms, "banana");
11373 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11374 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11375 ok(!lstrcmpA(patch, patchcode),
11376 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11377 ok(!lstrcmpA(transforms, "whatever"),
11378 "Expected \"whatever\", got \"%s\"\n", transforms);
11379 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
11380
11381 /* lpPatchBuf is NULL */
11382 size = MAX_PATH;
11383 lstrcpyA(transforms, "banana");
11384 r = MsiEnumPatchesA(prodcode, 0, NULL, transforms, &size);
11386 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11387 ok(!lstrcmpA(transforms, "banana"),
11388 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11389 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11390
11391 /* lpTransformsBuf is NULL, pcchTransformsBuf is not */
11392 size = MAX_PATH;
11393 lstrcpyA(patch, "apple");
11394 r = MsiEnumPatchesA(prodcode, 0, patch, NULL, &size);
11396 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11397 ok(!lstrcmpA(patch, "apple"),
11398 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11399 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11400
11401 /* pcchTransformsBuf is NULL, lpTransformsBuf is not */
11402 lstrcpyA(patch, "apple");
11403 lstrcpyA(transforms, "banana");
11404 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, NULL);
11406 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11407 ok(!lstrcmpA(patch, "apple"),
11408 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11409 ok(!lstrcmpA(transforms, "banana"),
11410 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11411
11412 /* pcchTransformsBuf is too small */
11413 size = 6;
11414 lstrcpyA(patch, "apple");
11415 lstrcpyA(transforms, "banana");
11416 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11417 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11418 ok(!lstrcmpA(patch, patchcode),
11419 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11420 ok(!lstrcmpA(transforms, "whate") ||
11421 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
11422 "Expected \"whate\", got \"%s\"\n", transforms);
11423 ok(size == 8 || size == 16, "Expected 8 or 16, got %lu\n", size);
11424
11425 /* increase the index */
11426 size = MAX_PATH;
11427 lstrcpyA(patch, "apple");
11428 lstrcpyA(transforms, "banana");
11429 r = MsiEnumPatchesA(prodcode, 1, patch, transforms, &size);
11430 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11431 ok(!lstrcmpA(patch, "apple"),
11432 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11433 ok(!lstrcmpA(transforms, "banana"),
11434 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11435 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11436
11437 /* increase again */
11438 size = MAX_PATH;
11439 lstrcpyA(patch, "apple");
11440 lstrcpyA(transforms, "banana");
11441 r = MsiEnumPatchesA(prodcode, 2, patch, transforms, &size);
11442 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11443 ok(!lstrcmpA(patch, "apple"),
11444 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11445 ok(!lstrcmpA(transforms, "banana"),
11446 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11447 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11448
11449 RegDeleteValueA(patches, "Patches");
11450 delete_key(patches, "", access & KEY_WOW64_64KEY);
11451 RegCloseKey(patches);
11452 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11453 RegCloseKey(prodkey);
11454
11455 /* MSIINSTALLCONTEXT_USERUNMANAGED */
11456
11457 size = MAX_PATH;
11458 lstrcpyA(patch, "apple");
11459 lstrcpyA(transforms, "banana");
11460 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11462 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11463 ok(!lstrcmpA(patch, "apple"),
11464 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11465 ok(!lstrcmpA(transforms, "banana"),
11466 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11467 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11468
11469 lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
11470 lstrcatA(keypath, prod_squashed);
11471
11472 res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
11473 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11474
11475 /* current user product key exists */
11476 size = MAX_PATH;
11477 lstrcpyA(patch, "apple");
11478 lstrcpyA(transforms, "banana");
11479 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11480 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11481 ok(!lstrcmpA(patch, "apple"),
11482 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11483 ok(!lstrcmpA(transforms, "banana"),
11484 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11485 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11486
11487 res = RegCreateKeyA(prodkey, "Patches", &patches);
11488 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11489
11490 /* Patches key exists */
11491 size = MAX_PATH;
11492 lstrcpyA(patch, "apple");
11493 lstrcpyA(transforms, "banana");
11494 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11496 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11497 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11498 ok(!lstrcmpA(patch, "apple"),
11499 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11500 ok(!lstrcmpA(transforms, "banana"),
11501 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11502 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11503
11504 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11505 (const BYTE *)patch_squashed,
11506 lstrlenA(patch_squashed) + 1);
11507 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11508
11509 /* Patches value exists, is not REG_MULTI_SZ */
11510 size = MAX_PATH;
11511 lstrcpyA(patch, "apple");
11512 lstrcpyA(transforms, "banana");
11513 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11515 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11516 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11517 ok(!lstrcmpA(patch, "apple"),
11518 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11519 ok(!lstrcmpA(transforms, "banana"),
11520 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11521 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11522
11523 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11524 (const BYTE *)"a\0b\0c\0\0", 7);
11525 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11526
11527 /* Patches value exists, is not a squashed guid */
11528 size = MAX_PATH;
11529 lstrcpyA(patch, "apple");
11530 lstrcpyA(transforms, "banana");
11531 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11533 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11534 ok(!lstrcmpA(patch, "apple"),
11535 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11536 ok(!lstrcmpA(transforms, "banana"),
11537 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11538 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11539
11540 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11541 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11542 (const BYTE *)patch_squashed,
11543 lstrlenA(patch_squashed) + 2);
11544 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11545
11546 /* Patches value exists */
11547 size = MAX_PATH;
11548 lstrcpyA(patch, "apple");
11549 lstrcpyA(transforms, "banana");
11550 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11552 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11553 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11554 ok(!lstrcmpA(patch, "apple") ||
11555 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11556 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11557 ok(!lstrcmpA(transforms, "banana"),
11558 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11559 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11560
11561 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11562 (const BYTE *)"whatever", 9);
11563 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11564
11565 /* patch code value exists */
11566 size = MAX_PATH;
11567 lstrcpyA(patch, "apple");
11568 lstrcpyA(transforms, "banana");
11569 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11571 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11572 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11573 ok(!lstrcmpA(patch, "apple") ||
11574 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11575 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11576 ok(!lstrcmpA(transforms, "banana") ||
11577 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
11578 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11579 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11580
11581 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
11582 lstrcatA(keypath, usersid);
11583 lstrcatA(keypath, "\\Patches\\");
11584 lstrcatA(keypath, patch_squashed);
11585
11586 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
11587 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11588
11589 /* userdata patch key exists */
11590 size = MAX_PATH;
11591 lstrcpyA(patch, "apple");
11592 lstrcpyA(transforms, "banana");
11593 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11594 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11595 ok(!lstrcmpA(patch, patchcode),
11596 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11597 ok(!lstrcmpA(transforms, "whatever"),
11598 "Expected \"whatever\", got \"%s\"\n", transforms);
11599 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
11600
11601 delete_key(userkey, "", access & KEY_WOW64_64KEY);
11602 RegCloseKey(userkey);
11603 RegDeleteValueA(patches, patch_squashed);
11604 RegDeleteValueA(patches, "Patches");
11605 RegDeleteKeyA(patches, "");
11606 RegCloseKey(patches);
11607 RegDeleteKeyA(prodkey, "");
11608 RegCloseKey(prodkey);
11609
11610 /* MSIINSTALLCONTEXT_MACHINE */
11611
11612 size = MAX_PATH;
11613 lstrcpyA(patch, "apple");
11614 lstrcpyA(transforms, "banana");
11615 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11617 "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
11618 ok(!lstrcmpA(patch, "apple"),
11619 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11620 ok(!lstrcmpA(transforms, "banana"),
11621 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11622 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11623
11624 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
11625 lstrcatA(keypath, prod_squashed);
11626
11627 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
11628 if (res == ERROR_ACCESS_DENIED)
11629 {
11630 skip("Not enough rights to perform tests\n");
11631 LocalFree(usersid);
11632 return;
11633 }
11634 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11635
11636 /* local product key exists */
11637 size = MAX_PATH;
11638 lstrcpyA(patch, "apple");
11639 lstrcpyA(transforms, "banana");
11640 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11641 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11642 ok(!lstrcmpA(patch, "apple"),
11643 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11644 ok(!lstrcmpA(transforms, "banana"),
11645 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11646 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11647
11648 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
11649 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11650
11651 /* Patches key exists */
11652 size = MAX_PATH;
11653 lstrcpyA(patch, "apple");
11654 lstrcpyA(transforms, "banana");
11655 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11657 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11658 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11659 ok(!lstrcmpA(patch, "apple"),
11660 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11661 ok(!lstrcmpA(transforms, "banana"),
11662 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11663 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11664
11665 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
11666 (const BYTE *)patch_squashed,
11667 lstrlenA(patch_squashed) + 1);
11668 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11669
11670 /* Patches value exists, is not REG_MULTI_SZ */
11671 size = MAX_PATH;
11672 lstrcpyA(patch, "apple");
11673 lstrcpyA(transforms, "banana");
11674 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11676 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11677 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11678 ok(!lstrcmpA(patch, "apple"),
11679 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11680 ok(!lstrcmpA(transforms, "banana"),
11681 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11682 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11683
11684 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11685 (const BYTE *)"a\0b\0c\0\0", 7);
11686 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11687
11688 /* Patches value exists, is not a squashed guid */
11689 size = MAX_PATH;
11690 lstrcpyA(patch, "apple");
11691 lstrcpyA(transforms, "banana");
11692 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11694 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
11695 ok(!lstrcmpA(patch, "apple"),
11696 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11697 ok(!lstrcmpA(transforms, "banana"),
11698 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11699 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11700
11701 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
11702 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
11703 (const BYTE *)patch_squashed,
11704 lstrlenA(patch_squashed) + 2);
11705 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11706
11707 /* Patches value exists */
11708 size = MAX_PATH;
11709 lstrcpyA(patch, "apple");
11710 lstrcpyA(transforms, "banana");
11711 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11713 broken(r == ERROR_FILE_NOT_FOUND), /* Windows Installer < 3.0 */
11714 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11715 ok(!lstrcmpA(patch, "apple") ||
11716 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11717 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11718 ok(!lstrcmpA(transforms, "banana"),
11719 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11720 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11721
11722 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
11723 (const BYTE *)"whatever", 9);
11724 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11725
11726 /* patch code value exists */
11727 size = MAX_PATH;
11728 lstrcpyA(patch, "apple");
11729 lstrcpyA(transforms, "banana");
11730 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11731 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11732 ok(!lstrcmpA(patch, patchcode),
11733 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11734 ok(!lstrcmpA(transforms, "whatever"),
11735 "Expected \"whatever\", got \"%s\"\n", transforms);
11736 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
11737
11738 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
11739 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
11740 lstrcatA(keypath, prod_squashed);
11741
11742 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
11743 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11744
11745 /* local UserData product key exists */
11746 size = MAX_PATH;
11747 lstrcpyA(patch, "apple");
11748 lstrcpyA(transforms, "banana");
11749 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11750 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11751 ok(!lstrcmpA(patch, patchcode),
11752 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11753 ok(!lstrcmpA(transforms, "whatever"),
11754 "Expected \"whatever\", got \"%s\"\n", transforms);
11755 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
11756
11757 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
11758 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11759
11760 /* local UserData Patches key exists */
11761 size = MAX_PATH;
11762 lstrcpyA(patch, "apple");
11763 lstrcpyA(transforms, "banana");
11764 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11765 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11766 ok(!lstrcmpA(patch, patchcode),
11767 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11768 ok(!lstrcmpA(transforms, "whatever"),
11769 "Expected \"whatever\", got \"%s\"\n", transforms);
11770 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
11771
11772 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
11773 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11774
11775 /* local UserData Product patch key exists */
11776 size = MAX_PATH;
11777 lstrcpyA(patch, "apple");
11778 lstrcpyA(transforms, "banana");
11779 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11781 broken(r == ERROR_SUCCESS), /* Windows Installer < 3.0 */
11782 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
11783 ok(!lstrcmpA(patch, "apple") ||
11784 broken(!lstrcmpA(patch, patchcode)), /* Windows Installer < 3.0 */
11785 "Expected lpPatchBuf to be unchanged, got \"%s\"\n", patch);
11786 ok(!lstrcmpA(transforms, "banana") ||
11787 broken(!lstrcmpA(transforms, "whatever")), /* Windows Installer < 3.0 */
11788 "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
11789 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11790
11792 res = RegSetValueExA(hpatch, "State", 0, REG_DWORD,
11793 (const BYTE *)&data, sizeof(DWORD));
11794 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
11795
11796 /* State value exists */
11797 size = MAX_PATH;
11798 lstrcpyA(patch, "apple");
11799 lstrcpyA(transforms, "banana");
11800 r = MsiEnumPatchesA(prodcode, 0, patch, transforms, &size);
11801 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11802 ok(!lstrcmpA(patch, patchcode),
11803 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11804 ok(!lstrcmpA(transforms, "whatever"),
11805 "Expected \"whatever\", got \"%s\"\n", transforms);
11806 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
11807
11808 /* now duplicate some of the tests for the W version */
11809
11810 /* pcchTransformsBuf is too small */
11811 size = 6;
11812 MultiByteToWideChar( CP_ACP, 0, prodcode, -1, prodcodeW, MAX_PATH );
11813 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
11814 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
11815 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
11816 ok(r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
11817 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
11818 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
11819 ok(!lstrcmpA(patch, patchcode),
11820 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11821 ok(!lstrcmpA(transforms, "whate") ||
11822 broken(!lstrcmpA(transforms, "banana")), /* Windows Installer < 3.0 */
11823 "Expected \"whate\", got \"%s\"\n", transforms);
11824 ok(size == 8, "Expected 8, got %lu\n", size);
11825
11826 /* patch code value exists */
11827 size = MAX_PATH;
11828 MultiByteToWideChar( CP_ACP, 0, "apple", -1, patchW, MAX_PATH );
11829 MultiByteToWideChar( CP_ACP, 0, "banana", -1, transformsW, MAX_PATH );
11830 r = MsiEnumPatchesW(prodcodeW, 0, patchW, transformsW, &size);
11831 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
11832 WideCharToMultiByte( CP_ACP, 0, patchW, -1, patch, MAX_PATH, NULL, NULL );
11833 WideCharToMultiByte( CP_ACP, 0, transformsW, -1, transforms, MAX_PATH, NULL, NULL );
11834 ok(!lstrcmpA(patch, patchcode),
11835 "Expected \"%s\", got \"%s\"\n", patchcode, patch);
11836 ok(!lstrcmpA(transforms, "whatever"),
11837 "Expected \"whatever\", got \"%s\"\n", transforms);
11838 ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %lu\n", size);
11839
11840 RegDeleteValueA(patches, patch_squashed);
11841 RegDeleteValueA(patches, "Patches");
11842 delete_key(patches, "", access & KEY_WOW64_64KEY);
11843 RegCloseKey(patches);
11844 RegDeleteValueA(hpatch, "State");
11845 delete_key(hpatch, "", access & KEY_WOW64_64KEY);
11846 RegCloseKey(hpatch);
11847 delete_key(udpatch, "", access & KEY_WOW64_64KEY);
11848 RegCloseKey(udpatch);
11849 delete_key(udprod, "", access & KEY_WOW64_64KEY);
11850 RegCloseKey(udprod);
11851 delete_key(prodkey, "", access & KEY_WOW64_64KEY);
11852 RegCloseKey(prodkey);
11853 LocalFree(usersid);
11854}
#define broken(x)
Definition: _sntprintf.h:21
#define ERROR_MORE_DATA
Definition: dderror.h:13
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1179
UINT WINAPI MsiEnumPatchesW(const WCHAR *szProduct, DWORD iPatchIndex, WCHAR *lpPatchBuf, WCHAR *lpTransformsBuf, DWORD *pcchTransformsBuf)
Definition: registry.c:2070
UINT WINAPI MsiEnumPatchesA(const char *szProduct, DWORD iPatchIndex, char *lpPatchBuf, char *lpTransformsBuf, DWORD *pcchTransformsBuf)
Definition: registry.c:2016
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
@ MSIPATCHSTATE_APPLIED
Definition: msi.h:54
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define REG_DWORD
Definition: sdbapi.c:596
#define ERROR_BAD_CONFIGURATION
Definition: winerror.h:968
#define HKEY_CURRENT_USER
Definition: winreg.h:11

Referenced by START_TEST().

◆ test_MsiEnumPatchesEx()

static void test_MsiEnumPatchesEx ( void  )
static

Definition at line 10887 of file msi.c.

10888{
10889 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10890 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10891 CHAR patchcode[MAX_PATH];
10893 LPSTR usersid;
10894 DWORD size;
10895 UINT r;
10896
10897 if (!pMsiEnumPatchesExA)
10898 {
10899 win_skip("MsiEnumPatchesExA not implemented\n");
10900 return;
10901 }
10902
10903 create_test_guid(prodcode, prod_squashed);
10904 usersid = get_user_sid();
10905
10906 /* empty szProductCode */
10907 lstrcpyA(patchcode, "apple");
10908 lstrcpyA(targetprod, "banana");
10909 context = 0xdeadbeef;
10910 lstrcpyA(targetsid, "kiwi");
10911 size = MAX_PATH;
10912 r = pMsiEnumPatchesExA("", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10913 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
10914 targetsid, &size);
10916 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10917 ok(!lstrcmpA(patchcode, "apple"),
10918 "Expected patchcode to be unchanged, got %s\n", patchcode);
10919 ok(!lstrcmpA(targetprod, "banana"),
10920 "Expected targetprod to be unchanged, got %s\n", targetprod);
10921 ok(context == 0xdeadbeef,
10922 "Expected context to be unchanged, got %d\n", context);
10923 ok(!lstrcmpA(targetsid, "kiwi"),
10924 "Expected targetsid to be unchanged, got %s\n", targetsid);
10925 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10926
10927 /* garbage szProductCode */
10928 lstrcpyA(patchcode, "apple");
10929 lstrcpyA(targetprod, "banana");
10930 context = 0xdeadbeef;
10931 lstrcpyA(targetsid, "kiwi");
10932 size = MAX_PATH;
10933 r = pMsiEnumPatchesExA("garbage", usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
10934 MSIPATCHSTATE_ALL, 0, patchcode, targetprod, &context,
10935 targetsid, &size);
10937 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10938 ok(!lstrcmpA(patchcode, "apple"),
10939 "Expected patchcode to be unchanged, got %s\n", patchcode);
10940 ok(!lstrcmpA(targetprod, "banana"),
10941 "Expected targetprod to be unchanged, got %s\n", targetprod);
10942 ok(context == 0xdeadbeef,
10943 "Expected context to be unchanged, got %d\n", context);
10944 ok(!lstrcmpA(targetsid, "kiwi"),
10945 "Expected targetsid to be unchanged, got %s\n", targetsid);
10946 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10947
10948 /* guid without brackets */
10949 lstrcpyA(patchcode, "apple");
10950 lstrcpyA(targetprod, "banana");
10951 context = 0xdeadbeef;
10952 lstrcpyA(targetsid, "kiwi");
10953 size = MAX_PATH;
10954 r = pMsiEnumPatchesExA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", usersid,
10956 0, patchcode, targetprod, &context,
10957 targetsid, &size);
10959 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
10960 ok(!lstrcmpA(patchcode, "apple"),
10961 "Expected patchcode to be unchanged, got %s\n", patchcode);
10962 ok(!lstrcmpA(targetprod, "banana"),
10963 "Expected targetprod to be unchanged, got %s\n", targetprod);
10964 ok(context == 0xdeadbeef,
10965 "Expected context to be unchanged, got %d\n", context);
10966 ok(!lstrcmpA(targetsid, "kiwi"),
10967 "Expected targetsid to be unchanged, got %s\n", targetsid);
10968 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10969
10970 /* guid with brackets */
10971 lstrcpyA(patchcode, "apple");
10972 lstrcpyA(targetprod, "banana");
10973 context = 0xdeadbeef;
10974 lstrcpyA(targetsid, "kiwi");
10975 size = MAX_PATH;
10976 r = pMsiEnumPatchesExA("{6700E8CF-95AB-4D9C-BC2C-15840DDA7A5D}", usersid,
10978 0, patchcode, targetprod, &context,
10979 targetsid, &size);
10981 "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10982 ok(!lstrcmpA(patchcode, "apple"),
10983 "Expected patchcode to be unchanged, got %s\n", patchcode);
10984 ok(!lstrcmpA(targetprod, "banana"),
10985 "Expected targetprod to be unchanged, got %s\n", targetprod);
10986 ok(context == 0xdeadbeef,
10987 "Expected context to be unchanged, got %d\n", context);
10988 ok(!lstrcmpA(targetsid, "kiwi"),
10989 "Expected targetsid to be unchanged, got %s\n", targetsid);
10990 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10991
10992 /* szUserSid is S-1-5-18 */
10993 lstrcpyA(patchcode, "apple");
10994 lstrcpyA(targetprod, "banana");
10995 context = 0xdeadbeef;
10996 lstrcpyA(targetsid, "kiwi");
10997 size = MAX_PATH;
10998 r = pMsiEnumPatchesExA(prodcode, "S-1-5-18",
11000 0, patchcode, targetprod, &context,
11001 targetsid, &size);
11003 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11004 ok(!lstrcmpA(patchcode, "apple"),
11005 "Expected patchcode to be unchanged, got %s\n", patchcode);
11006 ok(!lstrcmpA(targetprod, "banana"),
11007 "Expected targetprod to be unchanged, got %s\n", targetprod);
11008 ok(context == 0xdeadbeef,
11009 "Expected context to be unchanged, got %d\n", context);
11010 ok(!lstrcmpA(targetsid, "kiwi"),
11011 "Expected targetsid to be unchanged, got %s\n", targetsid);
11012 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11013
11014 /* dwContext is MSIINSTALLCONTEXT_MACHINE, but szUserSid is non-NULL */
11015 lstrcpyA(patchcode, "apple");
11016 lstrcpyA(targetprod, "banana");
11017 context = 0xdeadbeef;
11018 lstrcpyA(targetsid, "kiwi");
11019 size = MAX_PATH;
11020 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_MACHINE,
11021 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11022 &context, targetsid, &size);
11024 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11025 ok(!lstrcmpA(patchcode, "apple"),
11026 "Expected patchcode to be unchanged, got %s\n", patchcode);
11027 ok(!lstrcmpA(targetprod, "banana"),
11028 "Expected targetprod to be unchanged, got %s\n", targetprod);
11029 ok(context == 0xdeadbeef,
11030 "Expected context to be unchanged, got %d\n", context);
11031 ok(!lstrcmpA(targetsid, "kiwi"),
11032 "Expected targetsid to be unchanged, got %s\n", targetsid);
11033 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11034
11035 /* dwContext is out of bounds */
11036 lstrcpyA(patchcode, "apple");
11037 lstrcpyA(targetprod, "banana");
11038 context = 0xdeadbeef;
11039 lstrcpyA(targetsid, "kiwi");
11040 size = MAX_PATH;
11041 r = pMsiEnumPatchesExA(prodcode, usersid, 0,
11042 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11043 &context, targetsid, &size);
11045 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11046 ok(!lstrcmpA(patchcode, "apple"),
11047 "Expected patchcode to be unchanged, got %s\n", patchcode);
11048 ok(!lstrcmpA(targetprod, "banana"),
11049 "Expected targetprod to be unchanged, got %s\n", targetprod);
11050 ok(context == 0xdeadbeef,
11051 "Expected context to be unchanged, got %d\n", context);
11052 ok(!lstrcmpA(targetsid, "kiwi"),
11053 "Expected targetsid to be unchanged, got %s\n", targetsid);
11054 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11055
11056 /* dwContext is out of bounds */
11057 lstrcpyA(patchcode, "apple");
11058 lstrcpyA(targetprod, "banana");
11059 context = 0xdeadbeef;
11060 lstrcpyA(targetsid, "kiwi");
11061 size = MAX_PATH;
11062 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_ALL + 1,
11063 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11064 &context, targetsid, &size);
11066 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11067 ok(!lstrcmpA(patchcode, "apple"),
11068 "Expected patchcode to be unchanged, got %s\n", patchcode);
11069 ok(!lstrcmpA(targetprod, "banana"),
11070 "Expected targetprod to be unchanged, got %s\n", targetprod);
11071 ok(context == 0xdeadbeef,
11072 "Expected context to be unchanged, got %d\n", context);
11073 ok(!lstrcmpA(targetsid, "kiwi"),
11074 "Expected targetsid to be unchanged, got %s\n", targetsid);
11075 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11076
11077 /* dwFilter is out of bounds */
11078 lstrcpyA(patchcode, "apple");
11079 lstrcpyA(targetprod, "banana");
11080 context = 0xdeadbeef;
11081 lstrcpyA(targetsid, "kiwi");
11082 size = MAX_PATH;
11083 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
11084 MSIPATCHSTATE_INVALID, 0, patchcode, targetprod,
11085 &context, targetsid, &size);
11087 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11088 ok(!lstrcmpA(patchcode, "apple"),
11089 "Expected patchcode to be unchanged, got %s\n", patchcode);
11090 ok(!lstrcmpA(targetprod, "banana"),
11091 "Expected targetprod to be unchanged, got %s\n", targetprod);
11092 ok(context == 0xdeadbeef,
11093 "Expected context to be unchanged, got %d\n", context);
11094 ok(!lstrcmpA(targetsid, "kiwi"),
11095 "Expected targetsid to be unchanged, got %s\n", targetsid);
11096 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11097
11098 /* dwFilter is out of bounds */
11099 lstrcpyA(patchcode, "apple");
11100 lstrcpyA(targetprod, "banana");
11101 context = 0xdeadbeef;
11102 lstrcpyA(targetsid, "kiwi");
11103 size = MAX_PATH;
11104 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
11105 MSIPATCHSTATE_ALL + 1, 0, patchcode, targetprod,
11106 &context, targetsid, &size);
11108 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11109 ok(!lstrcmpA(patchcode, "apple"),
11110 "Expected patchcode to be unchanged, got %s\n", patchcode);
11111 ok(!lstrcmpA(targetprod, "banana"),
11112 "Expected targetprod to be unchanged, got %s\n", targetprod);
11113 ok(context == 0xdeadbeef,
11114 "Expected context to be unchanged, got %d\n", context);
11115 ok(!lstrcmpA(targetsid, "kiwi"),
11116 "Expected targetsid to be unchanged, got %s\n", targetsid);
11117 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
11118
11119 /* pcchTargetUserSid is NULL while szTargetUserSid is non-NULL */
11120 lstrcpyA(patchcode, "apple");
11121 lstrcpyA(targetprod, "banana");
11122 context = 0xdeadbeef;
11123 lstrcpyA(targetsid, "kiwi");
11124 r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERUNMANAGED,
11125 MSIPATCHSTATE_ALL, 0, patchcode, targetprod,
11126 &context, targetsid, NULL);
11128 "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
11129 ok(!lstrcmpA(patchcode, "apple"),
11130 "Expected patchcode to be unchanged, got %s\n", patchcode);
11131 ok(!lstrcmpA(targetprod, "banana"),
11132 "Expected targetprod to be unchanged, got %s\n", targetprod);
11133 ok(context == 0xdeadbeef,
11134 "Expected context to be unchanged, got %d\n", context);
11135 ok(!lstrcmpA(targetsid, "kiwi"),
11136 "Expected targetsid to be unchanged, got %s\n", targetsid);
11137
11138 test_MsiEnumPatchesEx_usermanaged(usersid, usersid);
11140 test_MsiEnumPatchesEx_usermanaged("S-1-2-34", "S-1-2-34");
11141 test_MsiEnumPatchesEx_userunmanaged(usersid, usersid);
11143 /* FIXME: Successfully test userunmanaged with a different user */
11145 LocalFree(usersid);
11146}
static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid)
Definition: msi.c:9363
static void test_MsiEnumPatchesEx_machine(void)
Definition: msi.c:10438
static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expectedsid)
Definition: msi.c:9970
@ MSIPATCHSTATE_ALL
Definition: msi.h:58
@ MSIPATCHSTATE_INVALID
Definition: msi.h:53

Referenced by START_TEST().

◆ test_MsiEnumPatchesEx_machine()

static void test_MsiEnumPatchesEx_machine ( void  )
static

Definition at line 10438 of file msi.c.

10439{
10440 CHAR keypath[MAX_PATH], patch[MAX_PATH];
10441 CHAR patch_squashed[MAX_PATH], patchcode[MAX_PATH];
10442 CHAR targetsid[MAX_PATH], targetprod[MAX_PATH];
10443 CHAR prodcode[MAX_PATH], prod_squashed[MAX_PATH];
10444 HKEY prodkey, patches, udprod, udpatch;
10445 HKEY hpatch;
10447 DWORD size, data;
10448 LONG res;
10449 UINT r;
10451
10452 create_test_guid(prodcode, prod_squashed);
10453 create_test_guid(patch, patch_squashed);
10454
10455 if (is_wow64)
10457
10458 /* MSIPATCHSTATE_APPLIED */
10459
10460 lstrcpyA(patchcode, "apple");
10461 lstrcpyA(targetprod, "banana");
10462 context = 0xdeadbeef;
10463 lstrcpyA(targetsid, "kiwi");
10464 size = MAX_PATH;
10465 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10466 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10467 &context, targetsid, &size);
10468 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10469 ok(!lstrcmpA(patchcode, "apple"),
10470 "Expected patchcode to be unchanged, got %s\n", patchcode);
10471 ok(!lstrcmpA(targetprod, "banana"),
10472 "Expected targetprod to be unchanged, got %s\n", targetprod);
10473 ok(context == 0xdeadbeef,
10474 "Expected context to be unchanged, got %d\n", context);
10475 ok(!lstrcmpA(targetsid, "kiwi"),
10476 "Expected targetsid to be unchanged, got %s\n", targetsid);
10477 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10478
10479 lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
10480 lstrcatA(keypath, prod_squashed);
10481
10482 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
10483 if (res == ERROR_ACCESS_DENIED)
10484 {
10485 skip("Not enough rights to perform tests\n");
10486 return;
10487 }
10488 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10489
10490 /* local product key exists */
10491 lstrcpyA(patchcode, "apple");
10492 lstrcpyA(targetprod, "banana");
10493 context = 0xdeadbeef;
10494 lstrcpyA(targetsid, "kiwi");
10495 size = MAX_PATH;
10496 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10497 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10498 &context, targetsid, &size);
10499 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10500 ok(!lstrcmpA(patchcode, "apple"),
10501 "Expected patchcode to be unchanged, got %s\n", patchcode);
10502 ok(!lstrcmpA(targetprod, "banana"),
10503 "Expected targetprod to be unchanged, got %s\n", targetprod);
10504 ok(context == 0xdeadbeef,
10505 "Expected context to be unchanged, got %d\n", context);
10506 ok(!lstrcmpA(targetsid, "kiwi"),
10507 "Expected targetsid to be unchanged, got %s\n", targetsid);
10508 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10509
10510 res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
10511 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10512
10513 /* Patches key exists */
10514 lstrcpyA(patchcode, "apple");
10515 lstrcpyA(targetprod, "banana");
10516 context = 0xdeadbeef;
10517 lstrcpyA(targetsid, "kiwi");
10518 size = MAX_PATH;
10519 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10520 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10521 &context, targetsid, &size);
10522 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10523 ok(!lstrcmpA(patchcode, "apple"),
10524 "Expected patchcode to be unchanged, got %s\n", patchcode);
10525 ok(!lstrcmpA(targetprod, "banana"),
10526 "Expected targetprod to be unchanged, got %s\n", targetprod);
10527 ok(context == 0xdeadbeef,
10528 "Expected context to be unchanged, got %d\n", context);
10529 ok(!lstrcmpA(targetsid, "kiwi"),
10530 "Expected targetsid to be unchanged, got %s\n", targetsid);
10531 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10532
10533 res = RegSetValueExA(patches, "Patches", 0, REG_SZ,
10534 (const BYTE *)patch_squashed,
10535 lstrlenA(patch_squashed) + 1);
10536 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10537
10538 /* Patches value exists, is not REG_MULTI_SZ */
10539 lstrcpyA(patchcode, "apple");
10540 lstrcpyA(targetprod, "banana");
10541 context = 0xdeadbeef;
10542 lstrcpyA(targetsid, "kiwi");
10543 size = MAX_PATH;
10544 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10545 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10546 &context, targetsid, &size);
10548 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10549 ok(!lstrcmpA(patchcode, "apple"),
10550 "Expected patchcode to be unchanged, got %s\n", patchcode);
10551 ok(!lstrcmpA(targetprod, "banana"),
10552 "Expected targetprod to be unchanged, got %s\n", targetprod);
10553 ok(context == 0xdeadbeef,
10554 "Expected context to be unchanged, got %d\n", context);
10555 ok(!lstrcmpA(targetsid, "kiwi"),
10556 "Expected targetsid to be unchanged, got %s\n", targetsid);
10557 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10558
10559 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10560 (const BYTE *)"a\0b\0c\0\0", 7);
10561 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10562
10563 /* Patches value exists, is not a squashed guid */
10564 lstrcpyA(patchcode, "apple");
10565 lstrcpyA(targetprod, "banana");
10566 context = 0xdeadbeef;
10567 lstrcpyA(targetsid, "kiwi");
10568 size = MAX_PATH;
10569 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10570 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10571 &context, targetsid, &size);
10573 "Expected ERROR_BAD_CONFIGURATION, got %d\n", r);
10574 ok(!lstrcmpA(patchcode, "apple"),
10575 "Expected patchcode to be unchanged, got %s\n", patchcode);
10576 ok(!lstrcmpA(targetprod, "banana"),
10577 "Expected targetprod to be unchanged, got %s\n", targetprod);
10578 ok(context == 0xdeadbeef,
10579 "Expected context to be unchanged, got %d\n", context);
10580 ok(!lstrcmpA(targetsid, "kiwi"),
10581 "Expected targetsid to be unchanged, got %s\n", targetsid);
10582 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10583
10584 patch_squashed[lstrlenA(patch_squashed) + 1] = '\0';
10585 res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
10586 (const BYTE *)patch_squashed,
10587 lstrlenA(patch_squashed) + 2);
10588 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10589
10590 /* Patches value exists */
10591 lstrcpyA(patchcode, "apple");
10592 lstrcpyA(targetprod, "banana");
10593 context = 0xdeadbeef;
10594 lstrcpyA(targetsid, "kiwi");
10595 size = MAX_PATH;
10596 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10597 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10598 &context, targetsid, &size);
10599 ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
10600 ok(!lstrcmpA(patchcode, "apple"),
10601 "Expected patchcode to be unchanged, got %s\n", patchcode);
10602 ok(!lstrcmpA(targetprod, "banana"),
10603 "Expected targetprod to be unchanged, got %s\n", targetprod);
10604 ok(context == 0xdeadbeef,
10605 "Expected context to be unchanged, got %d\n", context);
10606 ok(!lstrcmpA(targetsid, "kiwi"),
10607 "Expected targetsid to be unchanged, got %s\n", targetsid);
10608 ok(size == MAX_PATH, "Expected size to be unchanged, got %lu\n", size);
10609
10610 res = RegSetValueExA(patches, patch_squashed, 0, REG_SZ,
10611 (const BYTE *)"whatever", 9);
10612 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10613
10614 /* patch code value exists */
10615 lstrcpyA(patchcode, "apple");
10616 lstrcpyA(targetprod, "banana");
10617 context = 0xdeadbeef;
10618 lstrcpyA(targetsid, "kiwi");
10619 size = MAX_PATH;
10620 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10621 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10622 &context, targetsid, &size);
10623 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10624 ok(!lstrcmpA(patchcode, patch),
10625 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10626 ok(!lstrcmpA(targetprod, prodcode),
10627 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10629 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10630 ok(!lstrcmpA(targetsid, ""), "Expected \"\", got \"%s\"\n", targetsid);
10631 ok(size == 0, "Expected 0, got %lu\n", size);
10632
10633 lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
10634 lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
10635 lstrcatA(keypath, prod_squashed);
10636
10637 res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
10638 if (res == ERROR_ACCESS_DENIED)
10639 {
10640 skip("Not enough rights to perform tests\n");
10641 goto done;
10642 }
10643 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10644
10645 /* local UserData product key exists */
10646 lstrcpyA(patchcode, "apple");
10647 lstrcpyA(targetprod, "banana");
10648 context = 0xdeadbeef;
10649 lstrcpyA(targetsid, "kiwi");
10650 size = MAX_PATH;
10651 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10652 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10653 &context, targetsid, &size);
10654 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10655 ok(!lstrcmpA(patchcode, patch),
10656 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10657 ok(!lstrcmpA(targetprod, prodcode),
10658 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10660 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10661 ok(!lstrcmpA(targetsid, ""),
10662 "Expected \"\", got \"%s\"\n", targetsid);
10663 ok(size == 0, "Expected 0, got %lu\n", size);
10664
10665 res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
10666 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10667
10668 /* local UserData Patches key exists */
10669 lstrcpyA(patchcode, "apple");
10670 lstrcpyA(targetprod, "banana");
10671 context = 0xdeadbeef;
10672 lstrcpyA(targetsid, "kiwi");
10673 size = MAX_PATH;
10674 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10675 MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
10676 &context, targetsid, &size);
10677 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
10678 ok(!lstrcmpA(patchcode, patch),
10679 "Expected \"%s\", got \"%s\"\n", patch, patchcode);
10680 ok(!lstrcmpA(targetprod, prodcode),
10681 "Expected \"%s\", got \"%s\"\n", prodcode, targetprod);
10683 "Expected MSIINSTALLCONTEXT_MACHINE, got %d\n", context);
10684 ok(!lstrcmpA(targetsid, ""),
10685 "Expected \"\", got \"%s\"\n", targetsid);
10686 ok(size == 0, "Expected 0, got %lu\n", size);
10687
10688 res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
10689 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
10690
10691 /* local UserData Product patch key exists */
10692 lstrcpyA(patchcode, "apple");
10693 lstrcpyA(targetprod, "banana");
10694 context = 0xdeadbeef;
10695 lstrcpyA(targetsid, "kiwi");
10696 size = MAX_PATH;
10697 r = pMsiEnumPatchesExA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE,
10698 MSIPATCHSTATE_APPLIED, 0, patchcode, targe