ReactOS 0.4.15-dev-8393-g61b7fb9
automation.c File Reference
#include <stdio.h>
#include <initguid.h>
#include <windows.h>
#include <msiquery.h>
#include <msidefs.h>
#include <msi.h>
#include <fci.h>
#include <oaidl.h>
#include "wine/test.h"
Include dependency graph for automation.c:

Go to the source code of this file.

Classes

struct  _msi_table
 
struct  _msi_summary_info
 
struct  get_did_t
 

Macros

#define COBJMACROS
 
#define ADD_TABLE(x)   {#x".idt", x##_dat, sizeof(x##_dat)}
 
#define ADD_INFO_I2(property, iValue)   {property, VT_I2, iValue, NULL, NULL}
 
#define ADD_INFO_I4(property, iValue)   {property, VT_I4, iValue, NULL, NULL}
 
#define ADD_INFO_LPSTR(property, szValue)   {property, VT_LPSTR, 0, NULL, szValue}
 
#define ADD_INFO_FILETIME(property, pftValue)   {property, VT_FILETIME, 0, pftValue, NULL}
 
#define GET_PROC(dll, func)
 
#define ok_w2(format, szString1, szString2)
 
#define ok_w2n(format, szString1, szString2, len)
 
#define ok_aw(format, aString, wString)
 
#define ok_awplus(format, extra, aString, wString)
 
#define ok_exception(hr, szDescription)
 
#define TEST_SUMMARYINFO_PROPERTIES_MODIFIED   4
 

Typedefs

typedef struct _msi_table msi_table
 
typedef struct _msi_summary_info msi_summary_info
 

Functions

static LONG (WINAPI *pRegDeleteKeyExA)(HKEY
 
static BOOL (WINAPI *pIsWow64Process)(HANDLE
 
 DEFINE_GUID (GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
 
static void init_functionpointers (void)
 
static BOOL is_process_limited (void)
 
static LONG delete_key_portable (HKEY key, LPCSTR subkey, REGSAM access)
 
static void write_file (const CHAR *filename, const char *data, int data_size)
 
static void write_msi_summary_info (MSIHANDLE db, const msi_summary_info *info, int num_info)
 
static void create_database (const CHAR *name, const msi_table *tables, int num_tables, const msi_summary_info *info, int num_info)
 
static BOOL create_package (LPWSTR path)
 
static BOOL get_program_files_dir (LPSTR buf)
 
static void create_file (const CHAR *name, DWORD size)
 
static void create_test_files (void)
 
static BOOL delete_pf (const CHAR *rel_path, BOOL is_file)
 
static void delete_test_files (void)
 
static DISPID get_dispid (IDispatch *disp, const char *name)
 
static void test_dispid (void)
 
static void test_dispatch (void)
 
static HRESULT invoke (IDispatch *pDispatch, LPCSTR szName, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, VARTYPE vtResult)
 
static HRESULT Installer_CreateRecord (int count, IDispatch **pRecord)
 
static HRESULT Installer_RegistryValue (HKEY hkey, LPCWSTR szKey, VARIANT vValue, VARIANT *pVarResult, VARTYPE vtExpect)
 
static HRESULT Installer_RegistryValueE (HKEY hkey, LPCWSTR szKey, BOOL *pBool)
 
static HRESULT Installer_RegistryValueW (HKEY hkey, LPCWSTR szKey, LPCWSTR szValue, LPWSTR szString)
 
static HRESULT Installer_RegistryValueI (HKEY hkey, LPCWSTR szKey, int iValue, LPWSTR szString, VARTYPE vtResult)
 
static HRESULT Installer_OpenPackage (LPCWSTR szPackagePath, int options, IDispatch **pSession)
 
static HRESULT Installer_OpenDatabase (LPCWSTR szDatabasePath, int openmode, IDispatch **pDatabase)
 
static HRESULT Installer_InstallProduct (LPCWSTR szPackagePath, LPCWSTR szPropertyValues)
 
static HRESULT Installer_ProductState (LPCWSTR szProduct, int *pInstallState)
 
static HRESULT Installer_ProductInfo (LPCWSTR szProduct, LPCWSTR szAttribute, LPWSTR szString)
 
static HRESULT Installer_Products (IDispatch **pStringList)
 
static HRESULT Installer_RelatedProducts (LPCWSTR szProduct, IDispatch **pStringList)
 
static HRESULT Installer_VersionGet (LPWSTR szVersion)
 
static HRESULT Installer_UILevelPut (int level)
 
static HRESULT Installer_SummaryInformation (BSTR PackagePath, int UpdateCount, IDispatch **pSumInfo)
 
static HRESULT Session_Installer (IDispatch *pSession, IDispatch **pInst)
 
static HRESULT Session_PropertyGet (IDispatch *pSession, LPCWSTR szName, LPWSTR szReturn)
 
static HRESULT Session_PropertyPut (IDispatch *pSession, LPCWSTR szName, LPCWSTR szValue)
 
static HRESULT Session_LanguageGet (IDispatch *pSession, UINT *pLangId)
 
static HRESULT Session_ModeGet (IDispatch *pSession, int iFlag, VARIANT_BOOL *mode)
 
static HRESULT Session_ModePut (IDispatch *pSession, int iFlag, VARIANT_BOOL mode)
 
static HRESULT Session_Database (IDispatch *pSession, IDispatch **pDatabase)
 
static HRESULT Session_DoAction (IDispatch *pSession, LPCWSTR szAction, int *iReturn)
 
static HRESULT Session_EvaluateCondition (IDispatch *pSession, LPCWSTR szCondition, int *iReturn)
 
static HRESULT Session_Message (IDispatch *pSession, LONG kind, IDispatch *record, int *ret)
 
static HRESULT Session_SetInstallLevel (IDispatch *pSession, LONG iInstallLevel)
 
static HRESULT Session_FeatureCurrentState (IDispatch *pSession, LPCWSTR szName, int *pState)
 
static HRESULT Session_FeatureRequestStateGet (IDispatch *pSession, LPCWSTR szName, int *pState)
 
static HRESULT Session_FeatureRequestStatePut (IDispatch *pSession, LPCWSTR szName, int iState)
 
static HRESULT Database_OpenView (IDispatch *pDatabase, LPCWSTR szSql, IDispatch **pView)
 
static HRESULT Database_SummaryInformation (IDispatch *pDatabase, int iUpdateCount, IDispatch **pSummaryInfo)
 
static HRESULT View_Execute (IDispatch *pView, IDispatch *pRecord)
 
static HRESULT View_Fetch (IDispatch *pView, IDispatch **ppRecord)
 
static HRESULT View_Modify (IDispatch *pView, int iMode, IDispatch *pRecord)
 
static HRESULT View_Close (IDispatch *pView)
 
static HRESULT Record_FieldCountGet (IDispatch *pRecord, int *pFieldCount)
 
static HRESULT Record_StringDataGet (IDispatch *pRecord, int iField, LPWSTR szString)
 
static HRESULT Record_StringDataPut (IDispatch *pRecord, int iField, LPCWSTR szString)
 
static HRESULT Record_IntegerDataGet (IDispatch *pRecord, int iField, int *pValue)
 
static HRESULT Record_IntegerDataPut (IDispatch *pRecord, int iField, int iValue)
 
static HRESULT StringList__NewEnum (IDispatch *pList, IUnknown **ppEnumVARIANT)
 
static HRESULT StringList_Item (IDispatch *pStringList, int iIndex, LPWSTR szString)
 
static HRESULT StringList_Count (IDispatch *pStringList, int *pCount)
 
static HRESULT SummaryInfo_PropertyGet (IDispatch *pSummaryInfo, int pid, VARIANT *pVarResult, VARTYPE vtExpect)
 
static HRESULT SummaryInfo_PropertyPut (IDispatch *pSummaryInfo, int pid, VARIANT *pVariant)
 
static HRESULT SummaryInfo_PropertyCountGet (IDispatch *pSummaryInfo, int *pCount)
 
static void test_SummaryInfo (IDispatch *pSummaryInfo, const msi_summary_info *info, int num_info, BOOL readonly)
 
static void test_Database (IDispatch *pDatabase, BOOL readonly)
 
static void test_Session (IDispatch *pSession)
 
static DWORD delete_key (HKEY hkey)
 
static void test_Installer_RegistryValue (void)
 
static void test_Installer_Products (BOOL bProductInstalled)
 
static UINT delete_registry_key (HKEY hkeyParent, LPCSTR subkey, REGSAM access)
 
static UINT find_registry_key (HKEY hkeyParent, LPCSTR subkey, LPCSTR findkey, REGSAM access, HKEY *phkey)
 
static void test_Installer_InstallProduct (void)
 
static void test_Installer (void)
 
 START_TEST (automation)
 

Variables

static BOOL is_wow64
 
static LPCSTR
 
static REGSAM
 
static DWORD
 
static PBOOL
 
static const charmsifile = "winetest-automation.msi"
 
static FILETIME systemtime
 
static CHAR CURR_DIR [MAX_PATH]
 
static EXCEPINFO excepinfo
 
static IDispatchpInstaller
 
static const CHAR component_dat []
 
static const CHAR directory_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 registry_dat []
 
static const msi_table tables []
 
static const msi_summary_info summary_info []
 
static char PROG_FILES_DIR [MAX_PATH]
 
static CHAR string1 [MAX_PATH]
 
static CHAR string2 [MAX_PATH]
 
static const get_did_t get_did_data []
 
static int _invoke_todo_vtResult = 0
 

Macro Definition Documentation

◆ ADD_INFO_FILETIME

#define ADD_INFO_FILETIME (   property,
  pftValue 
)    {property, VT_FILETIME, 0, pftValue, NULL}

Definition at line 193 of file automation.c.

◆ ADD_INFO_I2

#define ADD_INFO_I2 (   property,
  iValue 
)    {property, VT_I2, iValue, NULL, NULL}

Definition at line 190 of file automation.c.

◆ ADD_INFO_I4

#define ADD_INFO_I4 (   property,
  iValue 
)    {property, VT_I4, iValue, NULL, NULL}

Definition at line 191 of file automation.c.

◆ ADD_INFO_LPSTR

#define ADD_INFO_LPSTR (   property,
  szValue 
)    {property, VT_LPSTR, 0, NULL, szValue}

Definition at line 192 of file automation.c.

◆ ADD_TABLE

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

Definition at line 166 of file automation.c.

◆ COBJMACROS

#define COBJMACROS

Definition at line 22 of file automation.c.

◆ GET_PROC

#define GET_PROC (   dll,
  func 
)
Value:
p ## func = (void *)GetProcAddress(dll, #func); \
if(!p ## func) \
trace("GetProcAddress(%s) failed\n", #func);
#define GetProcAddress(x, y)
Definition: compat.h:753
GLenum func
Definition: glext.h:6028
GLfloat GLfloat p
Definition: glext.h:8902
static HMODULE dll
Definition: str.c:188

◆ ok_aw

#define ok_aw (   format,
  aString,
  wString 
)
Value:
\
WideCharToMultiByte(CP_ACP, 0, wString, -1, string1, MAX_PATH, NULL, NULL); \
if (lstrcmpA(string1, aString) != 0) \
ok(0, format, string1, aString); \
#define NULL
Definition: types.h:112
#define CP_ACP
Definition: compat.h:109
#define MAX_PATH
Definition: compat.h:34
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4194
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static CHAR string1[MAX_PATH]
Definition: automation.c:449

Definition at line 469 of file automation.c.

◆ ok_awplus

#define ok_awplus (   format,
  extra,
  aString,
  wString 
)
Value:
\
WideCharToMultiByte(CP_ACP, 0, wString, -1, string1, MAX_PATH, NULL, NULL); \
if (lstrcmpA(string1, aString) != 0) \
ok(0, format, extra, string1, aString); \
@ extra
Definition: id3.c:95

Definition at line 475 of file automation.c.

◆ ok_exception

#define ok_exception (   hr,
  szDescription 
)
Value:
if (hr == DISP_E_EXCEPTION) \
{ \
/* Compare wtype, source, and destination */ \
ok(excepinfo.wCode == 1000, "Exception info was %d, expected 1000\n", excepinfo.wCode); \
\
ok(excepinfo.bstrSource != NULL, "Exception source was NULL\n"); \
if (excepinfo.bstrSource) \
ok_w2("Exception source was \"%s\" but expected to be \"%s\"\n", excepinfo.bstrSource, L"Msi API Error"); \
\
ok(excepinfo.bstrDescription != NULL, "Exception description was NULL\n"); \
if (excepinfo.bstrDescription) \
ok_w2("Exception description was \"%s\" but expected to be \"%s\"\n", excepinfo.bstrDescription, szDescription); \
\
SysFreeString(excepinfo.bstrSource); \
SysFreeString(excepinfo.bstrDescription); \
SysFreeString(excepinfo.bstrHelpFile); \
}
static const WCHAR szDescription[]
Definition: provider.c:55
static EXCEPINFO excepinfo
Definition: automation.c:50
#define L(x)
Definition: ntvdm.h:50
HRESULT hr
Definition: shlfolder.c:183
#define DISP_E_EXCEPTION
Definition: winerror.h:2518

Definition at line 482 of file automation.c.

◆ ok_w2

#define ok_w2 (   format,
  szString1,
  szString2 
)
Value:
\
do { \
WideCharToMultiByte(CP_ACP, 0, szString1, -1, string1, MAX_PATH, NULL, NULL); \
WideCharToMultiByte(CP_ACP, 0, szString2, -1, string2, MAX_PATH, NULL, NULL); \
if (lstrcmpA(string1, string2) != 0) \
ok(0, format, string1, string2); \
} while(0);
static CHAR string2[MAX_PATH]
Definition: automation.c:449

Definition at line 451 of file automation.c.

◆ ok_w2n

#define ok_w2n (   format,
  szString1,
  szString2,
  len 
)
Value:
\
if (memcmp(szString1, szString2, len * sizeof(WCHAR)) != 0) \
{ \
WideCharToMultiByte(CP_ACP, 0, szString1, -1, string1, MAX_PATH, NULL, NULL); \
WideCharToMultiByte(CP_ACP, 0, szString2, -1, string2, MAX_PATH, NULL, NULL); \
ok(0, format, string1, string2); \
}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
GLenum GLsizei len
Definition: glext.h:6722
__wchar_t WCHAR
Definition: xmlstorage.h:180

Definition at line 460 of file automation.c.

◆ TEST_SUMMARYINFO_PROPERTIES_MODIFIED

#define TEST_SUMMARYINFO_PROPERTIES_MODIFIED   4

Definition at line 1580 of file automation.c.

Typedef Documentation

◆ msi_summary_info

◆ msi_table

Function Documentation

◆ BOOL()

static BOOL ( WINAPI pIsWow64Process)
static

◆ create_database()

static void create_database ( const CHAR name,
const msi_table tables,
int  num_tables,
const msi_summary_info info,
int  num_info 
)
static

Definition at line 304 of file automation.c.

306{
307 MSIHANDLE db;
308 UINT r;
309 WCHAR *nameW;
310 int j, len;
311
312 len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
313 if (!(nameW = malloc( len * sizeof(WCHAR) ))) return;
315
317 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
318
319 /* import the tables into the database */
320 for (j = 0; j < num_tables; j++)
321 {
322 const msi_table *table = &tables[j];
323
324 write_file(table->filename, table->data, (table->size - 1) * sizeof(char));
325
326 r = MsiDatabaseImportA(db, CURR_DIR, table->filename);
327 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
328
329 DeleteFileA(table->filename);
330 }
331
332 write_msi_summary_info(db, info, num_info);
333
334 r = MsiDatabaseCommit(db);
335 ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
336
337 MsiCloseHandle(db);
338 free( nameW );
339}
#define ok(value,...)
Definition: atltest.h:57
static const WCHAR nameW[]
Definition: main.c:49
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define MultiByteToWideChar
Definition: compat.h:110
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
UINT WINAPI MsiDatabaseImportA(MSIHANDLE handle, const char *szFolder, const char *szFilename)
Definition: database.c:853
UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
Definition: database.c:298
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
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 GLint GLint j
Definition: glfuncs.h:250
static CHAR CURR_DIR[MAX_PATH]
Definition: automation.c:49
static const msi_table tables[]
Definition: automation.c:168
static void write_msi_summary_info(MSIHANDLE db, const msi_summary_info *info, int num_info)
Definition: automation.c:278
static void write_file(const CHAR *filename, const char *data, int data_size)
Definition: automation.c:268
UINT WINAPI MsiDatabaseCommit(MSIHANDLE hdb)
Definition: msiquery.c:963
#define MSIDBOPEN_CREATE
Definition: msiquery.h:69
unsigned int UINT
Definition: ndis.h:50
Definition: name.c:39
BYTE * data
unsigned long MSIHANDLE
Definition: winemsi.idl:27

◆ create_file()

static void create_file ( const CHAR name,
DWORD  size 
)
static

Definition at line 381 of file automation.c.

382{
383 HANDLE file;
384 DWORD written, left;
385
387 ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
388 WriteFile(file, name, strlen(name), &written, NULL);
389 WriteFile(file, "\n", strlen("\n"), &written, NULL);
390
391 left = size - lstrlenA(name) - 1;
392
395
397}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define CloseHandle
Definition: compat.h:739
#define SetFilePointer
Definition: compat.h:743
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1004
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
GLint left
Definition: glext.h:7726
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define CREATE_ALWAYS
Definition: disk.h:72
#define GENERIC_WRITE
Definition: nt_native.h:90
Definition: fci.c:127
#define FILE_CURRENT
Definition: winbase.h:113

◆ create_package()

static BOOL create_package ( LPWSTR  path)
static

Definition at line 341 of file automation.c.

342{
343 DWORD len;
344
345 /* Prepare package */
347
349 CURR_DIR, -1, path, MAX_PATH);
350 ok(len, "MultiByteToWideChar returned error %lu\n", GetLastError());
351 if (!len)
352 return FALSE;
353
354 lstrcatW(path, L"\\winetest-automation.msi");
355 return TRUE;
356}
#define ARRAY_SIZE(A)
Definition: main.h:33
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
static const msi_summary_info summary_info[]
Definition: automation.c:195
static const char * msifile
Definition: automation.c:47
#define create_database(name, tables, num_tables)
Definition: utils.h:42
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define MB_PRECOMPOSED
Definition: winnls.h:281

Referenced by test_dispatch(), and test_Installer().

◆ create_test_files()

static void create_test_files ( void  )
static

Definition at line 399 of file automation.c.

400{
401 CreateDirectoryA("msitest", NULL);
402 create_file("msitest\\one.txt", 100);
403 CreateDirectoryA("msitest\\first", NULL);
404 create_file("msitest\\first\\two.txt", 100);
405 CreateDirectoryA("msitest\\second", NULL);
406 create_file("msitest\\second\\three.txt", 100);
407 CreateDirectoryA("msitest\\cabout",NULL);
408 create_file("msitest\\cabout\\four.txt", 100);
409 CreateDirectoryA("msitest\\cabout\\new",NULL);
410 create_file("msitest\\cabout\\new\\five.txt", 100);
411 create_file("msitest\\filename", 100);
412}
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
#define create_file(name, size)
Definition: asmcache.c:813

Referenced by test_Installer_InstallProduct().

◆ Database_OpenView()

static HRESULT Database_OpenView ( IDispatch pDatabase,
LPCWSTR  szSql,
IDispatch **  pView 
)
static

Definition at line 1346 of file automation.c.

1347{
1348 VARIANT varresult;
1349 VARIANTARG vararg[1];
1350 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1351 HRESULT hr;
1352
1353 VariantInit(&vararg[0]);
1354 V_VT(&vararg[0]) = VT_BSTR;
1355 V_BSTR(&vararg[0]) = SysAllocString(szSql);
1356
1357 hr = invoke(pDatabase, "OpenView", DISPATCH_METHOD, &dispparams, &varresult, VT_DISPATCH);
1358 *pView = V_DISPATCH(&varresult);
1359 return hr;
1360}
@ VT_BSTR
Definition: compat.h:2303
@ VT_DISPATCH
Definition: compat.h:2304
static HRESULT invoke(IDispatch *pDispatch, LPCSTR szName, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, VARTYPE vtResult)
Definition: automation.c:840
struct stdole::DISPPARAMS DISPPARAMS
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
#define DISPATCH_METHOD
Definition: oleauto.h:1006
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_DISPATCH(A)
Definition: oleauto.h:239
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568

Referenced by test_Database().

◆ Database_SummaryInformation()

static HRESULT Database_SummaryInformation ( IDispatch pDatabase,
int  iUpdateCount,
IDispatch **  pSummaryInfo 
)
static

Definition at line 1362 of file automation.c.

1363{
1364 VARIANT varresult;
1365 VARIANTARG vararg[1];
1366 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1367 HRESULT hr;
1368
1369 VariantInit(&vararg[0]);
1370 V_VT(&vararg[0]) = VT_I4;
1371 V_I4(&vararg[0]) = iUpdateCount;
1372
1373 hr = invoke(pDatabase, "SummaryInformation", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_DISPATCH);
1374 *pSummaryInfo = V_DISPATCH(&varresult);
1375 return hr;
1376}
@ VT_I4
Definition: compat.h:2298
#define V_I4(A)
Definition: oleauto.h:247
#define DISPATCH_PROPERTYGET
Definition: oleauto.h:1007

Referenced by test_Database().

◆ DEFINE_GUID()

DEFINE_GUID ( GUID_NULL  ,
,
,
,
,
,
,
,
,
,
,
 
)

◆ delete_key()

static DWORD delete_key ( HKEY  hkey)
static

Definition at line 1998 of file automation.c.

1999{
2000 char name[MAX_PATH];
2001 DWORD ret;
2002
2003 while (!(ret = RegEnumKeyA(hkey, 0, name, sizeof(name))))
2004 {
2005 HKEY tmp;
2006 if (!(ret = RegOpenKeyExA( hkey, name, 0, KEY_ENUMERATE_SUB_KEYS, &tmp )))
2007 {
2008 ret = delete_key( tmp );
2009 RegCloseKey( tmp );
2010 }
2011 if (ret) break;
2012 }
2013 if (ret != ERROR_NO_MORE_ITEMS) return ret;
2014 RegDeleteKeyA( hkey, "" );
2015 return 0;
2016}
#define RegCloseKey(hKey)
Definition: registry.h:49
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3298
LONG WINAPI RegEnumKeyA(HKEY hKey, DWORD dwIndex, LPSTR lpName, DWORD cbName)
Definition: reg.c:2368
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
#define delete_key(r, p, s)
Definition: reg_test.h:64
int ret

◆ delete_key_portable()

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

Definition at line 257 of file automation.c.

258{
259 if (pRegDeleteKeyExA)
260 return pRegDeleteKeyExA( key, subkey, access, 0 );
261 return RegDeleteKeyA( key, subkey );
262}
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
Definition: copy.c:22

Referenced by delete_registry_key(), and test_Installer_InstallProduct().

◆ delete_pf()

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

◆ delete_registry_key()

static UINT delete_registry_key ( HKEY  hkeyParent,
LPCSTR  subkey,
REGSAM  access 
)
static

Definition at line 2326 of file automation.c.

2327{
2328 UINT ret;
2329 CHAR *string = NULL;
2330 HKEY hkey;
2331 DWORD dwSize;
2332
2333 ret = RegOpenKeyExA(hkeyParent, subkey, 0, access, &hkey);
2334 if (ret != ERROR_SUCCESS) return ret;
2336 if (ret != ERROR_SUCCESS) return ret;
2337 if (!(string = malloc(++dwSize))) return ERROR_NOT_ENOUGH_MEMORY;
2338
2339 while (RegEnumKeyA(hkey, 0, string, dwSize) == ERROR_SUCCESS)
2340 delete_registry_key(hkey, string, access);
2341
2342 RegCloseKey(hkey);
2343 free(string);
2344 delete_key_portable(hkeyParent, subkey, access);
2345 return ERROR_SUCCESS;
2346}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
LONG WINAPI RegQueryInfoKeyA(HKEY hKey, LPSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3583
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
static UINT delete_registry_key(HKEY hkeyParent, LPCSTR subkey, REGSAM access)
Definition: automation.c:2326
static LONG delete_key_portable(HKEY key, LPCSTR subkey, REGSAM access)
Definition: automation.c:257

Referenced by delete_registry_key(), and test_Installer_InstallProduct().

◆ delete_test_files()

static void delete_test_files ( void  )
static

Definition at line 428 of file automation.c.

429{
431 DeleteFileA("msitest\\cabout\\new\\five.txt");
432 DeleteFileA("msitest\\cabout\\four.txt");
433 DeleteFileA("msitest\\second\\three.txt");
434 DeleteFileA("msitest\\first\\two.txt");
435 DeleteFileA("msitest\\one.txt");
436 DeleteFileA("msitest\\filename");
437 RemoveDirectoryA("msitest\\cabout\\new");
438 RemoveDirectoryA("msitest\\cabout");
439 RemoveDirectoryA("msitest\\second");
440 RemoveDirectoryA("msitest\\first");
441 RemoveDirectoryA("msitest");
442}

Referenced by test_Installer_InstallProduct().

◆ find_registry_key()

static UINT find_registry_key ( HKEY  hkeyParent,
LPCSTR  subkey,
LPCSTR  findkey,
REGSAM  access,
HKEY phkey 
)
static

Definition at line 2349 of file automation.c.

2350{
2351 UINT ret;
2352 CHAR *string = NULL;
2353 int idx = 0;
2354 HKEY hkey;
2355 DWORD dwSize;
2356 BOOL found = FALSE;
2357
2358 *phkey = 0;
2359
2360 ret = RegOpenKeyExA(hkeyParent, subkey, 0, access, &hkey);
2361 if (ret != ERROR_SUCCESS) return ret;
2363 if (ret != ERROR_SUCCESS) return ret;
2364 if (!(string = malloc(++dwSize))) return ERROR_NOT_ENOUGH_MEMORY;
2365
2366 while (!found &&
2367 RegEnumKeyA(hkey, idx++, string, dwSize) == ERROR_SUCCESS)
2368 {
2369 if (!strcmp(string, findkey))
2370 {
2371 *phkey = hkey;
2372 found = TRUE;
2373 }
2374 else if (find_registry_key(hkey, string, findkey, access, phkey) == ERROR_SUCCESS) found = TRUE;
2375 }
2376
2377 if (*phkey != hkey) RegCloseKey(hkey);
2378 free(string);
2379 return (found ? ERROR_SUCCESS : ERROR_FILE_NOT_FOUND);
2380}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
unsigned int idx
Definition: utils.c:41
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static UINT find_registry_key(HKEY hkeyParent, LPCSTR subkey, LPCSTR findkey, REGSAM access, HKEY *phkey)
Definition: automation.c:2349

Referenced by find_registry_key(), and test_Installer_InstallProduct().

◆ get_dispid()

static DISPID get_dispid ( IDispatch disp,
const char name 
)
static

Definition at line 501 of file automation.c.

502{
504 UINT len;
505 DISPID id = -1;
506 HRESULT r;
507
508 len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0 );
509 str = malloc( len * sizeof(WCHAR) );
510 if (str)
511 {
513 r = IDispatch_GetIDsOfNames( disp, &IID_NULL, &str, 1, 0, &id );
514 free( str );
515 if (r != S_OK)
516 return -1;
517 }
518
519 return id;
520}
GLuint id
Definition: glext.h:5910
#define S_OK
Definition: intsafe.h:52
static LPOLESTR
Definition: stg_prop.c:27
static VARIANTARG static DISPID
Definition: ordinal.c:52
#define IID_NULL
Definition: guiddef.h:98
const WCHAR * str

Referenced by test_dispid().

◆ get_program_files_dir()

static BOOL get_program_files_dir ( LPSTR  buf)
static

Definition at line 364 of file automation.c.

365{
366 HKEY hkey;
368
369 if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", &hkey))
370 return FALSE;
371
372 size = MAX_PATH;
373 if (RegQueryValueExA(hkey, "ProgramFilesDir (x86)", 0, &type, (LPBYTE)buf, &size) &&
374 RegQueryValueExA(hkey, "ProgramFilesDir", 0, &type, (LPBYTE)buf, &size))
375 return FALSE;
376
377 RegCloseKey(hkey);
378 return TRUE;
379}
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3234
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
unsigned char * LPBYTE
Definition: typedefs.h:53
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by START_TEST().

◆ init_functionpointers()

static void init_functionpointers ( void  )
static

Definition at line 205 of file automation.c.

206{
207 HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
208 HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
209
210#define GET_PROC(dll, func) \
211 p ## func = (void *)GetProcAddress(dll, #func); \
212 if(!p ## func) \
213 trace("GetProcAddress(%s) failed\n", #func);
214
215 GET_PROC(hadvapi32, RegDeleteKeyExA)
217
218#undef GET_PROC
219}
LONG WINAPI RegDeleteKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ REGSAM samDesired, _In_ DWORD Reserved)
Definition: reg.c:1254
#define IsWow64Process
Definition: compat.h:760
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
static HINSTANCE hkernel32
Definition: process.c:66
#define GET_PROC(dll, func)

Referenced by START_TEST().

◆ Installer_CreateRecord()

static HRESULT Installer_CreateRecord ( int  count,
IDispatch **  pRecord 
)
static

Definition at line 882 of file automation.c.

883{
884 VARIANT varresult;
885 VARIANTARG vararg[1];
886 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
887 HRESULT hr;
888
889 VariantInit(&vararg[0]);
890 V_VT(&vararg[0]) = VT_I4;
891 V_I4(&vararg[0]) = count;
892
893 hr = invoke(pInstaller, "CreateRecord", DISPATCH_METHOD, &dispparams, &varresult, VT_DISPATCH);
894 *pRecord = V_DISPATCH(&varresult);
895 return hr;
896}
GLuint GLuint GLsizei count
Definition: gl.h:1545
static IDispatch * pInstaller
Definition: automation.c:55

Referenced by test_Installer(), and test_Session().

◆ Installer_InstallProduct()

static HRESULT Installer_InstallProduct ( LPCWSTR  szPackagePath,
LPCWSTR  szPropertyValues 
)
static

Definition at line 1000 of file automation.c.

1001{
1002 VARIANT varresult;
1003 VARIANTARG vararg[2];
1004 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1005
1006 VariantInit(&vararg[1]);
1007 V_VT(&vararg[1]) = VT_BSTR;
1008 V_BSTR(&vararg[1]) = SysAllocString(szPackagePath);
1009 VariantInit(&vararg[0]);
1010 V_VT(&vararg[0]) = VT_BSTR;
1011 V_BSTR(&vararg[0]) = SysAllocString(szPropertyValues);
1012
1013 return invoke(pInstaller, "InstallProduct", DISPATCH_METHOD, &dispparams, &varresult, VT_EMPTY);
1014}
@ VT_EMPTY
Definition: compat.h:2295

Referenced by test_Installer_InstallProduct().

◆ Installer_OpenDatabase()

static HRESULT Installer_OpenDatabase ( LPCWSTR  szDatabasePath,
int  openmode,
IDispatch **  pDatabase 
)
static

Definition at line 981 of file automation.c.

982{
983 VARIANT varresult;
984 VARIANTARG vararg[2];
985 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
986 HRESULT hr;
987
988 VariantInit(&vararg[1]);
989 V_VT(&vararg[1]) = VT_BSTR;
990 V_BSTR(&vararg[1]) = SysAllocString(szDatabasePath);
991 VariantInit(&vararg[0]);
992 V_VT(&vararg[0]) = VT_I4;
993 V_I4(&vararg[0]) = openmode;
994
995 hr = invoke(pInstaller, "OpenDatabase", DISPATCH_METHOD, &dispparams, &varresult, VT_DISPATCH);
996 *pDatabase = V_DISPATCH(&varresult);
997 return hr;
998}

Referenced by test_Installer().

◆ Installer_OpenPackage()

static HRESULT Installer_OpenPackage ( LPCWSTR  szPackagePath,
int  options,
IDispatch **  pSession 
)
static

Definition at line 962 of file automation.c.

963{
964 VARIANT varresult;
965 VARIANTARG vararg[2];
966 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
967 HRESULT hr;
968
969 VariantInit(&vararg[1]);
970 V_VT(&vararg[1]) = VT_BSTR;
971 V_BSTR(&vararg[1]) = SysAllocString(szPackagePath);
972 VariantInit(&vararg[0]);
973 V_VT(&vararg[0]) = VT_I4;
974 V_I4(&vararg[0]) = options;
975
976 hr = invoke(pInstaller, "OpenPackage", DISPATCH_METHOD, &dispparams, &varresult, VT_DISPATCH);
977 *pSession = V_DISPATCH(&varresult);
978 return hr;
979}

Referenced by test_Installer().

◆ Installer_ProductInfo()

static HRESULT Installer_ProductInfo ( LPCWSTR  szProduct,
LPCWSTR  szAttribute,
LPWSTR  szString 
)
static

Definition at line 1033 of file automation.c.

1034{
1035 VARIANT varresult;
1036 VARIANTARG vararg[2];
1037 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1038 HRESULT hr;
1039
1040 VariantInit(&vararg[1]);
1041 V_VT(&vararg[1]) = VT_BSTR;
1042 V_BSTR(&vararg[1]) = SysAllocString(szProduct);
1043 VariantInit(&vararg[0]);
1044 V_VT(&vararg[0]) = VT_BSTR;
1045 V_BSTR(&vararg[0]) = SysAllocString(szAttribute);
1046
1047 hr = invoke(pInstaller, "ProductInfo", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR);
1048 if (V_BSTR(&varresult)) lstrcpyW(szString, V_BSTR(&varresult));
1049 VariantClear(&varresult);
1050 return hr;
1051}
#define lstrcpyW
Definition: compat.h:749
static const WCHAR szAttribute[]
Definition: domdoc.c:1179
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648

Referenced by test_Installer(), and test_Installer_InstallProduct().

◆ Installer_Products()

static HRESULT Installer_Products ( IDispatch **  pStringList)
static

Definition at line 1053 of file automation.c.

1054{
1055 VARIANT varresult;
1056 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
1057 HRESULT hr;
1058
1059 hr = invoke(pInstaller, "Products", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_DISPATCH);
1060 *pStringList = V_DISPATCH(&varresult);
1061 return hr;
1062}

Referenced by test_Installer_Products().

◆ Installer_ProductState()

static HRESULT Installer_ProductState ( LPCWSTR  szProduct,
int pInstallState 
)
static

Definition at line 1016 of file automation.c.

1017{
1018 VARIANT varresult;
1019 VARIANTARG vararg[1];
1020 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1021 HRESULT hr;
1022
1023 VariantInit(&vararg[0]);
1024 V_VT(&vararg[0]) = VT_BSTR;
1025 V_BSTR(&vararg[0]) = SysAllocString(szProduct);
1026
1027 hr = invoke(pInstaller, "ProductState", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_I4);
1028 *pInstallState = V_I4(&varresult);
1029 VariantClear(&varresult);
1030 return hr;
1031}

Referenced by test_Installer(), test_Installer_InstallProduct(), and test_Installer_Products().

◆ Installer_RegistryValue()

static HRESULT Installer_RegistryValue ( HKEY  hkey,
LPCWSTR  szKey,
VARIANT  vValue,
VARIANT pVarResult,
VARTYPE  vtExpect 
)
static

Definition at line 898 of file automation.c.

899{
900 VARIANTARG vararg[3];
901 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
902
903 VariantInit(&vararg[2]);
904 V_VT(&vararg[2]) = VT_I4;
905 V_I4(&vararg[2]) = (INT_PTR)hkey;
906 VariantInit(&vararg[1]);
907 V_VT(&vararg[1]) = VT_BSTR;
908 V_BSTR(&vararg[1]) = SysAllocString(szKey);
909 VariantInit(&vararg[0]);
910 VariantCopy(&vararg[0], &vValue);
911 VariantClear(&vValue);
912
913 return invoke(pInstaller, "RegistryValue", DISPATCH_METHOD, &dispparams, pVarResult, vtExpect);
914}
int32_t INT_PTR
Definition: typedefs.h:64
HRESULT WINAPI VariantCopy(VARIANTARG *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:748

Referenced by Installer_RegistryValueE(), Installer_RegistryValueI(), Installer_RegistryValueW(), and test_Installer_RegistryValue().

◆ Installer_RegistryValueE()

static HRESULT Installer_RegistryValueE ( HKEY  hkey,
LPCWSTR  szKey,
BOOL pBool 
)
static

Definition at line 916 of file automation.c.

917{
918 VARIANT varresult;
919 VARIANTARG vararg;
920 HRESULT hr;
921
922 VariantInit(&vararg);
923 V_VT(&vararg) = VT_EMPTY;
924 hr = Installer_RegistryValue(hkey, szKey, vararg, &varresult, VT_BOOL);
925 *pBool = V_BOOL(&varresult);
926 VariantClear(&varresult);
927 return hr;
928}
@ VT_BOOL
Definition: compat.h:2306
static HRESULT Installer_RegistryValue(HKEY hkey, LPCWSTR szKey, VARIANT vValue, VARIANT *pVarResult, VARTYPE vtExpect)
Definition: automation.c:898
#define V_BOOL(A)
Definition: oleauto.h:224

Referenced by test_Installer_RegistryValue().

◆ Installer_RegistryValueI()

static HRESULT Installer_RegistryValueI ( HKEY  hkey,
LPCWSTR  szKey,
int  iValue,
LPWSTR  szString,
VARTYPE  vtResult 
)
static

Definition at line 946 of file automation.c.

947{
948 VARIANT varresult;
949 VARIANTARG vararg;
950 HRESULT hr;
951
952 VariantInit(&vararg);
953 V_VT(&vararg) = VT_I4;
954 V_I4(&vararg) = iValue;
955
956 hr = Installer_RegistryValue(hkey, szKey, vararg, &varresult, vtResult);
957 if (SUCCEEDED(hr) && vtResult == VT_BSTR) lstrcpyW(szString, V_BSTR(&varresult));
958 VariantClear(&varresult);
959 return hr;
960}
#define SUCCEEDED(hr)
Definition: intsafe.h:50

Referenced by test_Installer_RegistryValue().

◆ Installer_RegistryValueW()

static HRESULT Installer_RegistryValueW ( HKEY  hkey,
LPCWSTR  szKey,
LPCWSTR  szValue,
LPWSTR  szString 
)
static

Definition at line 930 of file automation.c.

931{
932 VARIANT varresult;
933 VARIANTARG vararg;
934 HRESULT hr;
935
936 VariantInit(&vararg);
937 V_VT(&vararg) = VT_BSTR;
938 V_BSTR(&vararg) = SysAllocString(szValue);
939
940 hr = Installer_RegistryValue(hkey, szKey, vararg, &varresult, VT_BSTR);
941 if (V_BSTR(&varresult)) lstrcpyW(szString, V_BSTR(&varresult));
942 VariantClear(&varresult);
943 return hr;
944}

Referenced by test_Installer_RegistryValue().

◆ Installer_RelatedProducts()

static HRESULT Installer_RelatedProducts ( LPCWSTR  szProduct,
IDispatch **  pStringList 
)
static

Definition at line 1064 of file automation.c.

1065{
1066 VARIANT varresult;
1067 VARIANTARG vararg[1];
1068 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1069 HRESULT hr;
1070
1071 VariantInit(&vararg[0]);
1072 V_VT(&vararg[0]) = VT_BSTR;
1073 V_BSTR(&vararg[0]) = SysAllocString(szProduct);
1074
1075 hr = invoke(pInstaller, "RelatedProducts", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_DISPATCH);
1076 *pStringList = V_DISPATCH(&varresult);
1077 return hr;
1078}

Referenced by test_Installer(), and test_Installer_InstallProduct().

◆ Installer_SummaryInformation()

static HRESULT Installer_SummaryInformation ( BSTR  PackagePath,
int  UpdateCount,
IDispatch **  pSumInfo 
)
static

Definition at line 1106 of file automation.c.

1107{
1108 VARIANT varresult;
1109 VARIANTARG vararg[2];
1110 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1111 HRESULT hr;
1112
1113 VariantInit(&vararg[1]);
1114 V_VT(&vararg[1]) = VT_BSTR;
1115 V_BSTR(&vararg[1]) = SysAllocString(PackagePath);
1116 VariantInit(&vararg[0]);
1117 V_VT(&vararg[0]) = VT_I4;
1118 V_I4(&vararg[0]) = UpdateCount;
1119
1120 hr = invoke(pInstaller, "SummaryInformation", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_DISPATCH);
1121 *pSumInfo = V_DISPATCH(&varresult);
1122 return hr;
1123}

Referenced by test_Installer().

◆ Installer_UILevelPut()

static HRESULT Installer_UILevelPut ( int  level)
static

Definition at line 1092 of file automation.c.

1093{
1094 VARIANT varresult;
1095 VARIANTARG vararg;
1096 DISPID dispid = DISPID_PROPERTYPUT;
1097 DISPPARAMS dispparams = {&vararg, &dispid, sizeof(vararg)/sizeof(VARIANTARG), 1};
1098
1099 VariantInit(&vararg);
1100 V_VT(&vararg) = VT_I4;
1101 V_I4(&vararg) = level;
1102
1103 return invoke(pInstaller, "UILevel", DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_EMPTY);
1104}
GLint level
Definition: gl.h:1546
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008

Referenced by test_Installer_InstallProduct().

◆ Installer_VersionGet()

static HRESULT Installer_VersionGet ( LPWSTR  szVersion)
static

Definition at line 1080 of file automation.c.

1081{
1082 VARIANT varresult;
1083 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
1084 HRESULT hr;
1085
1086 hr = invoke(pInstaller, "Version", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR);
1087 if (V_BSTR(&varresult)) lstrcpyW(szVersion, V_BSTR(&varresult));
1088 VariantClear(&varresult);
1089 return hr;
1090}
static LPCWSTR szVersion
Definition: asmcache.c:748

Referenced by test_Installer().

◆ invoke()

static HRESULT invoke ( IDispatch pDispatch,
LPCSTR  szName,
WORD  wFlags,
DISPPARAMS *  pDispParams,
VARIANT pVarResult,
VARTYPE  vtResult 
)
static

Definition at line 840 of file automation.c.

841{
842 OLECHAR *name = NULL;
843 DISPID dispid;
844 HRESULT hr;
845 UINT i;
846 UINT len;
847
848 memset(pVarResult, 0, sizeof(VARIANT));
849 VariantInit(pVarResult);
850
851 len = MultiByteToWideChar(CP_ACP, 0, szName, -1, NULL, 0 );
852 name = malloc(len * sizeof(WCHAR));
853 if (!name) return E_FAIL;
855 hr = IDispatch_GetIDsOfNames(pDispatch, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid);
856 free(name);
857 ok(hr == S_OK, "IDispatch::GetIDsOfNames returned %#lx\n", hr);
858 if (hr != S_OK) return hr;
859
860 memset(&excepinfo, 0, sizeof(excepinfo));
861 hr = IDispatch_Invoke(pDispatch, dispid, &IID_NULL, LOCALE_NEUTRAL, wFlags, pDispParams, pVarResult, &excepinfo, NULL);
862
863 if (hr == S_OK)
864 {
866 ok(V_VT(pVarResult) == vtResult, "Variant result type is %d, expected %d\n", V_VT(pVarResult), vtResult);
867 if (vtResult != VT_EMPTY)
868 {
869 hr = VariantChangeTypeEx(pVarResult, pVarResult, LOCALE_NEUTRAL, 0, vtResult);
870 ok(hr == S_OK, "VariantChangeTypeEx returned %#lx\n", hr);
871 }
872 }
873
874 for (i=0; i<pDispParams->cArgs; i++)
875 VariantClear(&pDispParams->rgvarg[i]);
876
877 return hr;
878}
#define E_FAIL
Definition: ddrawi.h:102
WCHAR OLECHAR
Definition: compat.h:2292
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static int _invoke_todo_vtResult
Definition: automation.c:838
#define todo_wine_if(is_todo)
Definition: custom.c:76
#define LOCALE_NEUTRAL
#define LOCALE_USER_DEFAULT
static const WCHAR szName[]
Definition: powrprof.c:45
#define memset(x, y, z)
Definition: compat.h:39
HRESULT WINAPI VariantChangeTypeEx(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, LCID lcid, USHORT wFlags, VARTYPE vt)
Definition: variant.c:988
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531

Referenced by Database_OpenView(), Database_SummaryInformation(), Installer_CreateRecord(), Installer_InstallProduct(), Installer_OpenDatabase(), Installer_OpenPackage(), Installer_ProductInfo(), Installer_Products(), Installer_ProductState(), Installer_RegistryValue(), Installer_RelatedProducts(), Installer_SummaryInformation(), Installer_UILevelPut(), Installer_VersionGet(), Record_FieldCountGet(), Record_IntegerDataGet(), Record_IntegerDataPut(), Record_StringDataGet(), Record_StringDataPut(), Session_Database(), Session_DoAction(), Session_EvaluateCondition(), Session_FeatureCurrentState(), Session_FeatureRequestStateGet(), Session_FeatureRequestStatePut(), Session_Installer(), Session_LanguageGet(), Session_Message(), Session_ModeGet(), Session_ModePut(), Session_PropertyGet(), Session_PropertyPut(), Session_SetInstallLevel(), StringList__NewEnum(), StringList_Count(), StringList_Item(), SummaryInfo_PropertyCountGet(), SummaryInfo_PropertyGet(), SummaryInfo_PropertyPut(), View_Close(), View_Execute(), View_Fetch(), and View_Modify().

◆ is_process_limited()

static BOOL is_process_limited ( void  )
static

Definition at line 221 of file automation.c.

222{
224 PSID Group = NULL;
225 BOOL IsInGroup;
227
229 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &Group) ||
230 !CheckTokenMembership(NULL, Group, &IsInGroup))
231 {
232 trace("Could not check if the current user is an administrator\n");
233 FreeSid(Group);
234 return FALSE;
235 }
236 FreeSid(Group);
237
238 if (!IsInGroup)
239 {
240 /* Only administrators have enough privileges for these tests */
241 return TRUE;
242 }
243
245 {
246 BOOL ret;
248 DWORD size;
249
252 return (ret && type == TokenElevationTypeLimited);
253 }
254 return FALSE;
255}
#define trace
Definition: atltest.h:70
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
BOOL WINAPI CheckTokenMembership(IN HANDLE ExistingTokenHandle, IN PSID SidToCheck, OUT PBOOL IsMember)
Definition: token.c:21
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount, DWORD nSubAuthority0, DWORD nSubAuthority1, DWORD nSubAuthority2, DWORD nSubAuthority3, DWORD nSubAuthority4, DWORD nSubAuthority5, DWORD nSubAuthority6, DWORD nSubAuthority7, PSID *pSid)
Definition: security.c:674
PVOID WINAPI FreeSid(PSID pSid)
Definition: security.c:698
#define GetCurrentProcess()
Definition: compat.h:759
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
_In_opt_ PSID Group
Definition: rtlfuncs.h:1658
enum _TOKEN_ELEVATION_TYPE TOKEN_ELEVATION_TYPE
@ TokenElevationTypeLimited
Definition: winnt_old.h:2488
@ TokenElevationTypeDefault
Definition: winnt_old.h:2486
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define TOKEN_QUERY
Definition: setypes.h:928
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
@ TokenElevationType
Definition: setypes.h:983
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652

Referenced by test_Installer_InstallProduct().

◆ LONG()

static LONG ( WINAPI pRegDeleteKeyExA)
static

◆ Record_FieldCountGet()

static HRESULT Record_FieldCountGet ( IDispatch pRecord,
int pFieldCount 
)
static

Definition at line 1425 of file automation.c.

1426{
1427 VARIANT varresult;
1428 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
1429 HRESULT hr = invoke(pRecord, "FieldCount", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_I4);
1430 *pFieldCount = V_I4(&varresult);
1431 VariantClear(&varresult);
1432 return hr;
1433}

Referenced by test_Installer().

◆ Record_IntegerDataGet()

static HRESULT Record_IntegerDataGet ( IDispatch pRecord,
int  iField,
int pValue 
)
static

Definition at line 1469 of file automation.c.

1470{
1471 VARIANT varresult;
1472 VARIANTARG vararg[1];
1473 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1474 HRESULT hr;
1475
1476 VariantInit(&vararg[0]);
1477 V_VT(&vararg[0]) = VT_I4;
1478 V_I4(&vararg[0]) = iField;
1479
1480 hr = invoke(pRecord, "IntegerData", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_I4);
1481 *pValue = V_I4(&varresult);
1482 VariantClear(&varresult);
1483 return hr;
1484}
PWCHAR pValue

Referenced by test_Installer().

◆ Record_IntegerDataPut()

static HRESULT Record_IntegerDataPut ( IDispatch pRecord,
int  iField,
int  iValue 
)
static

Definition at line 1486 of file automation.c.

1487{
1488 VARIANT varresult;
1489 VARIANTARG vararg[2];
1490 DISPID dispid = DISPID_PROPERTYPUT;
1491 DISPPARAMS dispparams = {vararg, &dispid, ARRAY_SIZE(vararg), 1};
1492
1493 VariantInit(&vararg[1]);
1494 V_VT(&vararg[1]) = VT_I4;
1495 V_I4(&vararg[1]) = iField;
1496 VariantInit(&vararg[0]);
1497 V_VT(&vararg[0]) = VT_I4;
1498 V_I4(&vararg[0]) = iValue;
1499
1500 return invoke(pRecord, "IntegerData", DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_EMPTY);
1501}

Referenced by test_Installer().

◆ Record_StringDataGet()

static HRESULT Record_StringDataGet ( IDispatch pRecord,
int  iField,
LPWSTR  szString 
)
static

Definition at line 1435 of file automation.c.

1436{
1437 VARIANT varresult;
1438 VARIANTARG vararg[1];
1439 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1440 HRESULT hr;
1441
1442 VariantInit(&vararg[0]);
1443 V_VT(&vararg[0]) = VT_I4;
1444 V_I4(&vararg[0]) = iField;
1445
1446 hr = invoke(pRecord, "StringData", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR);
1447 if (V_BSTR(&varresult)) lstrcpyW(szString, V_BSTR(&varresult));
1448 VariantClear(&varresult);
1449 return hr;
1450}

Referenced by test_Database().

◆ Record_StringDataPut()

static HRESULT Record_StringDataPut ( IDispatch pRecord,
int  iField,
LPCWSTR  szString 
)
static

Definition at line 1452 of file automation.c.

1453{
1454 VARIANT varresult;
1455 VARIANTARG vararg[2];
1456 DISPID dispid = DISPID_PROPERTYPUT;
1457 DISPPARAMS dispparams = {vararg, &dispid, ARRAY_SIZE(vararg), 1};
1458
1459 VariantInit(&vararg[1]);
1460 V_VT(&vararg[1]) = VT_I4;
1461 V_I4(&vararg[1]) = iField;
1462 VariantInit(&vararg[0]);
1463 V_VT(&vararg[0]) = VT_BSTR;
1464 V_BSTR(&vararg[0]) = SysAllocString(szString);
1465
1466 return invoke(pRecord, "StringData", DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_EMPTY);
1467}

Referenced by test_Database().

◆ Session_Database()

static HRESULT Session_Database ( IDispatch pSession,
IDispatch **  pDatabase 
)
static

Definition at line 1216 of file automation.c.

1217{
1218 VARIANT varresult;
1219 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
1220 HRESULT hr;
1221
1222 hr = invoke(pSession, "Database", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_DISPATCH);
1223 *pDatabase = V_DISPATCH(&varresult);
1224 return hr;
1225}

Referenced by test_Session().

◆ Session_DoAction()

static HRESULT Session_DoAction ( IDispatch pSession,
LPCWSTR  szAction,
int iReturn 
)
static

Definition at line 1227 of file automation.c.

1228{
1229 VARIANT varresult;
1230 VARIANTARG vararg[1];
1231 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1232 HRESULT hr;
1233
1234 VariantInit(&vararg[0]);
1235 V_VT(&vararg[0]) = VT_BSTR;
1236 V_BSTR(&vararg[0]) = SysAllocString(szAction);
1237
1238 hr = invoke(pSession, "DoAction", DISPATCH_METHOD, &dispparams, &varresult, VT_I4);
1239 *iReturn = V_I4(&varresult);
1240 VariantClear(&varresult);
1241 return hr;
1242}

Referenced by test_Session().

◆ Session_EvaluateCondition()

static HRESULT Session_EvaluateCondition ( IDispatch pSession,
LPCWSTR  szCondition,
int iReturn 
)
static

Definition at line 1244 of file automation.c.

1245{
1246 VARIANT varresult;
1247 VARIANTARG vararg[1];
1248 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1249 HRESULT hr;
1250
1251 VariantInit(&vararg[0]);
1252 V_VT(&vararg[0]) = VT_BSTR;
1253 V_BSTR(&vararg[0]) = SysAllocString(szCondition);
1254
1255 hr = invoke(pSession, "EvaluateCondition", DISPATCH_METHOD, &dispparams, &varresult, VT_I4);
1256 *iReturn = V_I4(&varresult);
1257 VariantClear(&varresult);
1258 return hr;
1259}

Referenced by test_Session().

◆ Session_FeatureCurrentState()

static HRESULT Session_FeatureCurrentState ( IDispatch pSession,
LPCWSTR  szName,
int pState 
)
static

Definition at line 1295 of file automation.c.

1296{
1297 VARIANT varresult;
1298 VARIANTARG vararg[1];
1299 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1300 HRESULT hr;
1301
1302 VariantInit(&vararg[0]);
1303 V_VT(&vararg[0]) = VT_BSTR;
1304 V_BSTR(&vararg[0]) = SysAllocString(szName);
1305
1306 hr = invoke(pSession, "FeatureCurrentState", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_I4);
1307 *pState = V_I4(&varresult);
1308 VariantClear(&varresult);
1309 return hr;
1310}

Referenced by test_Session().

◆ Session_FeatureRequestStateGet()

static HRESULT Session_FeatureRequestStateGet ( IDispatch pSession,
LPCWSTR  szName,
int pState 
)
static

Definition at line 1312 of file automation.c.

1313{
1314 VARIANT varresult;
1315 VARIANTARG vararg[1];
1316 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1317 HRESULT hr;
1318
1319 VariantInit(&vararg[0]);
1320 V_VT(&vararg[0]) = VT_BSTR;
1321 V_BSTR(&vararg[0]) = SysAllocString(szName);
1322
1323 hr = invoke(pSession, "FeatureRequestState", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_I4);
1324 *pState = V_I4(&varresult);
1325 VariantClear(&varresult);
1326 return hr;
1327}

Referenced by test_Session().

◆ Session_FeatureRequestStatePut()

static HRESULT Session_FeatureRequestStatePut ( IDispatch pSession,
LPCWSTR  szName,
int  iState 
)
static

Definition at line 1329 of file automation.c.

1330{
1331 VARIANT varresult;
1332 VARIANTARG vararg[2];
1333 DISPID dispid = DISPID_PROPERTYPUT;
1334 DISPPARAMS dispparams = {vararg, &dispid, ARRAY_SIZE(vararg), 1};
1335
1336 VariantInit(&vararg[1]);
1337 V_VT(&vararg[1]) = VT_BSTR;
1338 V_BSTR(&vararg[1]) = SysAllocString(szName);
1339 VariantInit(&vararg[0]);
1340 V_VT(&vararg[0]) = VT_I4;
1341 V_I4(&vararg[0]) = iState;
1342
1343 return invoke(pSession, "FeatureRequestState", DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_EMPTY);
1344}

Referenced by test_Session().

◆ Session_Installer()

static HRESULT Session_Installer ( IDispatch pSession,
IDispatch **  pInst 
)
static

Definition at line 1125 of file automation.c.

1126{
1127 VARIANT varresult;
1128 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
1129 HRESULT hr;
1130
1131 hr = invoke(pSession, "Installer", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_DISPATCH);
1132 *pInst = V_DISPATCH(&varresult);
1133 return hr;
1134}

Referenced by test_Session().

◆ Session_LanguageGet()

static HRESULT Session_LanguageGet ( IDispatch pSession,
UINT pLangId 
)
static

Definition at line 1170 of file automation.c.

1171{
1172 VARIANT varresult;
1173 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
1174 HRESULT hr;
1175
1176 hr = invoke(pSession, "Language", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_I4);
1177 *pLangId = V_I4(&varresult);
1178 VariantClear(&varresult);
1179 return hr;
1180}

Referenced by test_Session().

◆ Session_Message()

static HRESULT Session_Message ( IDispatch pSession,
LONG  kind,
IDispatch record,
int ret 
)
static

Definition at line 1261 of file automation.c.

1262{
1263 VARIANT varresult;
1264 VARIANTARG vararg[2];
1265 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1266 HRESULT hr;
1267
1268 VariantInit(&varresult);
1269 V_VT(vararg) = VT_DISPATCH;
1270 V_DISPATCH(vararg) = record;
1271 V_VT(vararg+1) = VT_I4;
1272 V_I4(vararg+1) = kind;
1273
1274 hr = invoke(pSession, "Message", DISPATCH_METHOD, &dispparams, &varresult, VT_I4);
1275
1276 ok(V_VT(&varresult) == VT_I4, "V_VT(varresult) = %d\n", V_VT(&varresult));
1277 *ret = V_I4(&varresult);
1278
1279 return hr;
1280}

Referenced by test_Session().

◆ Session_ModeGet()

static HRESULT Session_ModeGet ( IDispatch pSession,
int  iFlag,
VARIANT_BOOL mode 
)
static

Definition at line 1182 of file automation.c.

1183{
1184 VARIANT varresult;
1185 VARIANTARG vararg[1];
1186 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1187 HRESULT hr;
1188
1189 VariantInit(&vararg[0]);
1190 V_VT(&vararg[0]) = VT_I4;
1191 V_I4(&vararg[0]) = iFlag;
1192
1193 hr = invoke(pSession, "Mode", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BOOL);
1194 *mode = V_BOOL(&varresult);
1195 VariantClear(&varresult);
1196 return hr;
1197}
GLenum mode
Definition: glext.h:6217

Referenced by test_Session().

◆ Session_ModePut()

static HRESULT Session_ModePut ( IDispatch pSession,
int  iFlag,
VARIANT_BOOL  mode 
)
static

Definition at line 1199 of file automation.c.

1200{
1201 VARIANT varresult;
1202 VARIANTARG vararg[2];
1203 DISPID dispid = DISPID_PROPERTYPUT;
1204 DISPPARAMS dispparams = {vararg, &dispid, ARRAY_SIZE(vararg), 1};
1205
1206 VariantInit(&vararg[1]);
1207 V_VT(&vararg[1]) = VT_I4;
1208 V_I4(&vararg[1]) = iFlag;
1209 VariantInit(&vararg[0]);
1210 V_VT(&vararg[0]) = VT_BOOL;
1211 V_BOOL(&vararg[0]) = mode;
1212
1213 return invoke(pSession, "Mode", DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_EMPTY);
1214}

Referenced by test_Session().

◆ Session_PropertyGet()

static HRESULT Session_PropertyGet ( IDispatch pSession,
LPCWSTR  szName,
LPWSTR  szReturn 
)
static

Definition at line 1136 of file automation.c.

1137{
1138 VARIANT varresult;
1139 VARIANTARG vararg[1];
1140 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1141 HRESULT hr;
1142
1143 VariantInit(&vararg[0]);
1144 V_VT(&vararg[0]) = VT_BSTR;
1145 V_BSTR(&vararg[0]) = SysAllocString(szName);
1146
1147 hr = invoke(pSession, "Property", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR);
1148 if (V_BSTR(&varresult)) lstrcpyW(szReturn, V_BSTR(&varresult));
1149 VariantClear(&varresult);
1150 return hr;
1151}

Referenced by test_Session().

◆ Session_PropertyPut()

static HRESULT Session_PropertyPut ( IDispatch pSession,
LPCWSTR  szName,
LPCWSTR  szValue 
)
static

Definition at line 1153 of file automation.c.

1154{
1155 VARIANT varresult;
1156 VARIANTARG vararg[2];
1157 DISPID dispid = DISPID_PROPERTYPUT;
1158 DISPPARAMS dispparams = {vararg, &dispid, ARRAY_SIZE(vararg), 1};
1159
1160 VariantInit(&vararg[1]);
1161 V_VT(&vararg[1]) = VT_BSTR;
1162 V_BSTR(&vararg[1]) = SysAllocString(szName);
1163 VariantInit(&vararg[0]);
1164 V_VT(&vararg[0]) = VT_BSTR;
1165 V_BSTR(&vararg[0]) = SysAllocString(szValue);
1166
1167 return invoke(pSession, "Property", DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_EMPTY);
1168}

Referenced by test_Session().

◆ Session_SetInstallLevel()

static HRESULT Session_SetInstallLevel ( IDispatch pSession,
LONG  iInstallLevel 
)
static

Definition at line 1282 of file automation.c.

1283{
1284 VARIANT varresult;
1285 VARIANTARG vararg[1];
1286 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1287
1288 VariantInit(&vararg[0]);
1289 V_VT(&vararg[0]) = VT_I4;
1290 V_I4(&vararg[0]) = iInstallLevel;
1291
1292 return invoke(pSession, "SetInstallLevel", DISPATCH_METHOD, &dispparams, &varresult, VT_EMPTY);
1293}

Referenced by test_Session().

◆ START_TEST()

START_TEST ( automation  )

Definition at line 2700 of file automation.c.

2701{
2702 DWORD len;
2703 char temp_path[MAX_PATH], prev_path[MAX_PATH];
2704 HRESULT hr;
2705 CLSID clsid;
2706 IUnknown *pUnk;
2707
2709
2710 if (pIsWow64Process)
2711 pIsWow64Process(GetCurrentProcess(), &is_wow64);
2712
2714
2715 GetCurrentDirectoryA(MAX_PATH, prev_path);
2718
2721
2722 if(len && (CURR_DIR[len - 1] == '\\'))
2723 CURR_DIR[len - 1] = 0;
2724
2726
2728 ok (hr == S_OK, "OleInitialize returned %#lx\n", hr);
2729 hr = CLSIDFromProgID(L"WindowsInstaller.Installer", &clsid);
2730 ok (hr == S_OK, "CLSIDFromProgID returned %#lx\n", hr);
2731 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&pUnk);
2732 ok(hr == S_OK, "CoCreateInstance returned %#lx\n", hr);
2733
2734 if (pUnk)
2735 {
2736 hr = IUnknown_QueryInterface(pUnk, &IID_IDispatch, (void **)&pInstaller);
2737 ok (hr == S_OK, "IUnknown::QueryInterface returned %#lx\n", hr);
2738
2739 test_dispid();
2740 test_dispatch();
2742
2743 IDispatch_Release(pInstaller);
2744 IUnknown_Release(pUnk);
2745 }
2746
2748
2749 SetCurrentDirectoryA(prev_path);
2750}
const GUID IID_IUnknown
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2146
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2206
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI DECLSPEC_HOTPATCH CLSIDFromProgID(LPCOLESTR progid, LPCLSID clsid)
Definition: compobj.c:2602
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:169
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:230
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
static void test_Installer(void)
Definition: automation.c:2561
static FILETIME systemtime
Definition: automation.c:48
static BOOL is_wow64
Definition: automation.c:40
static void init_functionpointers(void)
Definition: automation.c:205
static void test_dispatch(void)
Definition: automation.c:617
static void test_dispid(void)
Definition: automation.c:579
static BOOL get_program_files_dir(LPSTR buf)
Definition: automation.c:364
REFCLSID clsid
Definition: msctf.c:82
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
const GUID IID_IDispatch

◆ StringList__NewEnum()

static HRESULT StringList__NewEnum ( IDispatch pList,
IUnknown **  ppEnumVARIANT 
)
static

Definition at line 1503 of file automation.c.

1504{
1505 VARIANT varresult;
1506 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
1507 HRESULT hr = invoke(pList, "_NewEnum", DISPATCH_METHOD, &dispparams, &varresult, VT_UNKNOWN);
1508 *ppEnumVARIANT = V_UNKNOWN(&varresult);
1509 return hr;
1510}
@ VT_UNKNOWN
Definition: compat.h:2308
FxChildList * pList
#define V_UNKNOWN(A)
Definition: oleauto.h:281

Referenced by test_Installer_Products().

◆ StringList_Count()

static HRESULT StringList_Count ( IDispatch pStringList,
int pCount 
)
static

Definition at line 1529 of file automation.c.

1530{
1531 VARIANT varresult;
1532 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
1533 HRESULT hr = invoke(pStringList, "Count", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_I4);
1534 *pCount = V_I4(&varresult);
1535 VariantClear(&varresult);
1536 return hr;
1537}

Referenced by test_Installer(), test_Installer_InstallProduct(), and test_Installer_Products().

◆ StringList_Item()

static HRESULT StringList_Item ( IDispatch pStringList,
int  iIndex,
LPWSTR  szString 
)
static

Definition at line 1512 of file automation.c.

1513{
1514 VARIANT varresult;
1515 VARIANTARG vararg[1];
1516 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1517 HRESULT hr;
1518
1519 VariantInit(&vararg[0]);
1520 V_VT(&vararg[0]) = VT_I4;
1521 V_I4(&vararg[0]) = iIndex;
1522
1523 hr = invoke(pStringList, "Item", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_BSTR);
1524 if (V_BSTR(&varresult)) lstrcpyW(szString, V_BSTR(&varresult));
1525 VariantClear(&varresult);
1526 return hr;
1527}

Referenced by test_Installer_InstallProduct(), and test_Installer_Products().

◆ SummaryInfo_PropertyCountGet()

static HRESULT SummaryInfo_PropertyCountGet ( IDispatch pSummaryInfo,
int pCount 
)
static

Definition at line 1566 of file automation.c.

1567{
1568 VARIANT varresult;
1569 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
1570 HRESULT hr;
1571
1572 hr = invoke(pSummaryInfo, "PropertyCount", DISPATCH_PROPERTYGET, &dispparams, &varresult, VT_I4);
1573 *pCount = V_I4(&varresult);
1574 VariantClear(&varresult);
1575 return hr;
1576}

Referenced by test_SummaryInfo().

◆ SummaryInfo_PropertyGet()

static HRESULT SummaryInfo_PropertyGet ( IDispatch pSummaryInfo,
int  pid,
VARIANT pVarResult,
VARTYPE  vtExpect 
)
static

Definition at line 1539 of file automation.c.

1540{
1541 VARIANTARG vararg[1];
1542 DISPPARAMS dispparams = {vararg, NULL, ARRAY_SIZE(vararg), 0};
1543
1544 VariantInit(&vararg[0]);
1545 V_VT(&vararg[0]) = VT_I4;
1546 V_I4(&vararg[0]) = pid;
1547 return invoke(pSummaryInfo, "Property", DISPATCH_PROPERTYGET, &dispparams, pVarResult, vtExpect);
1548}
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837

Referenced by test_SummaryInfo().

◆ SummaryInfo_PropertyPut()

static HRESULT SummaryInfo_PropertyPut ( IDispatch pSummaryInfo,
int  pid,
VARIANT pVariant 
)
static

Definition at line 1550 of file automation.c.

1551{
1552 VARIANT varresult;
1553 VARIANTARG vararg[2];
1554 DISPID dispid = DISPID_PROPERTYPUT;
1555 DISPPARAMS dispparams = {vararg, &dispid, ARRAY_SIZE(vararg), 1};
1556
1557 VariantInit(&vararg[1]);
1558 V_VT(&vararg[1]) = VT_I4;
1559 V_I4(&vararg[1]) = pid;
1560 VariantInit(&vararg[0]);
1561 VariantCopyInd(vararg, pVariant);
1562
1563 return invoke(pSummaryInfo, "Property", DISPATCH_PROPERTYPUT, &dispparams, &varresult, VT_EMPTY);
1564}
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:847

Referenced by test_SummaryInfo().

◆ test_Database()

static void test_Database ( IDispatch pDatabase,
BOOL  readonly 
)
static

Definition at line 1723 of file automation.c.

1724{
1725 IDispatch *pView = NULL, *pSummaryInfo = NULL;
1726 HRESULT hr;
1727
1728 hr = Database_OpenView(pDatabase, L"SELECT `Feature` FROM `Feature` WHERE `Feature_Parent`='One'", &pView);
1729 ok(hr == S_OK, "Database_OpenView failed, hresult %#lx\n", hr);
1730 if (hr == S_OK)
1731 {
1732 IDispatch *pRecord = NULL;
1733 WCHAR szString[MAX_PATH];
1734
1735 /* View::Execute */
1736 hr = View_Execute(pView, NULL);
1737 ok(hr == S_OK, "View_Execute failed, hresult %#lx\n", hr);
1738
1739 /* View::Fetch */
1740 hr = View_Fetch(pView, &pRecord);
1741 ok(hr == S_OK, "View_Fetch failed, hresult %#lx\n", hr);
1742 ok(pRecord != NULL, "View_Fetch should not have returned NULL record\n");
1743 if (pRecord)
1744 {
1745 /* Record::StringDataGet */
1746 memset(szString, 0, sizeof(szString));
1747 hr = Record_StringDataGet(pRecord, 1, szString);
1748 ok(hr == S_OK, "Record_StringDataGet failed, hresult %#lx\n", hr);
1749 ok_w2("Record_StringDataGet result was %s but expected %s\n", szString, L"Three");
1750
1751 /* Record::StringDataPut with correct index */
1752 hr = Record_StringDataPut(pRecord, 1, L"Two");
1753 ok(hr == S_OK, "Record_StringDataPut failed, hresult %#lx\n", hr);
1754
1755 /* Record::StringDataGet */
1756 memset(szString, 0, sizeof(szString));
1757 hr = Record_StringDataGet(pRecord, 1, szString);
1758 ok(hr == S_OK, "Record_StringDataGet failed, hresult %#lx\n", hr);
1759 ok_w2("Record_StringDataGet result was %s but expected %s\n", szString, L"Two");
1760
1761 /* Record::StringDataPut with incorrect index */
1762 hr = Record_StringDataPut(pRecord, -1, szString);
1763 ok(hr == DISP_E_EXCEPTION, "Record_StringDataPut failed, hresult %#lx\n", hr);
1764 ok_exception(hr, L"StringData,Field");
1765
1766 /* View::Modify with incorrect parameters */
1767 hr = View_Modify(pView, -5, NULL);
1768 ok(hr == DISP_E_EXCEPTION, "View_Modify failed, hresult %#lx\n", hr);
1769 ok_exception(hr, L"Modify,Mode,Record");
1770
1771 hr = View_Modify(pView, -5, pRecord);
1772 ok(hr == DISP_E_EXCEPTION, "View_Modify failed, hresult %#lx\n", hr);
1773 ok_exception(hr, L"Modify,Mode,Record");
1774
1776 ok(hr == DISP_E_EXCEPTION, "View_Modify failed, hresult %#lx\n", hr);
1777 ok_exception(hr, L"Modify,Mode,Record");
1778
1779 hr = View_Modify(pView, MSIMODIFY_REFRESH, pRecord);
1780 ok(hr == S_OK, "View_Modify failed, hresult %#lx\n", hr);
1781
1782 /* Record::StringDataGet, confirm that the record is back to its unmodified value */
1783 memset(szString, 0, sizeof(szString));
1784 hr = Record_StringDataGet(pRecord, 1, szString);
1785 ok(hr == S_OK, "Record_StringDataGet failed, hresult %#lx\n", hr);
1786 todo_wine ok_w2("Record_StringDataGet result was %s but expected %s\n", szString, L"Three");
1787
1788 IDispatch_Release(pRecord);
1789 }
1790
1791 /* View::Fetch */
1792 hr = View_Fetch(pView, &pRecord);
1793 ok(hr == S_OK, "View_Fetch failed, hresult %#lx\n", hr);
1794 ok(pRecord != NULL, "View_Fetch should not have returned NULL record\n");
1795 if (pRecord)
1796 {
1797 /* Record::StringDataGet */
1798 memset(szString, 0, sizeof(szString));
1799 hr = Record_StringDataGet(pRecord, 1, szString);
1800 ok(hr == S_OK, "Record_StringDataGet failed, hresult %#lx\n", hr);
1801 ok_w2("Record_StringDataGet result was %s but expected %s\n", szString, L"Two");
1802
1803 IDispatch_Release(pRecord);
1804 }
1805
1806 /* View::Fetch */
1807 hr = View_Fetch(pView, &pRecord);
1808 ok(hr == S_OK, "View_Fetch failed, hresult %#lx\n", hr);
1809 ok(pRecord == NULL, "View_Fetch should have returned NULL record\n");
1810 if (pRecord)
1811 IDispatch_Release(pRecord);
1812
1813 /* View::Close */
1814 hr = View_Close(pView);
1815 ok(hr == S_OK, "View_Close failed, hresult %#lx\n", hr);
1816
1817 IDispatch_Release(pView);
1818 }
1819
1820 /* Database::SummaryInformation */
1822 ok(hr == S_OK, "Database_SummaryInformation failed, hresult %#lx\n", hr);
1823 ok(pSummaryInfo != NULL, "Database_SummaryInformation should not have returned NULL record\n");
1824 if (pSummaryInfo)
1825 {
1826 test_SummaryInfo(pSummaryInfo, summary_info, ARRAY_SIZE(summary_info), readonly);
1827 IDispatch_Release(pSummaryInfo);
1828 }
1829}
static HRESULT View_Execute(IDispatch *pView, IDispatch *pRecord)
Definition: automation.c:1378
static HRESULT View_Fetch(IDispatch *pView, IDispatch **ppRecord)
Definition: automation.c:1391
#define TEST_SUMMARYINFO_PROPERTIES_MODIFIED
Definition: automation.c:1580
static HRESULT Record_StringDataGet(IDispatch *pRecord, int iField, LPWSTR szString)
Definition: automation.c:1435
static HRESULT Database_OpenView(IDispatch *pDatabase, LPCWSTR szSql, IDispatch **pView)
Definition: automation.c:1346
#define ok_w2(format, szString1, szString2)
Definition: automation.c:451
static HRESULT Record_StringDataPut(IDispatch *pRecord, int iField, LPCWSTR szString)
Definition: automation.c:1452
static HRESULT View_Modify(IDispatch *pView, int iMode, IDispatch *pRecord)
Definition: automation.c:1400
static void test_SummaryInfo(IDispatch *pSummaryInfo, const msi_summary_info *info, int num_info, BOOL readonly)
Definition: automation.c:1582
static HRESULT Database_SummaryInformation(IDispatch *pDatabase, int iUpdateCount, IDispatch **pSummaryInfo)
Definition: automation.c:1362
#define ok_exception(hr, szDescription)
Definition: automation.c:482
static HRESULT View_Close(IDispatch *pView)
Definition: automation.c:1418
#define todo_wine
Definition: custom.c:79
@ MSIMODIFY_REFRESH
Definition: msiquery.h:51

Referenced by test_Installer(), and test_Session().

◆ test_dispatch()

static void test_dispatch ( void  )
static

Definition at line 617 of file automation.c.

618{
619 HRESULT hr;
620 DISPID dispid;
621 OLECHAR *name;
622 VARIANT varresult;
623 VARIANTARG vararg[3];
625 DISPPARAMS dispparams = {NULL, NULL, 0, 0};
626
627 /* Test getting ID of a function name that does not exist */
628 name = (WCHAR *)L"winetest-automation.msi";
629 hr = IDispatch_GetIDsOfNames(pInstaller, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid);
630 ok(hr == DISP_E_UNKNOWNNAME, "IDispatch::GetIDsOfNames returned %#lx\n", hr);
631
632 /* Test invoking this function */
633 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
634 ok(hr == DISP_E_MEMBERNOTFOUND, "IDispatch::Invoke returned %#lx\n", hr);
635
636 /* Test getting ID of a function name that does exist */
637 name = (WCHAR *)L"OpenPackage";
638 hr = IDispatch_GetIDsOfNames(pInstaller, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid);
639 ok(hr == S_OK, "IDispatch::GetIDsOfNames returned %#lx\n", hr);
640
641 /* Test invoking this function (without parameters passed) */
642 if (0) /* All of these crash MSI on Windows XP */
643 {
644 IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, NULL, NULL, NULL);
645 IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, NULL, &excepinfo, NULL);
646 VariantInit(&varresult);
647 IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, NULL, &varresult, &excepinfo, NULL);
648 }
649
650 /* Try with NULL params */
651 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
652 ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned %#lx\n", hr);
653
654 /* Try one empty parameter */
655 dispparams.rgvarg = vararg;
656 dispparams.cArgs = 1;
657 VariantInit(&vararg[0]);
658 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
659 ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned %#lx\n", hr);
660
661 /* Try two empty parameters */
662 dispparams.cArgs = 2;
663 VariantInit(&vararg[0]);
664 VariantInit(&vararg[1]);
665 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
666 ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned %#lx\n", hr);
667
668 /* Try one parameter, the required BSTR. Second parameter is optional.
669 * NOTE: The specified package does not exist, which is why the call fails.
670 */
671 dispparams.cArgs = 1;
672 VariantInit(&vararg[0]);
673 V_VT(&vararg[0]) = VT_BSTR;
674 V_BSTR(&vararg[0]) = SysAllocString(L"winetest-automation.msi");
675 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
676 ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned %#lx\n", hr);
677 ok_exception(hr, L"OpenPackage,PackagePath,Options");
678 VariantClear(&vararg[0]);
679
680 /* Provide the required BSTR and an empty second parameter.
681 * NOTE: The specified package does not exist, which is why the call fails.
682 */
683 dispparams.cArgs = 2;
684 VariantInit(&vararg[1]);
685 V_VT(&vararg[1]) = VT_BSTR;
686 V_BSTR(&vararg[1]) = SysAllocString(L"winetest-automation.msi");
687 VariantInit(&vararg[0]);
688 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
689 ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned %#lx\n", hr);
690 ok_exception(hr, L"OpenPackage,PackagePath,Options");
691 VariantClear(&vararg[1]);
692
693 /* Provide the required BSTR and two empty parameters.
694 * NOTE: The specified package does not exist, which is why the call fails.
695 */
696 dispparams.cArgs = 3;
697 VariantInit(&vararg[2]);
698 V_VT(&vararg[2]) = VT_BSTR;
699 V_BSTR(&vararg[2]) = SysAllocString(L"winetest-automation.msi");
700 VariantInit(&vararg[1]);
701 VariantInit(&vararg[0]);
702 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
703 ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned %#lx\n", hr);
704 ok_exception(hr, L"OpenPackage,PackagePath,Options");
705 VariantClear(&vararg[2]);
706
707 /* Provide the required BSTR and a second parameter with the wrong type. */
708 dispparams.cArgs = 2;
709 VariantInit(&vararg[1]);
710 V_VT(&vararg[1]) = VT_BSTR;
711 V_BSTR(&vararg[1]) = SysAllocString(L"winetest-automation.msi");
712 VariantInit(&vararg[0]);
713 V_VT(&vararg[0]) = VT_BSTR;
714 V_BSTR(&vararg[0]) = SysAllocString(L"winetest-automation.msi");
715 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
716 ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned %#lx\n", hr);
717 VariantClear(&vararg[0]);
718 VariantClear(&vararg[1]);
719
720 /* Create a proper installer package. */
722
723 /* Try one parameter, the required BSTR. Second parameter is optional.
724 * Proper installer package exists. Path to the package is relative.
725 */
726 dispparams.cArgs = 1;
727 VariantInit(&vararg[0]);
728 V_VT(&vararg[0]) = VT_BSTR;
729 V_BSTR(&vararg[0]) = SysAllocString(L"winetest-automation.msi");
730 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
731 todo_wine ok(hr == DISP_E_EXCEPTION, "IDispatch::Invoke returned %#lx\n", hr);
732 ok_exception(hr, L"OpenPackage,PackagePath,Options");
733 VariantClear(&vararg[0]);
734 if (hr != DISP_E_EXCEPTION)
735 VariantClear(&varresult);
736
737 /* Try one parameter, the required BSTR. Second parameter is optional.
738 * Proper installer package exists. Path to the package is absolute.
739 */
740 dispparams.cArgs = 1;
741 VariantInit(&vararg[0]);
742 V_VT(&vararg[0]) = VT_BSTR;
743 V_BSTR(&vararg[0]) = SysAllocString(path);
744 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
745 if (hr == DISP_E_EXCEPTION)
746 {
747 skip("OpenPackage failed, insufficient rights?\n");
749 return;
750 }
751 ok(hr == S_OK, "IDispatch::Invoke returned %#lx\n", hr);
752 VariantClear(&vararg[0]);
753 VariantClear(&varresult);
754
755 /* Provide the required BSTR and an empty second parameter. Proper
756 * installation package exists.
757 */
758 dispparams.cArgs = 2;
759 VariantInit(&vararg[1]);
760 V_VT(&vararg[1]) = VT_BSTR;
761 V_BSTR(&vararg[1]) = SysAllocString(path);
762 VariantInit(&vararg[0]);
763 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
764 ok(hr == S_OK, "IDispatch::Invoke returned %#lx\n", hr);
765 VariantClear(&vararg[1]);
766 VariantClear(&varresult);
767
768 /* Provide the required BSTR and two empty parameters. Proper
769 * installation package exists.
770 */
771 dispparams.cArgs = 3;
772 VariantInit(&vararg[2]);
773 V_VT(&vararg[2]) = VT_BSTR;
774 V_BSTR(&vararg[2]) = SysAllocString(path);
775 VariantInit(&vararg[1]);
776 VariantInit(&vararg[0]);
777 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
778 ok(hr == S_OK, "IDispatch::Invoke returned %#lx\n", hr);
779 VariantClear(&vararg[2]);
780 VariantClear(&varresult);
781
782 /* Provide the required BSTR and a second parameter with the wrong type. */
783 dispparams.cArgs = 2;
784 VariantInit(&vararg[1]);
785 V_VT(&vararg[1]) = VT_BSTR;
786 V_BSTR(&vararg[1]) = SysAllocString(path);
787 VariantInit(&vararg[0]);
788 V_VT(&vararg[0]) = VT_BSTR;
789 V_BSTR(&vararg[0]) = SysAllocString(path);
790 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
791 ok(hr == DISP_E_TYPEMISMATCH, "IDispatch::Invoke returned %#lx\n", hr);
792 VariantClear(&vararg[0]);
793 VariantClear(&vararg[1]);
794
795 /* Provide the required BSTR and a second parameter that can be coerced to
796 * VT_I4.
797 */
798 dispparams.cArgs = 2;
799 VariantInit(&vararg[1]);
800 V_VT(&vararg[1]) = VT_BSTR;
801 V_BSTR(&vararg[1]) = SysAllocString(path);
802 VariantInit(&vararg[0]);
803 V_VT(&vararg[0]) = VT_I2;
804 V_BSTR(&vararg[0]) = 0;
805 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
806 ok(hr == S_OK, "IDispatch::Invoke returned %#lx\n", hr);
807 VariantClear(&vararg[1]);
808 VariantClear(&varresult);
809
811
812 /* Test invoking a method as a DISPATCH_PROPERTYGET or DISPATCH_PROPERTYPUT */
813 VariantInit(&vararg[0]);
814 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYGET, &dispparams, &varresult, &excepinfo, NULL);
815 ok(hr == DISP_E_MEMBERNOTFOUND, "IDispatch::Invoke returned %#lx\n", hr);
816
817 VariantInit(&vararg[0]);
818 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL);
819 ok(hr == DISP_E_MEMBERNOTFOUND, "IDispatch::Invoke returned %#lx\n", hr);
820
821 /* Test invoking a read-only property as DISPATCH_PROPERTYPUT or as a DISPATCH_METHOD */
822 name = (WCHAR *)L"ProductState";
823 hr = IDispatch_GetIDsOfNames(pInstaller, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid);
824 ok(hr == S_OK, "IDispatch::GetIDsOfNames returned %#lx\n", hr);
825
826 dispparams.rgvarg = NULL;
827 dispparams.cArgs = 0;
828 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dispparams, &varresult, &excepinfo, NULL);
829 ok(hr == DISP_E_MEMBERNOTFOUND, "IDispatch::Invoke returned %#lx\n", hr);
830
831 dispparams.rgvarg = NULL;
832 dispparams.cArgs = 0;
833 hr = IDispatch_Invoke(pInstaller, dispid, &IID_NULL, LOCALE_NEUTRAL, DISPATCH_METHOD, &dispparams, &varresult, &excepinfo, NULL);
834 ok(hr == DISP_E_MEMBERNOTFOUND, "IDispatch::Invoke returned %#lx\n", hr);
835}
#define skip(...)
Definition: atltest.h:64
@ VT_I2
Definition: compat.h:2297
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
static BOOL create_package(LPWSTR path)
Definition: automation.c:341
#define DISP_E_MEMBERNOTFOUND
Definition: winerror.h:2512
#define DISP_E_TYPEMISMATCH
Definition: winerror.h:2514
#define DISP_E_UNKNOWNNAME
Definition: winerror.h:2515

Referenced by START_TEST().

◆ test_dispid()

static void test_dispid ( void  )
static

Definition at line 579 of file automation.c.

580{
581 const get_did_t *ptr = get_did_data;
582 DISPID dispid;
583
584 while (ptr->name)
585 {
586 dispid = get_dispid(pInstaller, ptr->name);
587 todo_wine_if (ptr->todo)
588 ok(dispid == ptr->did, "%s: expected %ld, got %ld\n", ptr->name, ptr->did, dispid);
589 ptr++;
590 }
591
592 dispid = get_dispid(pInstaller, "RemovePatches");
593 ok(dispid == 49 || dispid == -1, "Expected 49 or -1, got %ld\n", dispid);
594 dispid = get_dispid(pInstaller, "ApplyMultiplePatches");
595 ok(dispid == 51 || dispid == -1, "Expected 51 or -1, got %ld\n", dispid);
596 dispid = get_dispid(pInstaller, "ProductsEx");
597 ok(dispid == 52 || dispid == -1, "Expected 52 or -1, got %ld\n", dispid);
598 dispid = get_dispid(pInstaller, "PatchesEx");
599 ok(dispid == 55 || dispid == -1, "Expected 55 or -1, got %ld\n", dispid);
600 dispid = get_dispid(pInstaller, "ExtractPatchXMLData");
601 ok(dispid == 57 || dispid == -1, "Expected 57 or -1, got %ld\n", dispid);
602 dispid = get_dispid( pInstaller, "ProductElevated" );
603 ok(dispid == 59 || dispid == -1, "Expected 59 or -1, got %ld\n", dispid);
604 dispid = get_dispid( pInstaller, "ProvideAssembly" );
605 ok(dispid == 60 || dispid == -1, "Expected 60 or -1, got %ld\n", dispid);
606 dispid = get_dispid( pInstaller, "ProductInfoFromScript" );
607 ok(dispid == 61 || dispid == -1, "Expected 61 or -1, got %ld\n", dispid);
608 dispid = get_dispid( pInstaller, "AdvertiseProduct" );
609 ok(dispid == 62 || dispid == -1, "Expected 62 or -1, got %ld\n", dispid);
610 dispid = get_dispid( pInstaller, "CreateAdvertiseScript" );
611 ok(dispid == 63 || dispid == -1, "Expected 63 or -1, got %ld\n", dispid);
612 dispid = get_dispid( pInstaller, "PatchFiles" );
613 ok(dispid == 65 || dispid == -1, "Expected 65 or -1, got %ld\n", dispid);
614}
BOOLEAN Expected
GLdouble s
Definition: gl.h:2039
GLdouble n
Definition: glext.h:7729
static PVOID ptr
Definition: dispmode.c:27
BOOL expected
Definition: store.c:2063
static const get_did_t get_did_data[]
Definition: automation.c:528
static DISPID get_dispid(IDispatch *disp, const char *name)
Definition: automation.c:501

Referenced by START_TEST().

◆ test_Installer()

static void test_Installer ( void  )
static

Definition at line 2561 of file automation.c.

2562{
2564 HRESULT hr;
2565 IDispatch *pSession = NULL, *pDatabase = NULL, *pRecord = NULL, *pStringList = NULL, *pSumInfo = NULL;
2566 int iValue, iCount;
2567
2568 if (!pInstaller) return;
2569
2570 /* Installer::CreateRecord */
2571
2572 /* Test for error */
2573 hr = Installer_CreateRecord(-1, &pRecord);
2574 ok(hr == DISP_E_EXCEPTION, "Installer_CreateRecord failed, hresult %#lx\n", hr);
2575 ok_exception(hr, L"CreateRecord,Count");
2576
2577 /* Test for success */
2578 hr = Installer_CreateRecord(1, &pRecord);
2579 ok(hr == S_OK, "Installer_CreateRecord failed, hresult %#lx\n", hr);
2580 ok(pRecord != NULL, "Installer_CreateRecord should not have returned NULL record\n");
2581 if (pRecord)
2582 {
2583 /* Record::FieldCountGet */
2584 hr = Record_FieldCountGet(pRecord, &iValue);
2585 ok(hr == S_OK, "Record_FiledCountGet failed, hresult %#lx\n", hr);
2586 ok(iValue == 1, "Record_FieldCountGet result was %d but expected 1\n", iValue);
2587
2588 /* Record::IntegerDataGet */
2589 hr = Record_IntegerDataGet(pRecord, 1, &iValue);
2590 ok(hr == S_OK, "Record_IntegerDataGet failed, hresult %#lx\n", hr);
2591 ok(iValue == MSI_NULL_INTEGER, "Record_IntegerDataGet result was %d but expected %d\n", iValue, MSI_NULL_INTEGER);
2592
2593 /* Record::IntegerDataGet, bad index */
2594 hr = Record_IntegerDataGet(pRecord, 10, &iValue);
2595 ok(hr == S_OK, "Record_IntegerDataGet failed, hresult %#lx\n", hr);
2596 ok(iValue == MSI_NULL_INTEGER, "Record_IntegerDataGet result was %d but expected %d\n", iValue, MSI_NULL_INTEGER);
2597
2598 /* Record::IntegerDataPut */
2599 hr = Record_IntegerDataPut(pRecord, 1, 100);
2600 ok(hr == S_OK, "Record_IntegerDataPut failed, hresult %#lx\n", hr);
2601
2602 /* Record::IntegerDataPut, bad index */
2603 hr = Record_IntegerDataPut(pRecord, 10, 100);
2604 ok(hr == DISP_E_EXCEPTION, "Record_IntegerDataPut failed, hresult %#lx\n", hr);
2605 ok_exception(hr, L"IntegerData,Field");
2606
2607 /* Record::IntegerDataGet */
2608 hr = Record_IntegerDataGet(pRecord, 1, &iValue);
2609 ok(hr == S_OK, "Record_IntegerDataGet failed, hresult %#lx\n", hr);
2610 ok(iValue == 100, "Record_IntegerDataGet result was %d but expected 100\n", iValue);
2611
2612 IDispatch_Release(pRecord);
2613 }
2614
2616
2617 /* Installer::OpenPackage */
2618 hr = Installer_OpenPackage(szPath, 0, &pSession);
2619 if (hr == DISP_E_EXCEPTION)
2620 {
2621 skip("OpenPackage failed, insufficient rights?\n");
2623 return;
2624 }
2625 ok(hr == S_OK, "Installer_OpenPackage failed, hresult %#lx\n", hr);
2626 if (hr == S_OK)
2627 {
2628 test_Session(pSession);
2629 IDispatch_Release(pSession);
2630 }
2631
2632 /* Installer::OpenDatabase */
2634 ok(hr == S_OK, "Installer_OpenDatabase failed, hresult %#lx\n", hr);
2635 if (hr == S_OK)
2636 {
2637 test_Database(pDatabase, FALSE);
2638 IDispatch_Release(pDatabase);
2639 }
2640
2641 /* Installer::SummaryInformation */
2642 hr = Installer_SummaryInformation(szPath, 0, &pSumInfo);
2643 ok(hr == S_OK, "Installer_SummaryInformation failed, hresult %#lx\n", hr);
2644 if (hr == S_OK)
2645 {
2647 IDispatch_Release(pSumInfo);
2648 }
2649
2650 hr = Installer_SummaryInformation(NULL, 0, &pSumInfo);
2651 ok(hr == DISP_E_EXCEPTION, "Installer_SummaryInformation failed, hresult %#lx\n", hr);
2652
2653 /* Installer::RegistryValue */
2655
2656 /* Installer::ProductState for our product code, which should not be installed */
2657 hr = Installer_ProductState(L"{837450fa-a39b-4bc8-b321-08b393f784b3}", &iValue);
2658 ok(hr == S_OK, "Installer_ProductState failed, hresult %#lx\n", hr);
2659 ok(iValue == INSTALLSTATE_UNKNOWN, "Installer_ProductState returned %d, expected %d\n", iValue, INSTALLSTATE_UNKNOWN);
2660
2661 /* Installer::ProductInfo for our product code, which should not be installed */
2662
2663 /* Package name */
2664 memset(szPath, 0, sizeof(szPath));
2665 hr = Installer_ProductInfo(L"{837450fa-a39b-4bc8-b321-08b393f784b3}", L"PackageName", szPath);
2666 ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult %#lx\n", hr);
2667 ok_exception(hr, L"ProductInfo,Product,Attribute");
2668
2669 /* NULL attribute and NULL product code */
2670 memset(szPath, 0, sizeof(szPath));
2672 ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult %#lx\n", hr);
2673 ok_exception(hr, L"ProductInfo,Product,Attribute");
2674
2675 /* Installer::Products */
2677
2678 /* Installer::RelatedProducts for our upgrade code, should not find anything */
2679 hr = Installer_RelatedProducts(L"{CE067E8D-2E1A-4367-B734-4EB2BDAD6565}", &pStringList);
2680 ok(hr == S_OK, "Installer_RelatedProducts failed, hresult %#lx\n", hr);
2681 if (hr == S_OK)
2682 {
2683 /* StringList::Count */
2684 hr = StringList_Count(pStringList, &iCount);
2685 ok(hr == S_OK, "StringList_Count failed, hresult %#lx\n", hr);
2686 ok(!iCount, "Expected no related products but found %d\n", iCount);
2687
2688 IDispatch_Release(pStringList);
2689 }
2690
2691 /* Installer::Version */
2692 memset(szPath, 0, sizeof(szPath));
2694 ok(hr == S_OK, "Installer_VersionGet failed, hresult %#lx\n", hr);
2695
2696 /* Installer::InstallProduct and other tests that depend on our product being installed */
2698}
LPCWSTR szPath
Definition: env.c:37
static void test_Installer_Products(BOOL bProductInstalled)
Definition: automation.c:2171
static HRESULT Installer_CreateRecord(int count, IDispatch **pRecord)
Definition: automation.c:882
static HRESULT Record_IntegerDataGet(IDispatch *pRecord, int iField, int *pValue)
Definition: automation.c:1469
static HRESULT StringList_Count(IDispatch *pStringList, int *pCount)
Definition: automation.c:1529
static HRESULT Installer_VersionGet(LPWSTR szVersion)
Definition: automation.c:1080
static HRESULT Installer_SummaryInformation(BSTR PackagePath, int UpdateCount, IDispatch **pSumInfo)
Definition: automation.c:1106
static HRESULT Installer_ProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute, LPWSTR szString)
Definition: automation.c:1033
static void test_Database(IDispatch *pDatabase, BOOL readonly)
Definition: automation.c:1723
static void test_Installer_RegistryValue(void)
Definition: automation.c:2018
static void test_Session(IDispatch *pSession)
Definition: automation.c:1831
static HRESULT Installer_OpenPackage(LPCWSTR szPackagePath, int options, IDispatch **pSession)
Definition: automation.c:962
static void test_Installer_InstallProduct(void)
Definition: automation.c:2382
static HRESULT Installer_ProductState(LPCWSTR szProduct, int *pInstallState)
Definition: automation.c:1016
static HRESULT Record_IntegerDataPut(IDispatch *pRecord, int iField, int iValue)
Definition: automation.c:1486
static HRESULT Installer_RelatedProducts(LPCWSTR szProduct, IDispatch **pStringList)
Definition: automation.c:1064
static HRESULT Record_FieldCountGet(IDispatch *pRecord, int *pFieldCount)
Definition: automation.c:1425
static HRESULT Installer_OpenDatabase(LPCWSTR szDatabasePath, int openmode, IDispatch **pDatabase)
Definition: automation.c:981
@ INSTALLSTATE_UNKNOWN
Definition: msi.h:42
#define MSIDBOPEN_TRANSACT
Definition: msiquery.h:67
#define MSI_NULL_INTEGER
Definition: msiquery.h:32

Referenced by START_TEST().

◆ test_Installer_InstallProduct()

static void test_Installer_InstallProduct ( void  )
static

Definition at line 2382 of file automation.c.

2383{
2384 HRESULT hr;
2386 WCHAR szString[MAX_PATH];
2387 LONG res;
2388 HKEY hkey;
2389 DWORD num, size, type;
2390 int iValue, iCount;
2391 IDispatch *pStringList = NULL;
2393
2394 if (is_process_limited())
2395 {
2396 /* In fact InstallProduct would succeed but then Windows XP
2397 * would not allow us to clean up the registry!
2398 */
2399 skip("Installer_InstallProduct (insufficient privileges)\n");
2400 return;
2401 }
2402
2403 if (is_wow64)
2405
2407
2408 /* Avoid an interactive dialog in case of insufficient privileges. */
2410 ok(hr == S_OK, "Expected UILevel property put invoke to return S_OK, got %#lx\n", hr);
2411
2412 /* Installer::InstallProduct */
2413 hr = Installer_InstallProduct(L"winetest-automation.msi", NULL);
2414 if (hr == DISP_E_EXCEPTION)
2415 {
2416 skip("InstallProduct failed, insufficient rights?\n");
2418 return;
2419 }
2420 ok(hr == S_OK, "Installer_InstallProduct failed, hresult %#lx\n", hr);
2421
2422 /* Installer::ProductState for our product code, which has been installed */
2423 hr = Installer_ProductState(L"{837450fa-a39b-4bc8-b321-08b393f784b3}", &iValue);
2424 ok(hr == S_OK, "Installer_ProductState failed, hresult %#lx\n", hr);
2425 ok(iValue == INSTALLSTATE_DEFAULT, "Installer_ProductState returned %d, expected %d\n", iValue, INSTALLSTATE_DEFAULT);
2426
2427 /* Installer::ProductInfo for our product code */
2428
2429 /* NULL attribute */
2430 memset(szString, 0, sizeof(szString));
2431 hr = Installer_ProductInfo(L"{837450fa-a39b-4bc8-b321-08b393f784b3}", NULL, szString);
2432 ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult %#lx\n", hr);
2433 ok_exception(hr, L"ProductInfo,Product,Attribute");
2434
2435 /* Nonexistent attribute */
2436 memset(szString, 0, sizeof(szString));
2437 hr = Installer_ProductInfo(L"{837450fa-a39b-4bc8-b321-08b393f784b3}", L"winetest-automation.msi", szString);
2438 ok(hr == DISP_E_EXCEPTION, "Installer_ProductInfo failed, hresult %#lx\n", hr);
2439 ok_exception(hr, L"ProductInfo,Product,Attribute");
2440
2441 /* Package name */
2442 memset(szString, 0, sizeof(szString));
2443 hr = Installer_ProductInfo(L"{837450fa-a39b-4bc8-b321-08b393f784b3}", L"PackageName", szString);
2444 ok(hr == S_OK, "Installer_ProductInfo failed, hresult %#lx\n", hr);
2445 todo_wine ok_w2("Installer_ProductInfo returned %s but expected %s\n", szString, L"winetest-automation.msi");
2446
2447 /* Product name */
2448 memset(szString, 0, sizeof(szString));
2449 hr = Installer_ProductInfo(L"{837450fa-a39b-4bc8-b321-08b393f784b3}", L"ProductName", szString);
2450 ok(hr == S_OK, "Installer_ProductInfo failed, hresult %#lx\n", hr);
2451 todo_wine ok_w2("Installer_ProductInfo returned %s but expected %s\n", szString, L"MSITEST");
2452
2453 /* Installer::Products */
2455
2456 /* Installer::RelatedProducts for our upgrade code */
2457 hr = Installer_RelatedProducts(L"{CE067E8D-2E1A-4367-B734-4EB2BDAD6565}", &pStringList);
2458 ok(hr == S_OK, "Installer_RelatedProducts failed, hresult %#lx\n", hr);
2459 if (hr == S_OK)
2460 {
2461 /* StringList::Count */
2462 hr = StringList_Count(pStringList, &iCount);
2463 ok(hr == S_OK, "StringList_Count failed, hresult %#lx\n", hr);
2464 ok(iCount == 1, "Expected one related product but found %d\n", iCount);
2465
2466 /* StringList::Item */
2467 memset(szString, 0, sizeof(szString));
2468 hr = StringList_Item(pStringList, 0, szString);
2469 ok(hr == S_OK, "StringList_Item failed (idx 0, count %d), hresult %#lx\n", iCount, hr);
2470 ok_w2("StringList_Item returned %s but expected %s\n", szString, L"{837450fa-a39b-4bc8-b321-08b393f784b3}");
2471
2472 IDispatch_Release(pStringList);
2473 }
2474
2475 hr = Installer_ProductInfo(L"{837450fa-a39b-4bc8-b321-08b393f784b3}", L"LocalPackage", szString);
2476 ok(hr == S_OK, "Installer_ProductInfo failed, hresult %#lx\n", hr);
2477 DeleteFileW( szString );
2478
2479 /* Check & clean up installed files & registry keys */
2480 ok(delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
2481 ok(delete_pf("msitest\\cabout\\new", FALSE), "Directory not created\n");
2482 ok(delete_pf("msitest\\cabout\\four.txt", TRUE), "File not installed\n");
2483 ok(delete_pf("msitest\\cabout", FALSE), "Directory not created\n");
2484 ok(delete_pf("msitest\\changed\\three.txt", TRUE), "File not installed\n");
2485 ok(delete_pf("msitest\\changed", FALSE), "Directory not created\n");
2486 ok(delete_pf("msitest\\first\\two.txt", TRUE), "File not installed\n");
2487 ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
2488 ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
2489 ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
2490 ok(delete_pf("msitest", FALSE), "Directory not created\n");
2491
2492 res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", &hkey);
2493 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2494
2495 size = MAX_PATH;
2496 type = REG_SZ;
2497 res = RegQueryValueExA(hkey, "Name", NULL, &type, (LPBYTE)path, &size);
2498 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2499 ok(!lstrcmpA(path, "imaname"), "Expected imaname, got %s\n", path);
2500
2501 size = MAX_PATH;
2502 type = REG_SZ;
2503 res = RegQueryValueExA(hkey, "blah", NULL, &type, (LPBYTE)path, &size);
2504 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
2505
2506 size = sizeof(num);
2507 type = REG_DWORD;
2508 res = RegQueryValueExA(hkey, "number", NULL, &type, (LPBYTE)&num, &size);
2509 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2510 ok(num == 314, "Expected 314, got %lu\n", num);
2511
2512 size = MAX_PATH;
2513 type = REG_SZ;
2514 res = RegQueryValueExA(hkey, "OrderTestName", NULL, &type, (LPBYTE)path, &size);
2515 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2516 ok(!lstrcmpA(path, "OrderTestValue"), "Expected imaname, got %s\n", path);
2517
2518 RegCloseKey(hkey);
2519
2520 res = RegDeleteKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest");
2521 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2522
2523 /* Remove registry keys written by RegisterProduct standard action */
2525 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{837450fa-a39b-4bc8-b321-08b393f784b3}",
2527 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2528
2530 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UpgradeCodes\\D8E760ECA1E276347B43E42BDBDA5656", access);
2531 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2532
2534 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData", "af054738b93a8cb43b12803b397f483b", access, &hkey);
2535 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2536
2537 res = delete_registry_key(hkey, "af054738b93a8cb43b12803b397f483b", access);
2538 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2539 RegCloseKey(hkey);
2540
2542 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\Products\\af054738b93a8cb43b12803b397f483b", access);
2543 ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %ld\n", res);
2544
2545 /* Remove registry keys written by PublishProduct standard action */
2546 res = RegOpenKeyA(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Installer", &hkey);
2547 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2548
2549 res = delete_registry_key(hkey, "Products\\af054738b93a8cb43b12803b397f483b", KEY_ALL_ACCESS);
2550 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2551
2552 res = RegDeleteKeyA(hkey, "UpgradeCodes\\D8E760ECA1E276347B43E42BDBDA5656");
2553 ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", res);
2554
2555 RegCloseKey(hkey);
2556
2557 /* Delete installation files we created */
2559}
GLuint res
Definition: glext.h:9613
GLuint GLuint num
Definition: glext.h:9618
#define REG_SZ
Definition: layer.c:22
static void delete_test_files(void)
Definition: automation.c:428
static HRESULT StringList_Item(IDispatch *pStringList, int iIndex, LPWSTR szString)
Definition: automation.c:1512
static void create_test_files(void)
Definition: automation.c:399
static BOOL is_process_limited(void)
Definition: automation.c:221
static BOOL delete_pf(const CHAR *rel_path, BOOL is_file)
Definition: automation.c:414
static HRESULT Installer_UILevelPut(int level)
Definition: automation.c:1092
static HRESULT Installer_InstallProduct(LPCWSTR szPackagePath, LPCWSTR szPropertyValues)
Definition: automation.c:1000
@ INSTALLSTATE_DEFAULT
Definition: msi.h:48
@ INSTALLUILEVEL_NONE
Definition: msi.h:66
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
long LONG
Definition: pedump.c:60
#define REG_DWORD
Definition: sdbapi.c:596
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46

Referenced by test_Installer().

◆ test_Installer_Products()

static void test_Installer_Products ( BOOL  bProductInstalled)
static

Definition at line 2171 of file automation.c.

2172{
2173 WCHAR szString[MAX_PATH];
2174 HRESULT hr;
2175 int idx;
2176 IUnknown *pUnk = NULL;
2177 IEnumVARIANT *pEnum = NULL;
2178 VARIANT var;
2179 ULONG celt;
2180 int iCount, iValue;
2181 IDispatch *pStringList = NULL;
2182 BOOL bProductFound = FALSE;
2183
2184 /* Installer::Products */
2185 hr = Installer_Products(&pStringList);
2186 ok(hr == S_OK, "Installer_Products failed, hresult %#lx\n", hr);
2187 if (hr == S_OK)
2188 {
2189 /* StringList::_NewEnum */
2190 hr = StringList__NewEnum(pStringList, &pUnk);
2191 ok(hr == S_OK, "StringList_NewEnum failed, hresult %#lx\n", hr);
2192 if (hr == S_OK)
2193 {
2194 hr = IUnknown_QueryInterface(pUnk, &IID_IEnumVARIANT, (void **)&pEnum);
2195 ok (hr == S_OK, "IUnknown::QueryInterface returned %#lx\n", hr);
2196 }
2197 if (!pEnum)
2198 skip("IEnumVARIANT tests\n");
2199
2200 /* StringList::Count */
2201 hr = StringList_Count(pStringList, &iCount);
2202 ok(hr == S_OK, "StringList_Count failed, hresult %#lx\n", hr);
2203
2204 for (idx=0; idx<iCount; idx++)
2205 {
2206 /* StringList::Item */
2207 memset(szString, 0, sizeof(szString));
2208 hr = StringList_Item(pStringList, idx, szString);
2209 ok(hr == S_OK, "StringList_Item failed (idx %d, count %d), hresult %#lx\n", idx, iCount, hr);
2210
2211 if (hr == S_OK)
2212 {
2213 /* Installer::ProductState */
2214 hr = Installer_ProductState(szString, &iValue);
2215 ok(hr == S_OK, "Installer_ProductState failed, hresult %#lx\n", hr);
2216 if (hr == S_OK)
2217 ok(iValue == INSTALLSTATE_DEFAULT || iValue == INSTALLSTATE_ADVERTISED,
2218 "Installer_ProductState returned %d, expected %d or %d\n", iValue, INSTALLSTATE_DEFAULT, INSTALLSTATE_ADVERTISED);
2219
2220 /* Not found our product code yet? Check */
2221 if (!bProductFound && !lstrcmpW(szString, L"{837450fa-a39b-4bc8-b321-08b393f784b3}"))
2222 bProductFound = TRUE;
2223
2224 /* IEnumVARIANT::Next */
2225 if (pEnum)
2226 {
2227 hr = IEnumVARIANT_Next(pEnum, 1, &var, &celt);
2228 ok(hr == S_OK, "IEnumVARIANT_Next failed (idx %d, count %d), hresult %#lx\n", idx, iCount, hr);
2229 ok(celt == 1, "%lu items were retrieved, expected 1\n", celt);
2230 ok(V_VT(&var) == VT_BSTR, "IEnumVARIANT_Next returned variant of type %d, expected %d\n", V_VT(&var), VT_BSTR);
2231 ok_w2("%s returned by StringList_Item does not match %s returned by IEnumVARIANT_Next\n", szString, V_BSTR(&var));
2232 VariantClear(&var);
2233 }
2234 }
2235 }
2236
2237 if (bProductInstalled)
2238 {
2239 ok(bProductInstalled == bProductFound, "Product expected to %s installed but product code was %s\n",
2240 bProductInstalled ? "be" : "not be",
2241 bProductFound ? "found" : "not found");
2242 }
2243
2244 if (pEnum)
2245 {
2246 IEnumVARIANT *pEnum2 = NULL;
2247
2248 if (0) /* Crashes on Windows XP */
2249 {
2250 /* IEnumVARIANT::Clone, NULL pointer */
2251 IEnumVARIANT_Clone(pEnum, NULL);
2252 }
2253
2254 /* IEnumVARIANT::Clone */
2255 hr = IEnumVARIANT_Clone(pEnum, &pEnum2);
2256 ok(hr == S_OK, "IEnumVARIANT_Clone failed, hresult %#lx\n", hr);
2257 if (hr == S_OK)
2258 {
2259 /* IEnumVARIANT::Clone is supposed to save the position, but it actually just goes back to the beginning */
2260
2261 /* IEnumVARIANT::Next of the clone */
2262 if (iCount)
2263 {
2264 hr = IEnumVARIANT_Next(pEnum2, 1, &var, &celt);
2265 ok(hr == S_OK, "IEnumVARIANT_Next failed, hresult %#lx\n", hr);
2266 ok(celt == 1, "%lu items were retrieved, expected 0\n", celt);
2267 ok(V_VT(&var) == VT_BSTR, "IEnumVARIANT_Next returned variant of type %d, expected %d\n", V_VT(&var), VT_BSTR);
2268 VariantClear(&var);
2269 }
2270 else
2271 skip("IEnumVARIANT::Next of clone will not return success with 0 products\n");
2272
2273 IEnumVARIANT_Release(pEnum2);
2274 }
2275
2276 /* IEnumVARIANT::Skip should fail */
2277 hr = IEnumVARIANT_Skip(pEnum, 1);
2278 ok(hr == S_FALSE, "IEnumVARIANT_Skip failed, hresult %#lx\n", hr);
2279
2280 /* IEnumVARIANT::Next, NULL variant pointer */
2281 hr = IEnumVARIANT_Next(pEnum, 1, NULL, &celt);
2282 ok(hr == S_FALSE, "IEnumVARIANT_Next failed, hresult %#lx\n", hr);
2283 ok(celt == 0, "%lu items were retrieved, expected 0\n", celt);
2284
2285 /* IEnumVARIANT::Next, should not return any more items */
2286 hr = IEnumVARIANT_Next(pEnum, 1, &var, &celt);
2287 ok(hr == S_FALSE, "IEnumVARIANT_Next failed, hresult %#lx\n", hr);
2288 ok(celt == 0, "%lu items were retrieved, expected 0\n", celt);
2289 VariantClear(&var);
2290
2291 /* IEnumVARIANT::Reset */
2292 hr = IEnumVARIANT_Reset(pEnum);
2293 ok(hr == S_OK, "IEnumVARIANT_Reset failed, hresult %#lx\n", hr);
2294
2295 if (iCount)
2296 {
2297 /* IEnumVARIANT::Skip to the last product */
2298 hr = IEnumVARIANT_Skip(pEnum, iCount-1);
2299 ok(hr == S_OK, "IEnumVARIANT_Skip failed, hresult %#lx\n", hr);
2300
2301 /* IEnumVARIANT::Next should match the very last retrieved value, also makes sure it works with
2302 * NULL celt pointer. */
2303 hr = IEnumVARIANT_Next(pEnum, 1, &var, NULL);
2304 ok(hr == S_OK, "IEnumVARIANT_Next failed (idx %d, count %d), hresult %#lx\n", idx, iCount, hr);
2305 ok(V_VT(&var) == VT_BSTR, "IEnumVARIANT_Next returned variant of type %d, expected %d\n", V_VT(&var), VT_BSTR);
2306 ok_w2("%s returned by StringList_Item does not match %s returned by IEnumVARIANT_Next\n", szString, V_BSTR(&var));
2307 VariantClear(&var);
2308 }
2309 else
2310 skip("IEnumVARIANT::Skip impossible for 0 products\n");
2311 }
2312
2313 /* StringList::Item using an invalid index */
2314 memset(szString, 0, sizeof(szString));
2315 hr = StringList_Item(pStringList, iCount, szString);
2316 ok(hr == DISP_E_BADINDEX, "StringList_Item for an invalid index did not return DISP_E_BADINDEX, hresult %#lx\n", hr);
2317
2318 if (pEnum) IEnumVARIANT_Release(pEnum);
2319 if (pUnk) IUnknown_Release(pUnk);
2320 IDispatch_Release(pStringList);
2321 }
2322}
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4242
const char * var
Definition: shader.c:5666
static HRESULT StringList__NewEnum(IDispatch *pList, IUnknown **ppEnumVARIANT)
Definition: automation.c:1503
static HRESULT Installer_Products(IDispatch **pStringList)
Definition: automation.c:1053
@ INSTALLSTATE_ADVERTISED
Definition: msi.h:44
uint32_t ULONG
Definition: typedefs.h:59
#define S_FALSE
Definition: winerror.h:2357
#define DISP_E_BADINDEX
Definition: winerror.h:2520

Referenced by test_Installer(), and test_Installer_InstallProduct().

◆ test_Installer_RegistryValue()

static void test_Installer_RegistryValue ( void  )
static

Definition at line 2018 of file automation.c.

2019{
2020 static const DWORD qw[2] = { 0x12345678, 0x87654321 };
2021 VARIANT varresult;
2022 VARIANTARG vararg;
2023 WCHAR szString[MAX_PATH];
2024 HKEY hkey, hkey_sub;
2025 HKEY curr_user = (HKEY)1;
2026 HRESULT hr;
2027 BOOL bRet;
2028 LONG lRet;
2029
2030 /* Delete keys */
2031 SetLastError(0xdeadbeef);
2032 lRet = RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Test", &hkey );
2033 if (!lRet && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2034 {
2035 win_skip("Needed W-functions are not implemented\n");
2036 return;
2037 }
2038 if (!lRet)
2039 delete_key( hkey );
2040
2041 /* Does our key exist? Shouldn't; check with all three possible value parameter types */
2042 hr = Installer_RegistryValueE(curr_user, L"Software\\Wine\\Test", &bRet);
2043 ok(hr == S_OK, "Installer_RegistryValueE failed, hresult %#lx\n", hr);
2044 ok(!bRet, "Registry key expected to not exist, but Installer_RegistryValue claims it does\n");
2045
2046 memset(szString, 0, sizeof(szString));
2047 hr = Installer_RegistryValueW(curr_user, L"Software\\Wine\\Test", NULL, szString);
2048 ok(hr == DISP_E_BADINDEX, "Installer_RegistryValueW failed, hresult %#lx\n", hr);
2049
2050 memset(szString, 0, sizeof(szString));
2051 hr = Installer_RegistryValueI(curr_user, L"Software\\Wine\\Test", 0, szString, VT_BSTR);
2052 ok(hr == DISP_E_BADINDEX, "Installer_RegistryValueI failed, hresult %#lx\n", hr);
2053
2054 /* Create key */
2055 ok(!RegCreateKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Test", &hkey ), "RegCreateKeyW failed\n");
2056
2057 ok(!RegSetValueExW(hkey, L"One", 0, REG_SZ, (const BYTE *)L"One", sizeof(L"one")),
2058 "RegSetValueExW failed\n");
2059 ok(!RegSetValueExW(hkey, L"Two", 0, REG_DWORD, (const BYTE *)qw, 4),
2060 "RegSetValueExW failed\n");
2061 ok(!RegSetValueExW(hkey, L"Three", 0, REG_BINARY, (const BYTE *)qw, 4),
2062 "RegSetValueExW failed\n");
2063 bRet = SetEnvironmentVariableA("MSITEST", "Four");
2064 ok(bRet, "SetEnvironmentVariableA failed %lu\n", GetLastError());
2065 ok(!RegSetValueExW(hkey, L"Four", 0, REG_EXPAND_SZ, (const BYTE *)L"%MSITEST%", sizeof(L"%MSITEST%")),
2066 "RegSetValueExW failed\n");
2067 ok(!RegSetValueExW(hkey, L"Five\0Hi\0", 0, REG_MULTI_SZ, (const BYTE *)L"Five\0Hi\0", sizeof(L"Five\0Hi\0")),
2068 "RegSetValueExW failed\n");
2069 ok(!RegSetValueExW(hkey, L"Six", 0, REG_QWORD, (const BYTE *)qw, 8),
2070 "RegSetValueExW failed\n");
2071 ok(!RegSetValueExW(hkey, L"Seven", 0, REG_NONE, NULL, 0),
2072 "RegSetValueExW failed\n");
2073
2074 ok(!RegSetValueExW(hkey, NULL, 0, REG_SZ, (const BYTE *)L"One", sizeof(L"One")),
2075 "RegSetValueExW failed\n");
2076
2077 ok(!RegCreateKeyW( hkey, L"Eight", &hkey_sub ), "RegCreateKeyW failed\n");
2078
2079 /* Does our key exist? It should, and make sure we retrieve the correct default value */
2080 bRet = FALSE;
2081 hr = Installer_RegistryValueE(curr_user, L"Software\\Wine\\Test", &bRet);
2082 ok(hr == S_OK, "Installer_RegistryValueE failed, hresult %#lx\n", hr);
2083 ok(bRet, "Registry key expected to exist, but Installer_RegistryValue claims it does not\n");
2084
2085 memset(szString, 0, sizeof(szString));
2086 hr = Installer_RegistryValueW(curr_user, L"Software\\Wine\\Test", NULL, szString);
2087 ok(hr == S_OK, "Installer_RegistryValueW failed, hresult %#lx\n", hr);
2088 ok_w2("Default registry value \"%s\" does not match expected \"%s\"\n", szString, L"One");
2089
2090 /* Ask for the value of a nonexistent key */
2091 memset(szString, 0, sizeof(szString));
2092 hr = Installer_RegistryValueW(curr_user, L"Software\\Wine\\Test", L"%MSITEST%", szString);
2093 ok(hr == DISP_E_BADINDEX, "Installer_RegistryValueW failed, hresult %#lx\n", hr);
2094
2095 /* Get values of keys */
2096 memset(szString, 0, sizeof(szString));
2097 hr = Installer_RegistryValueW(curr_user, L"Software\\Wine\\Test", L"One", szString);
2098 ok(hr == S_OK, "Installer_RegistryValueW failed, hresult %#lx\n", hr);
2099 ok_w2("Registry value \"%s\" does not match expected \"%s\"\n", szString, L"One");
2100
2101 VariantInit(&vararg);
2102 V_VT(&vararg) = VT_BSTR;
2103 V_BSTR(&vararg) = SysAllocString(L"Two");
2104 hr = Installer_RegistryValue(curr_user, L"Software\\Wine\\Test", vararg, &varresult, VT_I4);
2105 ok(hr == S_OK, "Installer_RegistryValue failed, hresult %#lx\n", hr);
2106 ok(V_I4(&varresult) == 305419896, "Registry value %ld does not match expected value\n", V_I4(&varresult));
2107 VariantClear(&varresult);
2108
2109 memset(szString, 0, sizeof(szString));
2110 hr = Installer_RegistryValueW(curr_user, L"Software\\Wine\\Test", L"Three", szString);
2111 ok(hr == S_OK, "Installer_RegistryValueW failed, hresult %#lx\n", hr);
2112 ok_w2("Registry value \"%s\" does not match expected \"%s\"\n", szString, L"(REG_BINARY)");
2113
2114 memset(szString, 0, sizeof(szString));
2115 hr = Installer_RegistryValueW(curr_user, L"Software\\Wine\\Test", L"Four", szString);
2116 ok(hr == S_OK, "Installer_RegistryValueW failed, hresult %#lx\n", hr);
2117 ok_w2("Registry value \"%s\" does not match expected \"%s\"\n", szString, L"Four");
2118
2119 /* Vista does not NULL-terminate this case */
2120 memset(szString, 0, sizeof(szString));
2121 hr = Installer_RegistryValueW(curr_user, L"Software\\Wine\\Test", L"Five\0Hi\0", szString);
2122 ok(hr == S_OK, "Installer_RegistryValueW failed, hresult %#lx\n", hr);
2123 ok_w2n("Registry value \"%s\" does not match expected \"%s\"\n",
2124 szString, L"Five\nHi", lstrlenW(L"Five\nHi"));
2125
2126 memset(szString, 0, sizeof(szString));
2127 hr = Installer_RegistryValueW(curr_user, L"Software\\Wine\\Test", L"Six", szString);
2128 ok(hr == S_OK, "Installer_RegistryValueW failed, hresult %#lx\n", hr);
2129 ok(!lstrcmpW(szString, L"(REG_\?\?)") || broken(!lstrcmpW(szString, L"(REG_]")),
2130 "Registry value does not match\n");
2131
2132 VariantInit(&vararg);
2133 V_VT(&vararg) = VT_BSTR;
2134 V_BSTR(&vararg) = SysAllocString(L"Seven");
2135 hr = Installer_RegistryValue(curr_user, L"Software\\Wine\\Test", vararg, &varresult, VT_EMPTY);
2136 ok(hr == S_OK, "Installer_RegistryValue failed, hresult %#lx\n", hr);
2137
2138 /* Get string class name for the key */
2139 memset(szString, 0, sizeof(szString));
2140 hr = Installer_RegistryValueI(curr_user, L"Software\\Wine\\Test", 0, szString, VT_BSTR);
2141 ok(hr == S_OK, "Installer_RegistryValueI failed, hresult %#lx\n", hr);
2142 ok_w2("Registry name \"%s\" does not match expected \"%s\"\n", szString, L"");
2143
2144 /* Get name of a value by positive number (RegEnumValue like), valid index */
2145 memset(szString, 0, sizeof(szString));
2146 hr = Installer_RegistryValueI(curr_user, L"Software\\Wine\\Test", 2, szString, VT_BSTR);
2147 ok(hr == S_OK, "Installer_RegistryValueI failed, hresult %#lx\n", hr);
2148 /* RegEnumValue order seems different on wine */
2149 todo_wine ok_w2("Registry name \"%s\" does not match expected \"%s\"\n", szString, L"Two");
2150
2151 /* Get name of a value by positive number (RegEnumValue like), invalid index */
2152 memset(szString, 0, sizeof(szString));
2153 hr = Installer_RegistryValueI(curr_user, L"Software\\Wine\\Test", 10, szString, VT_EMPTY);
2154 ok(hr == S_OK, "Installer_RegistryValueI failed, hresult %#lx\n", hr);
2155
2156 /* Get name of a subkey by negative number (RegEnumValue like), valid index */
2157 memset(szString, 0, sizeof(szString));
2158 hr = Installer_RegistryValueI(curr_user, L"Software\\Wine\\Test", -1, szString, VT_BSTR);
2159 ok(hr == S_OK, "Installer_RegistryValueI failed, hresult %#lx\n", hr);
2160 ok_w2("Registry name \"%s\" does not match expected \"%s\"\n", szString, L"Eight");
2161
2162 /* Get name of a subkey by negative number (RegEnumValue like), invalid index */
2163 memset(szString, 0, sizeof(szString));
2164 hr = Installer_RegistryValueI(curr_user, L"Software\\Wine\\Test", -10, szString, VT_EMPTY);
2165 ok(hr == S_OK, "Installer_RegistryValueI failed, hresult %#lx\n", hr);
2166
2167 /* clean up */
2168 delete_key(hkey);
2169}
#define broken(x)
Definition: _sntprintf.h:21
HANDLE HKEY
Definition: registry.h:26
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define SetLastError(x)
Definition: compat.h:752
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableA(IN LPCSTR lpName, IN LPCSTR lpValue)
Definition: environ.c:218
#define ok_w2n(format, szString1, szString2, len)
Definition: automation.c:460
static HRESULT Installer_RegistryValueE(HKEY hkey, LPCWSTR szKey, BOOL *pBool)
Definition: automation.c:916
static HRESULT Installer_RegistryValueI(HKEY hkey, LPCWSTR szKey, int iValue, LPWSTR szString, VARTYPE vtResult)
Definition: automation.c:946
static HRESULT Installer_RegistryValueW(HKEY hkey, LPCWSTR szKey, LPCWSTR szValue, LPWSTR szString)
Definition: automation.c:930
#define REG_BINARY
Definition: nt_native.h:1496
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define REG_NONE
Definition: nt_native.h:1492
#define REG_QWORD
Definition: sdbapi.c:597
#define win_skip
Definition: test.h:163
unsigned char BYTE
Definition: xxhash.c:193

Referenced by test_Installer().

◆ test_Session()

static void test_Session ( IDispatch pSession)
static

Definition at line 1831 of file automation.c.

1832{
1834 CHAR string[MAX_PATH];
1835 UINT len;
1837 int myint;
1838 IDispatch *pDatabase = NULL, *pInst = NULL, *record = NULL;
1839 ULONG refs_before, refs_after;
1840 HRESULT hr;
1841
1842 /* Session::Installer */
1843 hr = Session_Installer(pSession, &pInst);
1844 ok(hr == S_OK, "Session_Installer failed, hresult %#lx\n", hr);
1845 ok(pInst != NULL, "Session_Installer returned NULL IDispatch pointer\n");
1846 ok(pInst == pInstaller, "Session_Installer does not match Installer instance from CoCreateInstance\n");
1847 refs_before = IDispatch_AddRef(pInst);
1848
1849 hr = Session_Installer(pSession, &pInst);
1850 ok(hr == S_OK, "Session_Installer failed, hresult %#lx\n", hr);
1851 ok(pInst != NULL, "Session_Installer returned NULL IDispatch pointer\n");
1852 ok(pInst == pInstaller, "Session_Installer does not match Installer instance from CoCreateInstance\n");
1853 refs_after = IDispatch_Release(pInst);
1854 ok(refs_before == refs_after, "got %lu and %lu\n", refs_before, refs_after);
1855
1856 /* Session::Property, get */
1857 memset(stringw, 0, sizeof(stringw));
1858 hr = Session_PropertyGet(pSession, L"ProductName", stringw);
1859 ok(hr == S_OK, "Session_PropertyGet failed, hresult %#lx\n", hr);
1860 if (lstrcmpW(stringw, L"MSITEST") != 0)
1861 {
1862 len = WideCharToMultiByte(CP_ACP, 0, stringw, -1, string, MAX_PATH, NULL, NULL);
1863 ok(len, "WideCharToMultiByteChar returned error %lu\n", GetLastError());
1864 ok(0, "Property \"ProductName\" expected to be \"MSITEST\" but was \"%s\"\n", string);
1865 }
1866
1867 /* Session::Property, put */
1868 hr = Session_PropertyPut(pSession, L"ProductName", L"ProductName");
1869 ok(hr == S_OK, "Session_PropertyPut failed, hresult %#lx\n", hr);
1870 memset(stringw, 0, sizeof(stringw));
1871 hr = Session_PropertyGet(pSession, L"ProductName", stringw);
1872 ok(hr == S_OK, "Session_PropertyGet failed, hresult %#lx\n", hr);
1873 if (lstrcmpW(stringw, L"ProductName") != 0)
1874 {
1875 len = WideCharToMultiByte(CP_ACP, 0, stringw, -1, string, MAX_PATH, NULL, NULL);
1876 ok(len, "WideCharToMultiByteChar returned error %lu\n", GetLastError());
1877 ok(0, "Property \"ProductName\" expected to be \"ProductName\" but was \"%s\"\n", string);
1878 }
1879
1880 /* Try putting a property using empty property identifier */
1881 hr = Session_PropertyPut(pSession, L"", L"ProductName");
1882 ok(hr == DISP_E_EXCEPTION, "Session_PropertyPut failed, hresult %#lx\n", hr);
1883 ok_exception(hr, L"Property,Name");
1884
1885 /* Try putting a property using illegal property identifier */
1886 hr = Session_PropertyPut(pSession, L"=", L"ProductName");
1887 ok(hr == S_OK, "Session_PropertyPut failed, hresult %#lx\n", hr);
1888
1889 /* Session::Language, get */
1890 hr = Session_LanguageGet(pSession, &len);
1891 ok(hr == S_OK, "Session_LanguageGet failed, hresult %#lx\n", hr);
1892 /* Not sure how to check the language is correct */
1893
1894 /* Session::Mode, get */
1895 hr = Session_ModeGet(pSession, MSIRUNMODE_REBOOTATEND, &bool);
1896 ok(hr == S_OK, "Session_ModeGet failed, hresult %#lx\n", hr);
1897 ok(!bool, "Reboot at end session mode is %d\n", bool);
1898
1899 hr = Session_ModeGet(pSession, MSIRUNMODE_MAINTENANCE, &bool);
1900 ok(hr == S_OK, "Session_ModeGet failed, hresult %#lx\n", hr);
1901 ok(!bool, "Maintenance mode is %d\n", bool);
1902
1903 /* Session::Mode, put */
1904 hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTATEND, VARIANT_TRUE);
1905 ok(hr == S_OK, "Session_ModePut failed, hresult %#lx\n", hr);
1906 hr = Session_ModeGet(pSession, MSIRUNMODE_REBOOTATEND, &bool);
1907 ok(hr == S_OK, "Session_ModeGet failed, hresult %#lx\n", hr);
1908 ok(bool, "Reboot at end session mode is %d, expected 1\n", bool);
1909 hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTATEND, VARIANT_FALSE); /* set it again so we don't reboot */
1910 ok(hr == S_OK, "Session_ModePut failed, hresult %#lx\n", hr);
1911
1912 hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTNOW, VARIANT_TRUE);
1913 ok(hr == S_OK, "Session_ModePut failed, hresult %#lx\n", hr);
1914 ok_exception(hr, L"Mode,Flag");
1915
1916 hr = Session_ModeGet(pSession, MSIRUNMODE_REBOOTNOW, &bool);
1917 ok(hr == S_OK, "Session_ModeGet failed, hresult %#lx\n", hr);
1918 ok(bool, "Reboot now mode is %d, expected 1\n", bool);
1919
1920 hr = Session_ModePut(pSession, MSIRUNMODE_REBOOTNOW, VARIANT_FALSE); /* set it again so we don't reboot */
1921 ok(hr == S_OK, "Session_ModePut failed, hresult %#lx\n", hr);
1922 ok_exception(hr, L"Mode,Flag");
1923
1924 hr = Session_ModePut(pSession, MSIRUNMODE_MAINTENANCE, VARIANT_TRUE);
1925 ok(hr == DISP_E_EXCEPTION, "Session_ModePut failed, hresult %#lx\n", hr);
1926 ok_exception(hr, L"Mode,Flag");
1927
1928 /* Session::Database, get */
1929 hr = Session_Database(pSession, &pDatabase);
1930 ok(hr == S_OK, "Session_Database failed, hresult %#lx\n", hr);
1931 if (hr == S_OK)
1932 {
1933 test_Database(pDatabase, TRUE);
1934 IDispatch_Release(pDatabase);
1935 }
1936
1937 /* Session::EvaluateCondition */
1938 hr = Session_EvaluateCondition(pSession, NULL, &myint);
1939 ok(hr == S_OK, "Session_EvaluateCondition failed, hresult %#lx\n", hr);
1940 ok(myint == MSICONDITION_NONE, "Feature current state was %d but expected %d\n", myint, INSTALLSTATE_UNKNOWN);
1941
1942 hr = Session_EvaluateCondition(pSession, L"", &myint);
1943 ok(hr == S_OK, "Session_EvaluateCondition failed, hresult %#lx\n", hr);
1944 ok(myint == MSICONDITION_NONE, "Feature current state was %d but expected %d\n", myint, INSTALLSTATE_UNKNOWN);
1945
1946 hr = Session_EvaluateCondition(pSession, L"=", &myint);
1947 ok(hr == S_OK, "Session_EvaluateCondition failed, hresult %#lx\n", hr);
1948 ok(myint == MSICONDITION_ERROR, "Feature current state was %d but expected %d\n", myint, INSTALLSTATE_UNKNOWN);
1949
1950 /* Session::DoAction(CostInitialize) must occur before the next statements */
1951 hr = Session_DoAction(pSession, L"CostInitialize", &myint);
1952 ok(hr == S_OK, "Session_DoAction failed, hresult %#lx\n", hr);
1953 ok(myint == IDOK, "DoAction(CostInitialize) returned %d, %d expected\n", myint, IDOK);
1954
1955 /* Session::SetInstallLevel */
1957 ok(hr == S_OK, "Session_SetInstallLevel failed, hresult %#lx\n", hr);
1958
1959 /* Session::FeatureCurrentState, get */
1960 hr = Session_FeatureCurrentState(pSession, L"One", &myint);
1961 ok(hr == S_OK, "Session_FeatureCurrentState failed, hresult %#lx\n", hr);
1962 ok(myint == INSTALLSTATE_UNKNOWN, "Feature current state was %d but expected %d\n", myint, INSTALLSTATE_UNKNOWN);
1963
1964 /* Session::Message */
1966 ok(hr == S_OK, "Installer_CreateRecord failed: %#lx\n", hr);
1967 hr = Session_Message(pSession, INSTALLMESSAGE_INFO, record, &myint);
1968 ok(hr == S_OK, "Session_Message failed: %#lx\n", hr);
1969 ok(myint == 0, "Session_Message returned %x\n", myint);
1970
1971 /* Session::EvaluateCondition */
1972 hr = Session_EvaluateCondition(pSession, L"!One>0", &myint);
1973 ok(hr == S_OK, "Session_EvaluateCondition failed, hresult %#lx\n", hr);
1974 ok(myint == MSICONDITION_FALSE, "Feature current state was %d but expected %d\n", myint, INSTALLSTATE_UNKNOWN);
1975
1976 hr = Session_EvaluateCondition(pSession, L"!One=-1", &myint);
1977 ok(hr == S_OK, "Session_EvaluateCondition failed, hresult %#lx\n", hr);
1978 ok(myint == MSICONDITION_TRUE, "Feature current state was %d but expected %d\n", myint, INSTALLSTATE_UNKNOWN);
1979
1980 /* Session::FeatureRequestState, put */
1982 ok(hr == S_OK, "Session_FeatureRequestStatePut failed, hresult %#lx\n", hr);
1983 hr = Session_FeatureRequestStateGet(pSession, L"One", &myint);
1984 ok(hr == S_OK, "Session_FeatureRequestStateGet failed, hresult %#lx\n", hr);
1985 ok(myint == INSTALLSTATE_ADVERTISED, "Feature request state was %d but expected %d\n", myint, INSTALLSTATE_ADVERTISED);
1986
1987 /* Session::EvaluateCondition */
1988 hr = Session_EvaluateCondition(pSession, L"$One=-1", &myint);
1989 ok(hr == S_OK, "Session_EvaluateCondition failed, hresult %#lx\n", hr);
1990 ok(myint == MSICONDITION_FALSE, "Feature current state was %d but expected %d\n", myint, INSTALLSTATE_UNKNOWN);
1991
1992 hr = Session_EvaluateCondition(pSession, L"$One>0", &myint);
1993 ok(hr == S_OK, "Session_EvaluateCondition failed, hresult %#lx\n", hr);
1994 ok(myint == MSICONDITION_TRUE, "Feature current state was %d but expected %d\n", myint, INSTALLSTATE_UNKNOWN);
1995}
#define WideCharToMultiByte
Definition: compat.h:111
short VARIANT_BOOL
Definition: compat.h:2290
static HRESULT Session_DoAction(IDispatch *pSession, LPCWSTR szAction, int *iReturn)
Definition: automation.c:1227
static HRESULT Session_Database(IDispatch *pSession, IDispatch **pDatabase)
Definition: automation.c:1216
static HRESULT Session_LanguageGet(IDispatch *pSession, UINT *pLangId)
Definition: automation.c:1170
static HRESULT Session_PropertyGet(IDispatch *pSession, LPCWSTR szName, LPWSTR szReturn)
Definition: automation.c:1136
static HRESULT Session_EvaluateCondition(IDispatch *pSession, LPCWSTR szCondition, int *iReturn)
Definition: automation.c:1244
static HRESULT Session_SetInstallLevel(IDispatch *pSession, LONG iInstallLevel)
Definition: automation.c:1282
static HRESULT Session_ModePut(IDispatch *pSession, int iFlag, VARIANT_BOOL mode)
Definition: automation.c:1199
static HRESULT Session_FeatureRequestStateGet(IDispatch *pSession, LPCWSTR szName, int *pState)
Definition: automation.c:1312
static HRESULT Session_Installer(IDispatch *pSession, IDispatch **pInst)
Definition: automation.c:1125
static HRESULT Session_FeatureRequestStatePut(IDispatch *pSession, LPCWSTR szName, int iState)
Definition: automation.c:1329
static HRESULT Session_PropertyPut(IDispatch *pSession, LPCWSTR szName, LPCWSTR szValue)
Definition: automation.c:1153
static HRESULT Session_ModeGet(IDispatch *pSession, int iFlag, VARIANT_BOOL *mode)
Definition: automation.c:1182
static HRESULT Session_FeatureCurrentState(IDispatch *pSession, LPCWSTR szName, int *pState)
Definition: automation.c:1295
static HRESULT Session_Message(IDispatch *pSession, LONG kind, IDispatch *record, int *ret)
Definition: automation.c:1261
@ INSTALLMESSAGE_INFO
Definition: msi.h:98
@ INSTALLLEVEL_MINIMUM
Definition: msi.h:88
@ MSICONDITION_FALSE
Definition: msiquery.h:26
@ MSICONDITION_ERROR
Definition: msiquery.h:29
@ MSICONDITION_NONE
Definition: msiquery.h:28
@ MSICONDITION_TRUE
Definition: msiquery.h:27
@ MSIRUNMODE_MAINTENANCE
Definition: msiquery.h:85
@ MSIRUNMODE_REBOOTATEND
Definition: msiquery.h:89
@ MSIRUNMODE_REBOOTNOW
Definition: msiquery.h:90
#define bool
Definition: nsiface.idl:72
static char * stringw(char *buf, char *end, const wchar_t *sw, int len, int field_width, int precision, int flags)
Definition: sprintf.c:335
#define IDOK
Definition: winuser.h:830

Referenced by test_Installer().

◆ test_SummaryInfo()

static void test_SummaryInfo ( IDispatch pSummaryInfo,
const msi_summary_info info,
int  num_info,
BOOL  readonly 
)
static

Definition at line 1582 of file automation.c.

1583{
1584 VARIANT varresult, var;
1585 SYSTEMTIME st;
1586 HRESULT hr;
1587 int j;
1588
1589 /* SummaryInfo::PropertyCount */
1590 hr = SummaryInfo_PropertyCountGet(pSummaryInfo, &j);
1591 ok(hr == S_OK, "SummaryInfo_PropertyCount failed, hresult %#lx\n", hr);
1592 ok(j == num_info, "SummaryInfo_PropertyCount returned %d, expected %d\n", j, num_info);
1593
1594 /* SummaryInfo::Property, get for properties we have set */
1595 for (j = 0; j < num_info; j++)
1596 {
1597 const msi_summary_info *entry = &info[j];
1598
1599 int vt = entry->datatype;
1600 if (vt == VT_LPSTR) vt = VT_BSTR;
1601 else if (vt == VT_FILETIME) vt = VT_DATE;
1602 else if (vt == VT_I2) vt = VT_I4;
1603
1604 hr = SummaryInfo_PropertyGet(pSummaryInfo, entry->property, &varresult, vt);
1605 ok(hr == S_OK, "SummaryInfo_Property (pid %d) failed, hresult %#lx\n", entry->property, hr);
1606 if (V_VT(&varresult) != vt)
1607 skip("Skipping property tests due to type mismatch\n");
1608 else if (vt == VT_I4)
1609 ok(V_I4(&varresult) == entry->iValue, "SummaryInfo_Property (pid %d) I4 result expected to be %d, but was %ld\n",
1610 entry->property, entry->iValue, V_I4(&varresult));
1611 else if (vt == VT_DATE)
1612 {
1613 FILETIME ft;
1614 DATE d;
1615
1616 FileTimeToLocalFileTime(entry->pftValue, &ft);
1617 FileTimeToSystemTime(&ft, &st);
1619 ok(d == V_DATE(&varresult), "SummaryInfo_Property (pid %d) DATE result expected to be %lf, but was %lf\n", entry->property, d, V_DATE(&varresult));
1620 }
1621 else if (vt == VT_BSTR)
1622 {
1623 ok_awplus("SummaryInfo_Property (pid %d) BSTR result expected to be %s, but was %s\n", entry->property, entry->szValue, V_BSTR(&varresult));
1624 }
1625 else
1626 skip("SummaryInfo_Property (pid %d) unhandled result type %d\n", entry->property, vt);
1627
1628 VariantClear(&varresult);
1629 }
1630
1631 /* SummaryInfo::Property, get; invalid arguments */
1632
1633 /* Invalid pids */
1634 hr = SummaryInfo_PropertyGet(pSummaryInfo, -1, &varresult, VT_EMPTY);
1635 ok(hr == DISP_E_EXCEPTION, "SummaryInfo_PropertyGet failed, hresult %#lx\n", hr);
1636 ok_exception(hr, L"Property,Pid");
1637
1638 hr = SummaryInfo_PropertyGet(pSummaryInfo, 1000, &varresult, VT_EMPTY);
1639 ok(hr == DISP_E_EXCEPTION, "SummaryInfo_PropertyGet failed, hresult %#lx\n", hr);
1640 ok_exception(hr, L"Property,Pid");
1641
1642 /* Unsupported pids */
1643 hr = SummaryInfo_PropertyGet(pSummaryInfo, PID_DICTIONARY, &varresult, VT_EMPTY);
1644 ok(hr == S_OK, "SummaryInfo_PropertyGet failed, hresult %#lx\n", hr);
1645
1646 hr = SummaryInfo_PropertyGet(pSummaryInfo, PID_THUMBNAIL, &varresult, VT_EMPTY);
1647 ok(hr == S_OK, "SummaryInfo_PropertyGet failed, hresult %#lx\n", hr);
1648
1649 /* Pids we have not set, one for each type */
1650 hr = SummaryInfo_PropertyGet(pSummaryInfo, PID_CODEPAGE, &varresult, VT_EMPTY);
1651 ok(hr == S_OK, "SummaryInfo_PropertyGet failed, hresult %#lx\n", hr);
1652
1653 hr = SummaryInfo_PropertyGet(pSummaryInfo, PID_TITLE, &varresult, VT_EMPTY);
1654 ok(hr == S_OK, "SummaryInfo_PropertyGet failed, hresult %#lx\n", hr);
1655
1656 hr = SummaryInfo_PropertyGet(pSummaryInfo, PID_EDITTIME, &varresult, VT_EMPTY);
1657 ok(hr == S_OK, "SummaryInfo_PropertyGet failed, hresult %#lx\n", hr);
1658
1659 hr = SummaryInfo_PropertyGet(pSummaryInfo, PID_CHARCOUNT, &varresult, VT_EMPTY);
1660 ok(hr == S_OK, "SummaryInfo_PropertyGet failed, hresult %#lx\n", hr);
1661
1662 if (!readonly)
1663 {
1664 /* SummaryInfo::Property, put; one for each type */
1665
1666 /* VT_I2 */
1667 VariantInit(&var);
1668 V_VT(&var) = VT_I2;
1669 V_I2(&var) = 1;
1670 hr = SummaryInfo_PropertyPut(pSummaryInfo, PID_CODEPAGE, &var);
1671 ok(hr == S_OK, "SummaryInfo_PropertyPut failed, hresult %#lx\n", hr);
1672
1673 hr = SummaryInfo_PropertyGet(pSummaryInfo, PID_CODEPAGE, &varresult, VT_I4 /* NOT VT_I2 */);
1674 ok(hr == S_OK, "SummaryInfo_PropertyGet failed, hresult %#lx\n", hr);
1675 ok(V_I2(&var) == V_I2(&varresult), "SummaryInfo_PropertyGet expected %d, but returned %d\n", V_I2(&var), V_I2(&varresult));
1676 VariantClear(&varresult);
1677 VariantClear(&var);
1678
1679 /* VT_BSTR */
1680 V_VT(&var) = VT_BSTR;
1681 V_BSTR(&var) = SysAllocString(L"Title");
1682 hr = SummaryInfo_PropertyPut(pSummaryInfo, PID_TITLE, &