ReactOS  0.4.15-dev-5112-g22d8c0f
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);
GLenum func
Definition: glext.h:6028
static HMODULE dll
Definition: str.c:188
#define GetProcAddress(x, y)
Definition: compat.h:612
GLfloat GLfloat p
Definition: glext.h:8902

◆ 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;
static char org[]
Definition: encode.c:7456
#define MAX_PATH
Definition: compat.h:34
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
uint32_t serial
Definition: fsck.fat.h:64
void user(int argc, const char *argv[])
Definition: cmds.c:1350

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;
127  HANDLE handle;
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 
142  handle = CreateFileW(cabinetW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
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 CloseHandle
Definition: compat.h:598
HRESULT hr
Definition: shlfolder.c:183
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923
#define TRUE
Definition: types.h:120
#define CP_ACP
Definition: compat.h:109
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
GLuint buffer
Definition: glext.h:5915
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define FALSE
Definition: types.h:117
#define STGM_WRITE
Definition: objbase.h:918
#define OPEN_EXISTING
Definition: compat.h:634
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
HRESULT WINAPI StgOpenStorage(const OLECHAR *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8755
#define STGM_DIRECT
Definition: objbase.h:914
#define MAX_PATH
Definition: compat.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
#define GENERIC_READ
Definition: compat.h:135
#define STGM_READWRITE
Definition: objbase.h:919
#define ReadFile(a, b, c, d, e)
Definition: compat.h:601
#define NULL
Definition: types.h:112
#define MultiByteToWideChar
Definition: compat.h:110
#define CreateFileW
Definition: compat.h:600

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 }
static void encode_base85_guid(GUID *guid, LPWSTR str)
Definition: msi.c:1580
#define WideCharToMultiByte
Definition: compat.h:111
HRESULT hr
Definition: shlfolder.c:183
#define CP_ACP
Definition: compat.h:109
const GUID * guid
GLsizeiptr size
Definition: glext.h:5919
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
#define MAX_PATH
Definition: compat.h:34
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
HRESULT WINAPI CoCreateGuid(GUID *pguid)
Definition: compobj.c:2206
#define S_OK
Definition: intsafe.h:52
#define ok(value,...)
Definition: atltest.h:57
DWORD size
Definition: msi.c:1103
#define NULL
Definition: types.h:112
static BOOL squash_guid(LPCWSTR in, LPWSTR out)
Definition: msi.c:1193

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 }
#define ERROR_SUCCESS
Definition: deptool.c:10
char CHAR
Definition: xmlstorage.h:175
#define sprintf(buf, format,...)
Definition: sprintf.c:55
unsigned long MSIHANDLE
Definition: winemsi.idl:24
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
static UINT set_summary_info(MSIHANDLE hdb, LPSTR prodcode)
Definition: msi.c:783
#define MAX_PATH
Definition: compat.h:34
#define MSIDBOPEN_CREATE
Definition: msiquery.h:69
static const char msifile[]
Definition: msi.c:41
static int run_query(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL recurse)
Definition: query.c:311
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:963
#define ok(value,...)
Definition: atltest.h:57
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
Definition: database.c:298
unsigned int UINT
Definition: ndis.h:50
GLuint res
Definition: glext.h:9613
static const WCHAR msifileW[]
Definition: msi.c:42

Referenced by test_MsiOpenProduct().

◆ 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 }
#define create_file(name, size)
Definition: asmcache.c:813
#define MEDIA_SIZE
Definition: msi.c:118
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
static void create_cab_file(void)
Definition: files.c:356
#define NULL
Definition: types.h:112

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

Definition at line 1225 of file msi.c.

1226 {
1227  WCHAR guidW[GUID_SIZE];
1228  WCHAR squashedW[SQUASHED_GUID_SIZE];
1229  GUID guid;
1230  HRESULT hr;
1231  int size;
1232 
1233  hr = CoCreateGuid(&guid);
1234  ok(hr == S_OK, "Expected S_OK, got %#lx\n", hr);
1235 
1236  size = StringFromGUID2(&guid, guidW, ARRAY_SIZE(guidW));
1237  ok(size == GUID_SIZE, "Expected %d, got %d.\n", GUID_SIZE, size);
1238 
1239  WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, GUID_SIZE, NULL, NULL);
1240  if (squashed)
1241  {
1242  squash_guid(guidW, squashedW);
1243  WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, SQUASHED_GUID_SIZE, NULL, NULL);
1244  }
1245 }
#define WideCharToMultiByte
Definition: compat.h:111
HRESULT hr
Definition: shlfolder.c:183
#define CP_ACP
Definition: compat.h:109
const GUID * guid
#define SQUASHED_GUID_SIZE
Definition: msi.c:38
GLsizeiptr size
Definition: glext.h:5919
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
HRESULT WINAPI CoCreateGuid(GUID *pguid)
Definition: compobj.c:2206
#define GUID_SIZE
Definition: msi.c:37
#define S_OK
Definition: intsafe.h:52
#define ARRAY_SIZE(a)
Definition: main.h:24
#define ok(value,...)
Definition: atltest.h:57
DWORD size
Definition: msi.c:1103
#define NULL
Definition: types.h:112
static BOOL squash_guid(LPCWSTR in, LPWSTR out)
Definition: msi.c:1193

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

◆ delete_key()

◆ 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 DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
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
static const char table_enc85[]
Definition: msi.c:1571
const GUID * guid
const WCHAR * str
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
GLfloat GLfloat p
Definition: glext.h:8902

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;
1251  TOKEN_USER *user;
1252  char *usersid = NULL;
1253 
1256 
1257  user = malloc(size);
1259  ConvertSidToStringSidA(user->User.Sid, &usersid);
1260  free(user);
1261 
1262  CloseHandle(token);
1263  return usersid;
1264 }
#define CloseHandle
Definition: compat.h:598
#define free
Definition: debug_ros.c:5
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
GLsizeiptr size
Definition: glext.h:5919
#define TOKEN_QUERY
Definition: setypes.h:924
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI ConvertSidToStringSidA(PSID Sid, LPSTR *StringSid)
Definition: security.c:3436
#define GetCurrentProcess()
Definition: compat.h:618
#define NULL
Definition: types.h:112
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:296
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:413
#define malloc
Definition: debug_ros.c:4
void user(int argc, const char *argv[])
Definition: cmds.c:1350

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 }
#define free
Definition: debug_ros.c:5
DWORD dwFileVersionLS
Definition: compat.h:762
BOOL WINAPI VerQueryValueA(LPCVOID pBlock, LPCSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:993
char * LPSTR
Definition: xmlstorage.h:182
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const WCHAR version[]
Definition: asmname.c:66
static const WCHAR lang[]
Definition: wbemdisp.c:287
GLsizeiptr size
Definition: glext.h:5919
DWORD WINAPI GetFileVersionInfoSizeA(LPCSTR filename, LPDWORD handle)
Definition: version.c:619
#define MAX_PATH
Definition: compat.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD dwFileVersionMS
Definition: compat.h:761
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
unsigned short USHORT
Definition: pedump.c:61
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define HIWORD(l)
Definition: typedefs.h:247
#define malloc
Definition: debug_ros.c:4
#define LOWORD(l)
Definition: pedump.c:82

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:824

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 }
#define IDOK
Definition: winuser.h:824

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 }
#define IDOK
Definition: winuser.h:824

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 }
INSTALLSTATE WINAPI MsiGetComponentPathExA(LPCSTR product, LPCSTR comp, LPCSTR usersid, MSIINSTALLCONTEXT ctx, LPSTR buf, LPDWORD buflen)
Definition: msi.c:2866
#define GET_PROC(dll, func)
LONG WINAPI RegDeleteKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ REGSAM samDesired, _In_ DWORD Reserved)
Definition: reg.c:1252
INSTALLSTATE WINAPI MsiUseFeatureExA(const char *szProduct, const char *szFeature, DWORD dwInstallMode, DWORD dwReserved)
Definition: msi.c:3309
UINT WINAPI MsiGetPatchInfoExA(LPCSTR szPatchCode, LPCSTR szProductCode, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCSTR szProperty, LPSTR lpValue, DWORD *pcchValue)
Definition: msi.c:1592
static HINSTANCE hkernel32
Definition: process.c:66
UINT WINAPI MsiProvideComponentW(const WCHAR *product, const WCHAR *feature, const WCHAR *component, DWORD mode, WCHAR *buf, DWORD *buflen)
Definition: msi.c:4252
INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR product, LPCSTR comp, LPSTR buf, LPDWORD buflen)
Definition: msi.c:2904
UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
Definition: package.c:1650
BOOL WINAPI IsWow64Process(IN HANDLE hProcess, OUT PBOOL Wow64Process)
Definition: proc.c:1975
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 MsiGetProductInfoExA(LPCSTR szProductCode, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCSTR szProperty, LPSTR szValue, LPDWORD pcchValue)
Definition: msi.c:1302
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
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
UINT WINAPI MsiProvideComponentA(const char *product, const char *feature, const char *component, DWORD mode, char *buf, DWORD *buflen)
Definition: msi.c:4204
UINT WINAPI MsiOpenPackageExW(const WCHAR *szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
Definition: package.c:1612
UINT WINAPI MsiGetFileHashA(const char *szFilePath, DWORD dwOptions, MSIFILEHASHINFO *pHash)
Definition: msi.c:4096
UINT WINAPI MsiSourceListGetInfoA(LPCSTR szProduct, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCSTR szProperty, LPSTR szValue, LPDWORD pcchValue)
Definition: source.c:470
UINT WINAPI MsiSetExternalUIRecord(INSTALLUI_HANDLER_RECORD handler, DWORD filter, void *context, INSTALLUI_HANDLER_RECORD *prev)
Definition: msi.c:4155
UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode, LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCSTR szComponent, INSTALLSTATE *pdwState)
Definition: msi.c:2057
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

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 }
Definition: compat.h:2157
#define ERROR_SUCCESS
Definition: deptool.c:10
#define PID_REVNUMBER
Definition: suminfo.c:51
static const CHAR suminfo[]
Definition: db.c:2206
unsigned long MSIHANDLE
Definition: winemsi.idl:24
UINT WINAPI MsiSummaryInfoSetPropertyA(MSIHANDLE handle, UINT uiProperty, UINT uiDataType, INT iValue, FILETIME *pftValue, const char *szValue)
Definition: suminfo.c:937
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase, const char *szDatabase, UINT uiUpdateCount, MSIHANDLE *pHandle)
Definition: suminfo.c:584
#define ok(value,...)
Definition: atltest.h:57
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
UINT WINAPI MsiSummaryInfoPersist(MSIHANDLE handle)
Definition: suminfo.c:1222
GLuint res
Definition: glext.h:9613

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 }
#define TRUE
Definition: types.h:120
GLdouble n
Definition: glext.h:7729
const GUID * guid
#define FALSE
Definition: types.h:117
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint in
Definition: glext.h:9616
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
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338

Referenced by compose_base85_guid(), create_test_guid(), MSI_GetComponentPath(), MSI_GetProductInfo(), MSI_GetUserInfo(), MsiGetPatchInfoExW(), MsiGetProductCodeW(), MsiGetProductInfoExW(), MsiOpenProductW(), MsiQueryComponentStateW(), MsiQueryFeatureStateExW(), and MsiQueryFeatureStateW().

◆ 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 
14608  len = lstrlenA(CURR_DIR);
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 
14615  test_usefeature();
14616  test_null();
14649  if (pMsiGetComponentPathExA)
14653 
14654  SetCurrentDirectoryA(prev_path);
14655 }
static void test_MsiGetFileVersion(void)
Definition: msi.c:4106
static void test_MsiGetProductInfo(void)
Definition: msi.c:4376
static void test_MsiProvideQualifiedComponentEx(void)
Definition: msi.c:3463
BOOL is_wow64
Definition: msi.c:54
static void test_MsiEnumClients(void)
Definition: msi.c:3882
static void test_MsiQueryComponentState(void)
Definition: msi.c:2113
static void test_MsiGetUserInfo(void)
Definition: msi.c:8440
int winetest_interactive
static void test_MsiGetFeatureInfo(void)
Definition: msi.c:13954
static void test_usefeature(void)
Definition: msi.c:873
static char CURR_DIR[MAX_PATH]
static void test_MsiSetFeatureAttributes(void)
Definition: msi.c:13872
static void test_MsiOpenProduct(void)
Definition: msi.c:9036
static void test_MsiQueryProductState(void)
Definition: msi.c:1266
static void test_MsiEnumComponentsEx(void)
Definition: msi.c:13482
static void test_MsiEnumProductsEx(void)
Definition: msi.c:13232
static void test_MsiGetPatchInfoEx(void)
Definition: msi.c:11856
static void test_MsiEnumPatches(void)
Definition: msi.c:11148
const char * winetest_platform
static void test_MsiGetProductCode(void)
Definition: msi.c:3603
static void test_MsiSetInternalUI(void)
Definition: msi.c:14052
static void test_lastusedsource(void)
Definition: msi.c:14132
static void test_MsiGetProductInfoEx(void)
Definition: msi.c:5673
static void test_MsiGetFileSignatureInformation(void)
Definition: msi.c:13189
static void test_MsiGetComponentPath(void)
Definition: msi.c:2503
#define MAX_PATH
Definition: compat.h:34
static void test_null(void)
Definition: msi.c:919
static void test_MsiConfigureProductEx(void)
Definition: msi.c:13587
unsigned long DWORD
Definition: ntddk_ex.h:95
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2206
GLenum GLsizei len
Definition: glext.h:6722
#define GetCurrentProcess()
Definition: compat.h:618
static void test_MsiGetComponentPathEx(void)
Definition: msi.c:3050
static void test_getcomponentpath(void)
Definition: msi.c:1024
static void test_MsiGetFileHash(void)
Definition: msi.c:1132
static void test_sourcedir_props(void)
Definition: msi.c:14309
static void test_MsiQueryFeatureState(void)
Definition: msi.c:1623
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
static void test_command_line_parsing(void)
Definition: msi.c:14424
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
static void test_MsiEnumComponents(void)
Definition: msi.c:13409
static void test_MsiEnumProducts(void)
Definition: msi.c:13093
static void init_functionpointers(void)
Definition: msi.c:81
#define ok(value,...)
Definition: atltest.h:57
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
BOOL get_system_dirs(void)
Definition: install.c:2423
#define skip(...)
Definition: atltest.h:64
static void test_MsiEnumPatchesEx(void)
Definition: msi.c:10887
static void test_concurrentinstall(void)
Definition: msi.c:14372
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static void test_MsiGetPatchInfo(void)
Definition: msi.c:12900
static void test_MsiProvideComponent(void)
Definition: msi.c:3377
static void test_MsiSetExternalUI(void)
Definition: msi.c:14069
static void test_setpropertyfolder(void)
Definition: msi.c:14254
char temp_path[MAX_PATH]
Definition: mspatcha.c:123

◆ 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 }
#define ERROR_SUCCESS
Definition: deptool.c:10
UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
Definition: msi.c:200
Definition: ftp_var.h:139
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define todo_wine
Definition: custom.c:79
char * cmd
Definition: vfdcmd.c:85
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2284
#define ERROR_INVALID_COMMAND_LINE
Definition: winerror.h:997
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
#define ERROR_INSTALL_FAILURE
Definition: winerror.h:961
static const msi_table cl_tables[]
Definition: msi.c:770
static const char msifile[]
Definition: msi.c:41
#define create_database(name, tables, num_tables)
Definition: utils.h:42
#define ARRAY_SIZE(a)
Definition: main.h:24
static void create_test_files(void)
Definition: msi.c:1064
#define ok(value,...)
Definition: atltest.h:57
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define skip(...)
Definition: atltest.h:64
static BOOL is_process_limited(void)
Definition: atl.c:113
static void delete_test_files(void)
Definition: msi.c:1084

Referenced by START_TEST().

◆ test_concurrentinstall()

static void test_concurrentinstall ( void  )
static

Definition at line 14372 of file msi.c.

14373 {
14374  UINT r;
14375  CHAR path[MAX_PATH];
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 
14415 error:
14416  DeleteFileA(path);
14418  DeleteFileA("msitest\\msitest\\augustus");
14419  DeleteFileA("msitest\\maximus");
14420  RemoveDirectoryA("msitest\\msitest");
14421  RemoveDirectoryA("msitest");
14422 }
#define ERROR_INSTALL_PACKAGE_REJECTED
Definition: winerror.h:983
#define ERROR_SUCCESS
Definition: deptool.c:10
static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
Definition: automation.c:414
#define error(str)
Definition: mkdosfs.c:1605
UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
Definition: msi.c:200
#define TRUE
Definition: types.h:120
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
char CHAR
Definition: xmlstorage.h:175
#define create_file(name, size)
Definition: asmcache.c:813
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2284
static char CURR_DIR[MAX_PATH]
#define FALSE
Definition: types.h:117
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
Definition: msi.c:948
#define MAX_PATH
Definition: compat.h:34
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
static const char msifile[]
Definition: msi.c:41
static const msi_table ci2_tables[]
Definition: msi.c:758
#define create_database(name, tables, num_tables)
Definition: utils.h:42
#define ARRAY_SIZE(a)
Definition: main.h:24
#define ok(value,...)
Definition: atltest.h:57
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define skip(...)
Definition: atltest.h:64
static BOOL is_process_limited(void)
Definition: atl.c:113
static const msi_table ci_tables[]
Definition: msi.c:745

Referenced by START_TEST().

◆ test_getcomponentpath()

static void test_getcomponentpath ( void  )
static

Definition at line 1024 of file msi.c.

1025 {
1026  INSTALLSTATE r;
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 }
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint buffer
Definition: glext.h:5915
unsigned long DWORD
Definition: ntddk_ex.h:95
int INSTALLSTATE
Definition: winemsi.idl:31
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112

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 
14245 error:
14246  delete_cab_files();
14247  DeleteFileA("msitest\\maximus");
14248  RemoveDirectoryA("msitest");
14249  DeleteFileA("msifile0.msi");
14250  DeleteFileA("msifile1.msi");
14251  DeleteFileA("msifile2.msi");
14252 }
#define ERROR_INSTALL_PACKAGE_REJECTED
Definition: winerror.h:983
#define INSTALLPROPERTY_LASTUSEDSOURCEA
Definition: msi.h:404
Definition: pdh_main.c:93
#define ERROR_SUCCESS
Definition: deptool.c:10
#define error(str)
Definition: mkdosfs.c:1605
UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
Definition: msi.c:200
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define create_file(name, size)
Definition: asmcache.c:813
#define MEDIA_SIZE
Definition: msi.c:118
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2284
static BOOL add_cabinet_storage(LPCSTR db, LPCSTR cabinet)
Definition: msi.c:121
static const msi_table lus2_tables[]
Definition: msi.c:690
static char CURR_DIR[MAX_PATH]
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
static void create_cab_file(void)
Definition: files.c:356
GLsizeiptr size
Definition: glext.h:5919
static const msi_table lus1_tables[]
Definition: msi.c:678
#define ERROR_UNKNOWN_PRODUCT
Definition: winerror.h:963
#define MAX_PATH
Definition: compat.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
#define create_database(name, tables, num_tables)
Definition: utils.h:42
static const msi_table lus0_tables[]
Definition: msi.c:666
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define ARRAY_SIZE(a)
Definition: main.h:24
#define ok(value,...)
Definition: atltest.h:57
DWORD size
Definition: msi.c:1103
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define skip(...)
Definition: atltest.h:64
#define win_skip
Definition: test.h:160
void delete_cab_files(void)
Definition: install.c:3097

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 
13751  res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
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 
13775  RegCloseKey(props);
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 
13801  res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &props);
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 
13817  res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &source);
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 
13862  RegCloseKey(props);
13863 
13864 error:
13865  DeleteFileA("msitest\\hydrogen");
13866  DeleteFileA("msitest\\helium");
13867  DeleteFileA("msitest\\lithium");
13868  RemoveDirectoryA("msitest");
13870 }
static const msi_table mcp_tables[]
Definition: msi.c:654
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
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:4027
#define ERROR_INSTALL_PACKAGE_REJECTED
Definition: winerror.h:983
#define ERROR_SUCCESS
Definition: deptool.c:10
static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
Definition: automation.c:414
BOOL is_wow64
Definition: msi.c:54
#define error(str)
Definition: mkdosfs.c:1605
UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
Definition: msi.c:200
#define TRUE
Definition: types.h:120
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
char CHAR
Definition: xmlstorage.h:175
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3321
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2284
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState, LPCSTR szCommandLine)
Definition: msi.c:918
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
GLsizeiptr size
Definition: glext.h:5919
#define ERROR_UNKNOWN_PRODUCT
Definition: winerror.h:963
#define MAX_PATH
Definition: compat.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
static const char msifile[]
Definition: msi.c:41
#define create_database(name, tables, num_tables)
Definition: utils.h:42
unsigned char BYTE
Definition: xxhash.c:193
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
static void create_file_data(LPCSTR name, LPCSTR data, DWORD size)
Definition: asmcache.c:795
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
#define ARRAY_SIZE(a)
Definition: main.h:24
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define ok(value,...)
Definition: atltest.h:57
DWORD size
Definition: msi.c:1103
ACCESS_MASK REGSAM
Definition: winreg.h:69
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
static BOOL pf_exists(const char *file)
Definition: custom.c:1406
#define skip(...)
Definition: atltest.h:64
#define ERROR_INSTALL_SOURCE_ABSENT
Definition: winerror.h:970
static const WCHAR props[]
Definition: wbemdisp.c:288
GLuint res
Definition: glext.h:9613
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4816
static BOOL is_process_limited(void)
Definition: atl.c:113
#define RegCloseKey(hKey)
Definition: registry.h:47
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22

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 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL is_wow64
Definition: msi.c:54
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
char CHAR
Definition: xmlstorage.h:175
static LONG delete_key(HKEY key, LPCSTR subkey, REGSAM access)
Definition: msi.c:912
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
#define todo_wine
Definition: custom.c:79
char * LPSTR
Definition: xmlstorage.h:182
static void compose_base85_guid(LPSTR component, LPSTR comp_base85, LPSTR squashed)
Definition: msi.c:1601
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
long LONG
Definition: pedump.c:60
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
#define MAX_PATH
Definition: compat.h:34
static char * get_user_sid(void)
Definition: msi.c:1247
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
unsigned char BYTE
Definition: xxhash.c:193
static void create_test_guid(LPSTR prodcode, LPSTR squashed)
Definition: msi.c:1225
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define ok(value,...)
Definition: atltest.h:57
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2319
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define ERROR_UNKNOWN_COMPONENT
Definition: winerror.h:965
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define skip(...)
Definition: atltest.h:64
GLuint res
Definition: glext.h:9613
UINT WINAPI MsiEnumClientsA(const char *szComponent, DWORD index, char *szProduct)
Definition: registry.c:1328
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4816
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:1029
#define RegCloseKey(hKey)
Definition: registry.h:47
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22

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 
13474 done:
13475  delete_key( key1, "", access );
13476  delete_key( key2, "", access );
13477  RegCloseKey( key1 );
13478  RegCloseKey( key2 );
13479  LocalFree( usersid );
13480 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
UINT WINAPI MsiEnumComponentsA(DWORD index, char *lpguid)
Definition: registry.c:1099
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
Definition: glext.h:10608
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL is_wow64
Definition: msi.c:54
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define TRUE
Definition: types.h:120
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static LONG delete_key(HKEY key, LPCSTR subkey, REGSAM access)
Definition: msi.c:912
const GUID * guid
#define FALSE
Definition: types.h:117
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint index
Definition: glext.h:6031
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
#define MAX_PATH
Definition: compat.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
static char * get_user_sid(void)
Definition: msi.c:1247
#define index(s, c)
Definition: various.h:29
static void create_test_guid(LPSTR prodcode, LPSTR squashed)
Definition: msi.c:1225
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define ok(value,...)
Definition: atltest.h:57
ACCESS_MASK REGSAM
Definition: winreg.h:69
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define skip(...)
Definition: atltest.h:64
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
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:1029
static BOOL is_process_limited(void)
Definition: atl.c:113
#define RegCloseKey(hKey)
Definition: registry.h:47
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

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 
13578 done:
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 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
Definition: glext.h:10608
#define ERROR_SUCCESS
Definition: deptool.c:10
enum tagMSIINSTALLCONTEXT MSIINSTALLCONTEXT
Definition: action.c:49
BOOL is_wow64
Definition: msi.c:54
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
Definition: http.c:7251
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static LONG delete_key(HKEY key, LPCSTR subkey, REGSAM access)
Definition: msi.c:912
FT_UInt sid
Definition: cffcmap.c:139
const GUID * guid
#define FALSE
Definition: types.h:117
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint index
Definition: glext.h:6031
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
#define MAX_PATH
Definition: compat.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
static char * get_user_sid(void)
Definition: msi.c:1247
_In_opt_ PVOID _In_ ULONG _In_ PVOID context
Definition: wdfdriver.h:113
#define index(s, c)
Definition: various.h:29
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: xxhash.c:193
static void create_test_guid(LPSTR prodcode, LPSTR squashed)
Definition: msi.c:1225
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define ok(value,...)
Definition: atltest.h:57
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2319
ACCESS_MASK REGSAM
Definition: winreg.h:69
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define skip(...)
Definition: atltest.h:64
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4816
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:1029
static BOOL is_process_limited(void)
Definition: atl.c:113
#define win_skip
Definition: test.h:160
#define RegCloseKey(hKey)
Definition: registry.h:47
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22

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);
11299  ok(r == ERROR_NO_MORE_ITEMS ||
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);
11355  ok(r == ERROR_NO_MORE_ITEMS ||
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);
11495  ok(r == ERROR_NO_MORE_ITEMS ||
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);
11551  ok(r == ERROR_NO_MORE_ITEMS ||
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);
11570  ok(r == ERROR_NO_MORE_ITEMS ||
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);
11656  ok(r == ERROR_NO_MORE_ITEMS ||
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);
11712  ok(r == ERROR_NO_MORE_ITEMS ||
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);
11780  ok(r == ERROR_NO_MORE_ITEMS ||
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 ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WideCharToMultiByte
Definition: compat.h:111
BOOL is_wow64
Definition: msi.c:54
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define CP_ACP
Definition: compat.h:109
#define HKEY_CURRENT_USER
Definition: winreg.h:11
char CHAR
Definition: xmlstorage.h:175
static LONG delete_key(HKEY key, LPCSTR subkey, REGSAM access)
Definition: msi.c:912
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
char * LPSTR
Definition: xmlstorage.h:182
UINT WINAPI MsiEnumPatchesW(const WCHAR *szProduct, DWORD iPatchIndex, WCHAR *lpPatchBuf, WCHAR *lpTransformsBuf, DWORD *pcchTransformsBuf)
Definition: registry.c:2070
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
long LONG
Definition: pedump.c:60
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1177
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
GLsizeiptr size
Definition: glext.h:5919
#define ERROR_BAD_CONFIGURATION
Definition: winerror.h:968
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ERROR_UNKNOWN_PRODUCT
Definition: winerror.h:963
#define MAX_PATH
Definition: compat.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
UINT WINAPI MsiEnumPatchesA(const char *szProduct, DWORD iPatchIndex, char *lpPatchBuf, char *lpTransformsBuf, DWORD *pcchTransformsBuf)
Definition: registry.c:2016
static char * get_user_sid(void)
Definition: msi.c:1247
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
#define ERROR_MORE_DATA
Definition: dderror.h:13
unsigned char BYTE
Definition: xxhash.c:193
#define broken(x)
Definition: _sntprintf.h:21
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1222
static void create_test_guid(LPSTR prodcode, LPSTR squashed)
Definition: msi.c:1225
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
LPCSTR data
Definition: msi.c:1102
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define ok(value,...)
Definition: atltest.h:57
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2319
DWORD size
Definition: msi.c:1103
ACCESS_MASK REGSAM
Definition: winreg.h:69
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define MultiByteToWideChar
Definition: compat.h:110
#define skip(...)
Definition: atltest.h:64
GLuint res
Definition: glext.h:9613
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4816
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:1029
#define REG_DWORD
Definition: sdbapi.c:596
#define RegCloseKey(hKey)
Definition: registry.h:47