ReactOS 0.4.17-dev-966-gf06eace
custom.c File Reference
#include <stdarg.h>
#include <stdio.h>
#include "ntstatus.h"
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "msidefs.h"
#include "winuser.h"
#include "objbase.h"
#include "oleauto.h"
#include "msipriv.h"
#include "winemsi.h"
#include "wine/asm.h"
#include "wine/debug.h"
#include "wine/exception.h"
Include dependency graph for custom.c:

Go to the source code of this file.

Classes

struct  running_action
 
struct  custom_action_info
 

Macros

#define COBJMACROS
 
#define WIN32_NO_STATUS
 
#define CUSTOM_ACTION_TYPE_MASK   0x3F
 

Typedefs

typedef UINT(WINAPI * MsiCustomActionEntryPoint) (MSIHANDLE)
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msi)
 
void __RPC_FAR *__RPC_USER MIDL_user_allocate (SIZE_T len)
 
void __RPC_USER MIDL_user_free (void __RPC_FAR *ptr)
 
LONG WINAPI rpc_filter (EXCEPTION_POINTERS *eptr)
 
UINT msi_schedule_action (MSIPACKAGE *package, UINT script, const WCHAR *action)
 
UINT msi_register_unique_action (MSIPACKAGE *package, const WCHAR *action)
 
BOOL msi_action_is_unique (const MSIPACKAGE *package, const WCHAR *action)
 
static BOOL check_execution_scheduling_options (MSIPACKAGE *package, LPCWSTR action, UINT options)
 
static WCHAR * get_deferred_action (const WCHAR *action, const WCHAR *actiondata, const WCHAR *usersid, const WCHAR *prodcode)
 
static void set_deferred_action_props (MSIPACKAGE *package, const WCHAR *deferred_data)
 
WCHAR * msi_create_temp_file (MSIDATABASE *db)
 
static MSIBINARY * create_temp_binary (MSIPACKAGE *package, LPCWSTR source)
 
static MSIBINARY * get_temp_binary (MSIPACKAGE *package, LPCWSTR source)
 
static void file_running_action (MSIPACKAGE *package, HANDLE Handle, BOOL process, LPCWSTR name)
 
static UINT custom_get_process_return (HANDLE process)
 
static UINT custom_get_thread_return (MSIPACKAGE *package, HANDLE thread)
 
static UINT wait_process_handle (MSIPACKAGE *package, UINT type, HANDLE ProcessHandle, LPCWSTR name)
 
static void free_custom_action_data (custom_action_info *info)
 
static UINT wait_thread_handle (custom_action_info *info)
 
static custom_action_info * find_action_by_guid (const GUID *guid)
 
static void handle_msi_break (const WCHAR *action)
 
static UINT custom_proc_wrapper (MsiCustomActionEntryPoint entry, MSIHANDLE hinst)
 
UINT CDECL __wine_msi_call_dll_function (DWORD client_pid, const GUID *guid)
 
static HANDLE get_admin_token (void)
 
static DWORD custom_start_server (MSIPACKAGE *package, DWORD arch)
 
void custom_stop_server (HANDLE process, HANDLE pipe)
 
static DWORD WINAPI custom_client_thread (void *arg)
 
static BOOL get_binary_type (const WCHAR *name, DWORD *type)
 
static custom_action_info * do_msidbCustomActionTypeDll (MSIPACKAGE *package, INT type, LPCWSTR source, LPCWSTR target, LPCWSTR action)
 
static UINT HANDLE_CustomType1 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static HANDLE execute_command (const WCHAR *app, WCHAR *arg, const WCHAR *dir)
 
static UINT HANDLE_CustomType2 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static UINT HANDLE_CustomType17 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static UINT HANDLE_CustomType18 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static UINT HANDLE_CustomType19 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static WCHAR * build_msiexec_args (const WCHAR *filename, const WCHAR *params)
 
static UINT HANDLE_CustomType23 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static UINT write_substorage_to_file (MSIPACKAGE *package, const WCHAR *source, const WCHAR *filename)
 
static UINT HANDLE_CustomType7 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static UINT HANDLE_CustomType50 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static UINT HANDLE_CustomType34 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static DWORD ACTION_CallScript (const GUID *guid)
 
static DWORD WINAPI ScriptThread (LPVOID arg)
 
static custom_action_info * do_msidbCustomActionTypeScript (MSIPACKAGE *package, INT type, LPCWSTR script, LPCWSTR function, LPCWSTR action)
 
static UINT HANDLE_CustomType37_38 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static UINT HANDLE_CustomType5_6 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static UINT HANDLE_CustomType21_22 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static UINT HANDLE_CustomType53_54 (MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
 
static BOOL action_type_matches_script (UINT type, UINT script)
 
static UINT defer_custom_action (MSIPACKAGE *package, const WCHAR *action, UINT type)
 
UINT ACTION_CustomAction (MSIPACKAGE *package, const WCHAR *action)
 
void ACTION_FinishCustomActions (const MSIPACKAGE *package)
 
UINT __cdecl s_remote_GetActionInfo (const GUID *guid, WCHAR **name, int *type, WCHAR **dll, char **func, MSIHANDLE *hinst)
 

Variables

static CRITICAL_SECTION custom_action_cs = { &custom_action_cs_debug, -1, 0, 0, 0, 0 }
 
static CRITICAL_SECTION_DEBUG custom_action_cs_debug
 
static struct list pending_custom_actions = LIST_INIT( pending_custom_actions )
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 21 of file custom.c.

◆ CUSTOM_ACTION_TYPE_MASK

#define CUSTOM_ACTION_TYPE_MASK   0x3F

Definition at line 50 of file custom.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 27 of file custom.c.

Typedef Documentation

◆ MsiCustomActionEntryPoint

typedef UINT(WINAPI * MsiCustomActionEntryPoint) (MSIHANDLE)

Definition at line 60 of file custom.c.

Function Documentation

◆ __wine_msi_call_dll_function()

UINT CDECL __wine_msi_call_dll_function ( DWORD  client_pid,
const GUID *  guid 
)

Definition at line 507 of file custom.c.

508{
510 MSIHANDLE remote_package = 0;
511 RPC_WSTR binding_str;
512 MSIHANDLE hPackage;
514 WCHAR *dll = NULL, *action = NULL;
515 LPSTR proc = NULL;
517 INT type;
518 UINT r;
519
520 TRACE("%s\n", debugstr_guid( guid ));
521
522 if (!rpc_handle)
523 {
524 WCHAR endpoint[12];
525
527 status = RpcStringBindingComposeW(NULL, (WCHAR *)L"ncalrpc", NULL, endpoint, NULL, &binding_str);
528 if (status != RPC_S_OK)
529 {
530 ERR("RpcStringBindingCompose failed: %#lx\n", status);
531 return status;
532 }
533 status = RpcBindingFromStringBindingW(binding_str, &rpc_handle);
534 if (status != RPC_S_OK)
535 {
536 ERR("RpcBindingFromStringBinding failed: %#lx\n", status);
537 return status;
538 }
539 RpcStringFreeW(&binding_str);
540 }
541
542 r = remote_GetActionInfo(guid, &action, &type, &dll, &proc, &remote_package);
543 if (r != ERROR_SUCCESS)
544 return r;
545
546 hPackage = alloc_msi_remote_handle( remote_package );
547 if (!hPackage)
548 {
549 ERR( "failed to create handle for %#lx\n", remote_package );
551 midl_user_free( dll );
554 }
555
556 hModule = LoadLibraryW( dll );
557 if (!hModule)
558 {
559 ERR( "failed to load dll %s (%lu)\n", debugstr_w( dll ), GetLastError() );
561 midl_user_free( dll );
563 MsiCloseHandle( hPackage );
564 return ERROR_SUCCESS;
565 }
566
568 if (!fn) WARN( "GetProcAddress(%s) failed\n", debugstr_a(proc) );
569 else
570 {
572
573 __TRY
574 {
575 r = custom_proc_wrapper( fn, hPackage );
576 }
578 {
579 ERR( "Custom action (%s:%s) caused a page fault: %#lx\n",
582 }
583 __ENDTRY;
584 }
585
587
589 midl_user_free(dll);
591
593 return r;
594}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
HMODULE hModule
Definition: animate.c:44
#define GetProcAddress(x, y)
Definition: compat.h:753
#define __TRY
Definition: compat.h:80
#define FreeLibrary(x)
Definition: compat.h:748
#define __ENDTRY
Definition: compat.h:82
#define LoadLibraryW(x)
Definition: compat.h:747
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
GUID guid
Definition: version.c:147
static void handle_msi_break(const WCHAR *action)
Definition: custom.c:458
UINT(WINAPI * MsiCustomActionEntryPoint)(MSIHANDLE)
Definition: custom.c:60
static UINT custom_proc_wrapper(MsiCustomActionEntryPoint entry, MSIHANDLE hinst)
Definition: custom.c:501
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
MSIHANDLE alloc_msi_remote_handle(MSIHANDLE remote)
Definition: handle.c:135
UINT WINAPI MsiCloseAllHandles(void)
Definition: handle.c:325
#define swprintf
Definition: precomp.h:40
action
Definition: namespace.c:707
#define L(x)
Definition: resources.c:13
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
unsigned int UINT
Definition: sysinfo.c:13
#define GetExceptionCode
Definition: excpt.h:83
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
static DWORD client_pid
Definition: msiexec.c:401
static HANDLE proc()
Definition: pdb.c:32
short WCHAR
Definition: pedump.c:58
RPC_STATUS WINAPI RpcBindingFromStringBindingW(RPC_WSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:862
RPC_STATUS WINAPI RpcStringBindingComposeW(RPC_WSTR ObjUuid, RPC_WSTR Protseq, RPC_WSTR NetworkAddr, RPC_WSTR Endpoint, RPC_WSTR Options, RPC_WSTR *StringBinding)
Definition: rpc_binding.c:493
unsigned short * RPC_WSTR
Definition: rpcdce.h:46
#define RPC_S_OK
Definition: rpcnterr.h:22
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
Definition: rpcrt4_main.c:181
#define midl_user_free
Definition: rpc.h:41
long RPC_STATUS
Definition: rpc.h:48
#define TRACE(s)
Definition: solgame.cpp:4
Definition: nis.h:10
Definition: ps.c:97
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
unsigned long MSIHANDLE
Definition: winemsi.idl:27
#define ERROR_INSTALL_FAILURE
Definition: winerror.h:1309

Referenced by custom_action_thread().

◆ ACTION_CallScript()

static DWORD ACTION_CallScript ( const GUID *  guid)
static

Definition at line 1221 of file custom.c.

1222{
1224 MSIHANDLE hPackage;
1226
1228 if (!info)
1229 {
1230 ERR("failed to find action %s\n", debugstr_guid( guid) );
1231 return ERROR_FUNCTION_FAILED;
1232 }
1233
1234 TRACE("function %s, script %s\n", debugstr_w( info->target ), debugstr_w( info->source ) );
1235
1236 hPackage = alloc_msihandle( &info->package->hdr );
1237 if (hPackage)
1238 {
1239 r = call_script( hPackage, info->type, info->source, info->target, info->action );
1240 TRACE("script returned %u\n", r);
1241 MsiCloseHandle( hPackage );
1242 }
1243 else
1244 ERR("failed to create handle for %p\n", info->package );
1245
1246 return r;
1247}
static custom_action_info * find_action_by_guid(const GUID *guid)
Definition: custom.c:434
MSIHANDLE alloc_msihandle(MSIOBJECTHDR *obj)
Definition: handle.c:111
DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function, LPCWSTR action)
Definition: script.c:289
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:1333

Referenced by ScriptThread().

◆ ACTION_CustomAction()

UINT ACTION_CustomAction ( MSIPACKAGE *  package,
const WCHAR *  action 
)

Definition at line 1484 of file custom.c.

1485{
1486 UINT rc = ERROR_SUCCESS;
1487 MSIRECORD *row;
1488 UINT type;
1489 const WCHAR *source, *target, *ptr, *deferred_data = NULL;
1490 WCHAR *deformated = NULL;
1491 int len;
1492
1493 /* deferred action: [properties]Action */
1494 if ((ptr = wcsrchr(action, ']')))
1495 {
1496 deferred_data = action;
1497 action = ptr + 1;
1498 }
1499
1500 row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `CustomAction` WHERE `Action` = '%s'", action );
1501 if (!row)
1503
1507
1508 TRACE("Handling custom action %s (%x %s %s)\n",debugstr_w(action),type,
1510
1511 /* handle some of the deferred actions */
1513 FIXME("msidbCustomActionTypeTSAware not handled\n");
1514
1516 {
1518 WARN("msidbCustomActionTypeNoImpersonate not handled\n");
1519
1520 if (!action_type_matches_script(type, package->script))
1521 {
1522 rc = defer_custom_action( package, action, type );
1523 goto end;
1524 }
1525 else
1526 {
1527 LPWSTR actiondata = msi_dup_property( package->db, action );
1528
1530 package->scheduled_action_running = TRUE;
1531
1533 package->commit_action_running = TRUE;
1534
1536 package->rollback_action_running = TRUE;
1537
1538 if (deferred_data)
1539 set_deferred_action_props(package, deferred_data);
1540 else if (actiondata)
1541 msi_set_property( package->db, L"CustomActionData", actiondata, -1 );
1542 else
1543 msi_set_property( package->db, L"CustomActionData", L"", -1 );
1544
1545 free(actiondata);
1546 }
1547 }
1549 {
1550 rc = ERROR_SUCCESS;
1551 goto end;
1552 }
1553
1554 switch (type & CUSTOM_ACTION_TYPE_MASK)
1555 {
1556 case 1: /* DLL file stored in a Binary table stream */
1557 rc = HANDLE_CustomType1( package, source, target, type, action );
1558 break;
1559 case 2: /* EXE file stored in a Binary table stream */
1560 rc = HANDLE_CustomType2( package, source, target, type, action );
1561 break;
1562 case 5:
1563 case 6: /* JScript/VBScript file stored in a Binary table stream */
1564 rc = HANDLE_CustomType5_6( package, source, target, type, action );
1565 break;
1566 case 7: /* Concurrent install from substorage */
1567 deformat_string( package, target, &deformated );
1568 rc = HANDLE_CustomType7( package, source, target, type, action );
1569 free( deformated );
1570 break;
1571 case 17:
1572 rc = HANDLE_CustomType17( package, source, target, type, action );
1573 break;
1574 case 18: /* EXE file installed with package */
1575 rc = HANDLE_CustomType18( package, source, target, type, action );
1576 break;
1577 case 19: /* Error that halts install */
1578 rc = HANDLE_CustomType19( package, source, target, type, action );
1579 break;
1580 case 21: /* JScript/VBScript file installed with the product */
1581 case 22:
1582 rc = HANDLE_CustomType21_22( package, source, target, type, action );
1583 break;
1584 case 23: /* Installs another package in the source tree */
1585 deformat_string( package, target, &deformated );
1586 rc = HANDLE_CustomType23( package, source, deformated, type, action );
1587 free( deformated );
1588 break;
1589 case 34: /* EXE to be run in specified directory */
1590 rc = HANDLE_CustomType34( package, source, target, type, action );
1591 break;
1592 case 35: /* Directory set with formatted text */
1593 deformat_string( package, target, &deformated );
1594 MSI_SetTargetPathW( package, source, deformated );
1595 free( deformated );
1596 break;
1597 case 37: /* JScript/VBScript text stored in target column */
1598 case 38:
1599 rc = HANDLE_CustomType37_38( package, source, target, type, action );
1600 break;
1601 case 50: /* EXE file specified by a property value */
1602 rc = HANDLE_CustomType50( package, source, target, type, action );
1603 break;
1604 case 51: /* Property set with formatted text */
1605 if (!source) break;
1606 len = deformat_string( package, target, &deformated );
1607 rc = msi_set_property( package->db, source, deformated, len );
1608 if (rc == ERROR_SUCCESS && !wcscmp( source, L"SourceDir" )) msi_reset_source_folders( package );
1609 free( deformated );
1610 break;
1611 case 53: /* JScript/VBScript text specified by a property value */
1612 case 54:
1613 rc = HANDLE_CustomType53_54( package, source, target, type, action );
1614 break;
1615 default:
1616 FIXME( "unhandled action type %u (%s %s)\n", type & CUSTOM_ACTION_TYPE_MASK, debugstr_w(source),
1617 debugstr_w(target) );
1618 }
1619
1620end:
1622 package->commit_action_running = FALSE;
1623 package->rollback_action_running = FALSE;
1624 msiobj_release(&row->hdr);
1625 return rc;
1626}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define free
Definition: debug_ros.c:5
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define wcsrchr
Definition: compat.h:16
static UINT HANDLE_CustomType1(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:861
static UINT defer_custom_action(MSIPACKAGE *package, const WCHAR *action, UINT type)
Definition: custom.c:1447
static UINT HANDLE_CustomType7(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1146
#define CUSTOM_ACTION_TYPE_MASK
Definition: custom.c:50
static UINT HANDLE_CustomType37_38(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1295
static BOOL check_execution_scheduling_options(MSIPACKAGE *package, LPCWSTR action, UINT options)
Definition: custom.c:141
static UINT HANDLE_CustomType21_22(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1354
static UINT HANDLE_CustomType23(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1065
static UINT HANDLE_CustomType17(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:974
static UINT HANDLE_CustomType2(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:955
static void set_deferred_action_props(MSIPACKAGE *package, const WCHAR *deferred_data)
Definition: custom.c:198
static BOOL action_type_matches_script(UINT type, UINT script)
Definition: custom.c:1429
static UINT HANDLE_CustomType34(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1198
static UINT HANDLE_CustomType5_6(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1306
static UINT HANDLE_CustomType18(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1005
static UINT HANDLE_CustomType50(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1180
static UINT HANDLE_CustomType53_54(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1413
static UINT HANDLE_CustomType19(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1023
DWORD deformat_string(MSIPACKAGE *package, const WCHAR *fmt, WCHAR **data)
Definition: format.c:1015
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolderPath)
Definition: install.c:564
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
GLuint GLuint end
Definition: gl.h:1545
GLenum GLsizei len
Definition: glext.h:6722
static PVOID ptr
Definition: dispmode.c:27
@ msidbCustomActionTypeCommit
Definition: msidefs.h:137
@ msidbCustomActionTypeNoImpersonate
Definition: msidefs.h:139
@ msidbCustomActionTypeTSAware
Definition: msidefs.h:140
@ msidbCustomActionTypeRollback
Definition: msidefs.h:136
@ msidbCustomActionTypeInScript
Definition: msidefs.h:134
int MSI_RecordGetInteger(MSIRECORD *, UINT)
Definition: record.c:213
void msi_reset_source_folders(MSIPACKAGE *package)
Definition: package.c:2121
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT)
Definition: record.c:433
UINT msi_set_property(MSIDATABASE *, const WCHAR *, const WCHAR *, int)
Definition: package.c:2132
MSIRECORD *WINAPIV MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR query,...)
Definition: msiquery.c:201
WCHAR * msi_dup_property(MSIDATABASE *db, const WCHAR *prop) __WINE_DEALLOC(free) __WINE_MALLOC
unsigned char commit_action_running
Definition: msipriv.h:481
MSIDATABASE * db
Definition: msipriv.h:407
unsigned char rollback_action_running
Definition: msipriv.h:482
enum script script
Definition: msipriv.h:446
unsigned char scheduled_action_running
Definition: msipriv.h:480
Definition: tools.h:99
uint16_t * LPWSTR
Definition: typedefs.h:56
#define ERROR_FUNCTION_NOT_CALLED
Definition: winerror.h:1332

Referenced by ACTION_HandleCustomAction().

◆ ACTION_FinishCustomActions()

void ACTION_FinishCustomActions ( const MSIPACKAGE *  package)

Definition at line 1628 of file custom.c.

1629{
1630 struct list *item;
1631 HANDLE *wait_handles;
1632 unsigned int handle_count, i;
1634
1635 while ((item = list_head( &package->RunningActions )))
1636 {
1638
1639 list_remove( &action->entry );
1640
1641 TRACE("waiting for %s\n", debugstr_w( action->name ) );
1643
1644 CloseHandle( action->handle );
1645 free( action->name );
1646 free( action );
1647 }
1648
1650
1651 handle_count = list_count( &pending_custom_actions );
1652 wait_handles = malloc( handle_count * sizeof(HANDLE) );
1653
1654 handle_count = 0;
1656 {
1657 if (info->package == package )
1658 {
1659 if (DuplicateHandle(GetCurrentProcess(), info->handle, GetCurrentProcess(), &wait_handles[handle_count], SYNCHRONIZE, FALSE, 0))
1660 handle_count++;
1661 }
1662 }
1663
1665
1666 for (i = 0; i < handle_count; i++)
1667 {
1668 msi_dialog_check_messages( wait_handles[i] );
1669 CloseHandle( wait_handles[i] );
1670 }
1671 free( wait_handles );
1672
1675 {
1676 if (info->package == package)
1678 }
1680}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
Definition: list.h:39
#define malloc
Definition: debug_ros.c:4
#define CloseHandle
Definition: compat.h:739
#define GetCurrentProcess()
Definition: compat.h:759
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
static struct list pending_custom_actions
Definition: custom.c:72
static CRITICAL_SECTION custom_action_cs
Definition: custom.c:62
static void free_custom_action_data(custom_action_info *info)
Definition: custom.c:395
void msi_dialog_check_messages(HANDLE handle)
Definition: dialog.c:3991
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const char cursor[]
Definition: icontest.c:13
uint32_t entry
Definition: isohybrid.c:63
#define SYNCHRONIZE
Definition: nt_native.h:61
__WINE_SERVER_LIST_INLINE unsigned int list_count(const struct list *list)
Definition: list.h:157
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
Definition: list.h:15
struct list RunningActions
Definition: msipriv.h:454
#define LIST_ENTRY(type)
Definition: queue.h:175
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

Referenced by MSI_InstallPackage().

◆ action_type_matches_script()

static BOOL action_type_matches_script ( UINT  type,
UINT  script 
)
static

Definition at line 1429 of file custom.c.

1430{
1431 switch (script)
1432 {
1433 case SCRIPT_NONE:
1434 return FALSE;
1435 case SCRIPT_INSTALL:
1437 case SCRIPT_COMMIT:
1439 case SCRIPT_ROLLBACK:
1441 default:
1442 ERR("unhandled script %u\n", script);
1443 }
1444 return FALSE;
1445}
script
Definition: msipriv.h:396
@ SCRIPT_INSTALL
Definition: msipriv.h:398
@ SCRIPT_ROLLBACK
Definition: msipriv.h:400
@ SCRIPT_NONE
Definition: msipriv.h:397
@ SCRIPT_COMMIT
Definition: msipriv.h:399

Referenced by ACTION_CustomAction().

◆ build_msiexec_args()

static WCHAR * build_msiexec_args ( const WCHAR *  filename,
const WCHAR *  params 
)
static

Definition at line 1048 of file custom.c.

1049{
1050 UINT len_filename = lstrlenW( filename ), len_params = lstrlenW( params );
1051 UINT len = ARRAY_SIZE(L"/qb /i ") - 1;
1052 WCHAR *ret;
1053
1054 if (!(ret = malloc( (len + len_filename + len_params + 4) * sizeof(WCHAR) ))) return NULL;
1055 memcpy( ret, L"/qb /i ", sizeof(L"/qb /i ") );
1056 ret[len++] = '"';
1057 memcpy( ret + len, filename, len_filename * sizeof(WCHAR) );
1058 len += len_filename;
1059 ret[len++] = '"';
1060 ret[len++] = ' ';
1061 lstrcpyW( ret + len, params );
1062 return ret;
1063}
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
return ret
Definition: mutex.c:147
GLenum const GLfloat * params
Definition: glext.h:5645
const char * filename
Definition: ioapi.h:137
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by HANDLE_CustomType23(), and HANDLE_CustomType7().

◆ check_execution_scheduling_options()

static BOOL check_execution_scheduling_options ( MSIPACKAGE *  package,
LPCWSTR  action,
UINT  options 
)
static

Definition at line 141 of file custom.c.

142{
145 {
146 if (!(package->InWhatSequence & SEQUENCE_UI &&
147 package->InWhatSequence & SEQUENCE_EXEC))
148 {
149 TRACE("Skipping action due to dbCustomActionTypeClientRepeat option.\n");
150 return FALSE;
151 }
152 }
154 {
155 if (package->InWhatSequence & SEQUENCE_UI &&
156 package->InWhatSequence & SEQUENCE_EXEC )
157 {
158 TRACE("Skipping action due to msidbCustomActionTypeFirstSequence option.\n");
159 return FALSE;
160 }
161 }
163 {
164 if (msi_action_is_unique(package, action))
165 {
166 TRACE("Skipping action due to msidbCustomActionTypeOncePerProcess option.\n");
167 return FALSE;
168 }
169 else
171 }
172
173 return TRUE;
174}
UINT msi_register_unique_action(MSIPACKAGE *package, const WCHAR *action)
Definition: custom.c:112
BOOL msi_action_is_unique(const MSIPACKAGE *package, const WCHAR *action)
Definition: custom.c:130
@ msidbCustomActionTypeOncePerProcess
Definition: msidefs.h:132
@ msidbCustomActionTypeClientRepeat
Definition: msidefs.h:133
@ msidbCustomActionTypeFirstSequence
Definition: msidefs.h:131
#define SEQUENCE_UI
Definition: msipriv.h:742
#define SEQUENCE_EXEC
Definition: msipriv.h:743
UINT InWhatSequence
Definition: msipriv.h:452

Referenced by ACTION_CustomAction().

◆ create_temp_binary()

static MSIBINARY * create_temp_binary ( MSIPACKAGE *  package,
LPCWSTR  source 
)
static

Definition at line 243 of file custom.c.

244{
245 MSIRECORD *row;
247 HANDLE file;
248 CHAR buffer[1024];
249 WCHAR *tmpfile;
250 DWORD sz, write;
251 UINT r;
252
253 if (!(tmpfile = msi_create_temp_file( package->db ))) return NULL;
254
255 if (!(row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `Binary` WHERE `Name` = '%s'", source ))) goto error;
256 if (!(binary = calloc( 1, sizeof(MSIBINARY) ))) goto error;
257
259 if (file == INVALID_HANDLE_VALUE) goto error;
260
261 do
262 {
263 sz = sizeof(buffer);
264 r = MSI_RecordReadStream( row, 2, buffer, &sz );
265 if (r != ERROR_SUCCESS)
266 {
267 ERR("Failed to get stream\n");
268 break;
269 }
270 WriteFile( file, buffer, sz, &write, NULL );
271 } while (sz == sizeof buffer);
272
273 CloseHandle( file );
274 if (r != ERROR_SUCCESS) goto error;
275
276 binary->source = wcsdup( source );
277 binary->tmpfile = tmpfile;
278 list_add_tail( &package->binaries, &binary->entry );
279
280 msiobj_release( &row->hdr );
281 return binary;
282
283error:
284 if (row) msiobj_release( &row->hdr );
286 free( tmpfile );
287 free( binary );
288 return NULL;
289}
#define write
Definition: acwin.h:98
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI WriteFile(_In_ HANDLE hFile, _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer, _In_ DWORD nNumberOfBytesToWrite, _Out_opt_ LPDWORD lpNumberOfBytesWritten, _Inout_opt_ LPOVERLAPPED lpOverlapped)
Definition: rw.c:25
WCHAR * msi_create_temp_file(MSIDATABASE *db)
Definition: custom.c:214
FILE *CDECL tmpfile(void)
Definition: file.c:5199
static wchar_t * wcsdup(const wchar_t *str)
Definition: string.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint buffer
Definition: glext.h:5915
const GLuint GLenum const GLvoid * binary
Definition: glext.h:7538
#define error(str)
Definition: mkdosfs.c:1605
UINT MSI_RecordReadStream(MSIRECORD *, UINT, char *, LPDWORD)
Definition: record.c:761
#define GENERIC_WRITE
Definition: nt_native.h:90
char CHAR
Definition: pedump.c:57
#define calloc
Definition: rosglue.h:14
Definition: fci.c:123
struct list binaries
Definition: msipriv.h:420

Referenced by get_temp_binary().

◆ custom_client_thread()

static DWORD WINAPI custom_client_thread ( void *  arg)
static

Definition at line 691 of file custom.c.

692{
694 DWORD64 thread64;
697 HANDLE pipe;
698 DWORD size;
699 DWORD rc;
700
701 CoInitializeEx(NULL, COINIT_MULTITHREADED); /* needed to marshal streams */
702
703 if (info->arch == SCS_32BIT_BINARY)
704 {
705 process = info->package->custom_server_32_process;
706 pipe = info->package->custom_server_32_pipe;
707 }
708 else
709 {
710 process = info->package->custom_server_64_process;
711 pipe = info->package->custom_server_64_pipe;
712 }
713
715
716 if (!WriteFile(pipe, &info->guid, sizeof(info->guid), &size, NULL) ||
717 size != sizeof(info->guid))
718 {
719 ERR("failed to write to custom action client pipe: %lu\n", GetLastError());
721 return GetLastError();
722 }
723 if (!ReadFile(pipe, &thread64, sizeof(thread64), &size, NULL) || size != sizeof(thread64))
724 {
725 ERR("failed to read from custom action client pipe: %lu\n", GetLastError());
727 return GetLastError();
728 }
729
731
734 {
738 }
739 else
740 rc = GetLastError();
741
743 return rc;
744}
static HANDLE thread
Definition: service.c:33
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(void *reserved, DWORD model)
Definition: combase.c:2803
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
#define INFINITE
Definition: serial.h:102
GLsizeiptr size
Definition: glext.h:5919
@ COINIT_MULTITHREADED
Definition: objbase.h:280
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint64_t DWORD64
Definition: typedefs.h:67
#define SCS_32BIT_BINARY
Definition: winbase.h:261
void * arg
Definition: msvc.h:10
#define DUPLICATE_SAME_ACCESS
#define DUPLICATE_CLOSE_SOURCE

Referenced by do_msidbCustomActionTypeDll().

◆ custom_get_process_return()

static UINT custom_get_process_return ( HANDLE  process)
static

Definition at line 318 of file custom.c.

319{
320 DWORD rc = 0;
321
323 TRACE( "exit code is %lu\n", rc );
324 if (rc != 0)
326 return ERROR_SUCCESS;
327}
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1215

Referenced by wait_process_handle().

◆ custom_get_thread_return()

static UINT custom_get_thread_return ( MSIPACKAGE *  package,
HANDLE  thread 
)
static

Definition at line 329 of file custom.c.

330{
331 DWORD rc = 0;
332
334
335 switch (rc)
336 {
338 case ERROR_SUCCESS:
341 return rc;
343 return ERROR_SUCCESS;
345 ACTION_ForceReboot( package );
346 return ERROR_SUCCESS;
347 default:
348 ERR( "invalid Return Code %lu\n", rc );
350 }
351}
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
UINT ACTION_ForceReboot(MSIPACKAGE *package)
Definition: action.c:5227
#define ERROR_INSTALL_USEREXIT
Definition: winerror.h:1308
#define ERROR_INSTALL_SUSPEND
Definition: winerror.h:1310

Referenced by wait_thread_handle().

◆ custom_proc_wrapper()

static UINT custom_proc_wrapper ( MsiCustomActionEntryPoint  entry,
MSIHANDLE  hinst 
)
static

Definition at line 501 of file custom.c.

502{
503 return entry(hinst);
504}
static HINSTANCE hinst
Definition: edit.c:551

Referenced by __wine_msi_call_dll_function().

◆ custom_start_server()

static DWORD custom_start_server ( MSIPACKAGE *  package,
DWORD  arch 
)
static

Definition at line 618 of file custom.c.

619{
622 STARTUPINFOW si = {0};
623 WCHAR buffer[24];
625 void *cookie;
626 HANDLE pipe;
627
628 if ((arch == SCS_32BIT_BINARY && package->custom_server_32_process) ||
629 (arch == SCS_64BIT_BINARY && package->custom_server_64_process))
630 return ERROR_SUCCESS;
631
632 swprintf(buffer, ARRAY_SIZE(buffer), L"\\\\.\\pipe\\msica_%x_%d",
633 GetCurrentProcessId(), arch == SCS_32BIT_BINARY ? 32 : 64);
634 pipe = CreateNamedPipeW(buffer, PIPE_ACCESS_DUPLEX, 0, 1, sizeof(DWORD64),
635 sizeof(GUID), 0, NULL);
636 if (pipe == INVALID_HANDLE_VALUE)
637 ERR("failed to create custom action client pipe: %lu\n", GetLastError());
638
639 if ((sizeof(void *) == 8 || is_wow64) && arch == SCS_32BIT_BINARY)
641 else
642 GetSystemDirectoryW(path, MAX_PATH - ARRAY_SIZE(L"\\msiexec.exe"));
643 lstrcatW(path, L"\\msiexec.exe");
644 swprintf(cmdline, ARRAY_SIZE(cmdline), L"%s -Embedding %d", path, GetCurrentProcessId());
645
647
648 if (is_wow64 && arch == SCS_64BIT_BINARY)
649 {
653 }
654 else
656
657 if (token) CloseHandle(token);
658
660
661 if (arch == SCS_32BIT_BINARY)
662 {
664 package->custom_server_32_pipe = pipe;
665 }
666 else
667 {
669 package->custom_server_64_pipe = pipe;
670 }
671
672 if (!ConnectNamedPipe(pipe, NULL))
673 {
674 ERR("failed to connect to custom action server: %lu\n", GetLastError());
675 return GetLastError();
676 }
677
678 return ERROR_SUCCESS;
679}
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserW(_In_opt_ HANDLE hToken, _In_opt_ LPCWSTR lpApplicationName, _Inout_opt_ LPWSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCWSTR lpCurrentDirectory, _In_ LPSTARTUPINFOW lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation)
Definition: logon.c:987
#define MAX_PATH
Definition: compat.h:34
UINT WINAPI GetSystemWow64DirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2439
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2331
BOOL WINAPI Wow64RevertWow64FsRedirection(IN PVOID OldValue)
Definition: utils.c:810
BOOL WINAPI Wow64DisableWow64FsRedirection(IN PVOID *OldValue)
Definition: utils.c:787
static HANDLE get_admin_token(void)
Definition: custom.c:596
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
BOOL is_wow64
Definition: main.c:38
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
static PROCESS_INFORMATION pi
Definition: debugger.c:2303
static SYSTEM_INFO si
Definition: virtual.c:39
BOOL WINAPI ConnectNamedPipe(IN HANDLE hNamedPipe, IN LPOVERLAPPED lpOverlapped)
Definition: npipe.c:701
HANDLE WINAPI CreateNamedPipeW(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: npipe.c:246
TCHAR * cmdline
Definition: stretchblt.cpp:32
Definition: cookie.c:34
HANDLE custom_server_64_process
Definition: msipriv.h:457
HANDLE custom_server_32_pipe
Definition: msipriv.h:458
HANDLE custom_server_64_pipe
Definition: msipriv.h:459
HANDLE custom_server_32_process
Definition: msipriv.h:456
#define PIPE_ACCESS_DUPLEX
Definition: winbase.h:167
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1205
#define SCS_64BIT_BINARY
Definition: winbase.h:262

Referenced by do_msidbCustomActionTypeDll().

◆ custom_stop_server()

void custom_stop_server ( HANDLE  process,
HANDLE  pipe 
)

Definition at line 681 of file custom.c.

682{
683 DWORD size;
684
685 WriteFile(pipe, &GUID_NULL, sizeof(GUID_NULL), &size, NULL);
688 CloseHandle(pipe);
689}
#define GUID_NULL
Definition: ks.h:106

Referenced by MSI_FreePackage().

◆ defer_custom_action()

static UINT defer_custom_action ( MSIPACKAGE *  package,
const WCHAR *  action,
UINT  type 
)
static

Definition at line 1447 of file custom.c.

1448{
1449 WCHAR *actiondata = msi_dup_property( package->db, action );
1450 WCHAR *usersid = msi_dup_property( package->db, L"UserSID" );
1451 WCHAR *prodcode = msi_dup_property( package->db, L"ProductCode" );
1452 WCHAR *deferred = get_deferred_action( action, actiondata, usersid, prodcode );
1453
1454 if (!deferred)
1455 {
1456 free( actiondata );
1457 free( usersid );
1458 free( prodcode );
1459 return ERROR_OUTOFMEMORY;
1460 }
1462 {
1463 TRACE("deferring commit action\n");
1464 msi_schedule_action( package, SCRIPT_COMMIT, deferred );
1465 }
1467 {
1468 TRACE("deferring rollback action\n");
1469 msi_schedule_action( package, SCRIPT_ROLLBACK, deferred );
1470 }
1471 else
1472 {
1473 TRACE("deferring install action\n");
1474 msi_schedule_action( package, SCRIPT_INSTALL, deferred );
1475 }
1476
1477 free( actiondata );
1478 free( usersid );
1479 free( prodcode );
1480 free( deferred );
1481 return ERROR_SUCCESS;
1482}
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
static WCHAR * get_deferred_action(const WCHAR *action, const WCHAR *actiondata, const WCHAR *usersid, const WCHAR *prodcode)
Definition: custom.c:180
UINT msi_schedule_action(MSIPACKAGE *package, UINT script, const WCHAR *action)
Definition: custom.c:89

Referenced by ACTION_CustomAction().

◆ do_msidbCustomActionTypeDll()

static custom_action_info * do_msidbCustomActionTypeDll ( MSIPACKAGE *  package,
INT  type,
LPCWSTR  source,
LPCWSTR  target,
LPCWSTR  action 
)
static

Definition at line 791 of file custom.c.

793{
796 BOOL ret;
797
798 info = malloc( sizeof *info );
799 if (!info)
800 return NULL;
801
802 msiobj_addref( &package->hdr );
803 info->package = package;
804 info->type = type;
805 info->target = wcsdup( target );
806 info->source = wcsdup( source );
807 info->action = wcsdup( action );
808 CoCreateGuid( &info->guid );
809
813
814 if (!package->rpc_server_started)
815 {
816 WCHAR endpoint[12];
817
820 endpoint, NULL);
821 if (status != RPC_S_OK)
822 {
823 ERR("RpcServerUseProtseqEp failed: %#lx\n", status);
824 return NULL;
825 }
826
827 status = RpcServerRegisterIfEx(s_IWineMsiRemote_v0_0_s_ifspec, NULL, NULL,
829 if (status != RPC_S_OK)
830 {
831 ERR("RpcServerRegisterIfEx failed: %#lx\n", status);
832 return NULL;
833 }
834
835 info->package->rpc_server_started = 1;
836 }
837
838 ret = get_binary_type(source, &info->arch);
839 if (!ret)
840 info->arch = (sizeof(void *) == 8 ? SCS_64BIT_BINARY : SCS_32BIT_BINARY);
841
842 if (info->arch == SCS_64BIT_BINARY && sizeof(void *) == 4 && !is_wow64)
843 {
844 ERR("Attempt to run a 64-bit custom action inside a 32-bit WINEPREFIX.\n");
846 return NULL;
847 }
848
849 custom_start_server(package, info->arch);
850
852 if (!info->handle)
853 {
855 return NULL;
856 }
857
858 return info;
859}
HRESULT WINAPI CoCreateGuid(GUID *guid)
Definition: combase.c:1016
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
static DWORD custom_start_server(MSIPACKAGE *package, DWORD arch)
Definition: custom.c:618
static DWORD WINAPI custom_client_thread(void *arg)
Definition: custom.c:691
static BOOL get_binary_type(const WCHAR *name, DWORD *type)
Definition: custom.c:747
void msiobj_addref(MSIOBJECTHDR *info)
Definition: handle.c:217
unsigned int BOOL
Definition: ntddk_ex.h:94
RPC_STATUS WINAPI RpcServerRegisterIfEx(RPC_IF_HANDLE IfSpec, UUID *MgrTypeUuid, RPC_MGR_EPV *MgrEpv, UINT Flags, UINT MaxCalls, RPC_IF_CALLBACK_FN *IfCallbackFn)
Definition: rpc_server.c:1125
RPC_STATUS WINAPI RpcServerUseProtseqEpW(RPC_WSTR Protseq, UINT MaxCalls, RPC_WSTR Endpoint, LPVOID SecurityDescriptor)
Definition: rpc_server.c:927
#define RPC_C_LISTEN_MAX_CALLS_DEFAULT
Definition: rpcdce.h:122
#define RPC_C_PROTSEQ_MAX_REQS_DEFAULT
Definition: rpcdce.h:123
#define RPC_IF_AUTOLISTEN
Definition: rpcdce.h:313
MSIOBJECTHDR hdr
Definition: msipriv.h:406
unsigned char rpc_server_started
Definition: msipriv.h:486

Referenced by HANDLE_CustomType1(), and HANDLE_CustomType17().

◆ do_msidbCustomActionTypeScript()

static custom_action_info * do_msidbCustomActionTypeScript ( MSIPACKAGE *  package,
INT  type,
LPCWSTR  script,
LPCWSTR  function,
LPCWSTR  action 
)
static

Definition at line 1264 of file custom.c.

1266{
1268
1269 info = malloc( sizeof *info );
1270 if (!info)
1271 return NULL;
1272
1273 msiobj_addref( &package->hdr );
1274 info->package = package;
1275 info->type = type;
1276 info->target = wcsdup( function );
1277 info->source = wcsdup( script );
1278 info->action = wcsdup( action );
1279 CoCreateGuid( &info->guid );
1280
1284
1285 info->handle = CreateThread( NULL, 0, ScriptThread, &info->guid, 0, NULL );
1286 if (!info->handle)
1287 {
1289 return NULL;
1290 }
1291
1292 return info;
1293}
static DWORD WINAPI ScriptThread(LPVOID arg)
Definition: custom.c:1249

Referenced by HANDLE_CustomType21_22(), HANDLE_CustomType37_38(), HANDLE_CustomType53_54(), and HANDLE_CustomType5_6().

◆ execute_command()

static HANDLE execute_command ( const WCHAR *  app,
WCHAR *  arg,
const WCHAR *  dir 
)
static

Definition at line 888 of file custom.c.

889{
892 WCHAR *exe = NULL, *cmd = NULL, *p;
893 BOOL ret;
894
895 if (app)
896 {
897 int len_arg = 0;
898 DWORD len_exe;
899
900 if (!(exe = malloc( MAX_PATH * sizeof(WCHAR) ))) return INVALID_HANDLE_VALUE;
901 len_exe = SearchPathW( NULL, app, L".exe", MAX_PATH, exe, NULL );
902 if (len_exe >= MAX_PATH)
903 {
904 free( exe );
905 if (!(exe = malloc( len_exe * sizeof(WCHAR) ))) return INVALID_HANDLE_VALUE;
906 len_exe = SearchPathW( NULL, app, L".exe", len_exe, exe, NULL );
907 }
908 if (!len_exe)
909 {
910 ERR("can't find executable %lu\n", GetLastError());
911 free( exe );
913 }
914
915 if (arg) len_arg = lstrlenW( arg );
916 if (!(cmd = malloc( (len_exe + len_arg + 4) * sizeof(WCHAR) )))
917 {
918 free( exe );
920 }
921 p = cmd;
922 if (wcschr( exe, ' ' ))
923 {
924 *p++ = '\"';
925 memcpy( p, exe, len_exe * sizeof(WCHAR) );
926 p += len_exe;
927 *p++ = '\"';
928 *p = 0;
929 }
930 else
931 {
932 lstrcpyW( p, exe );
933 p += len_exe;
934 }
935 if (arg)
936 {
937 *p++ = ' ';
938 memcpy( p, arg, len_arg * sizeof(WCHAR) );
939 p[len_arg] = 0;
940 }
941 }
942 memset( &si, 0, sizeof(STARTUPINFOW) );
943 ret = CreateProcessW( exe, exe ? cmd : arg, NULL, NULL, FALSE, 0, NULL, dir, &si, &info );
944 free( cmd );
945 free( exe );
946 if (!ret)
947 {
948 ERR("unable to execute command %lu\n", GetLastError());
950 }
951 CloseHandle( info.hThread );
952 return info.hProcess;
953}
unsigned int dir
Definition: maze.c:112
#define wcschr
Definition: compat.h:17
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1397
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4491
GLfloat GLfloat p
Definition: glext.h:8902
#define memset(x, y, z)
Definition: compat.h:39
Definition: ftp_var.h:139

Referenced by HANDLE_CustomType18(), HANDLE_CustomType2(), HANDLE_CustomType23(), HANDLE_CustomType34(), HANDLE_CustomType50(), and HANDLE_CustomType7().

◆ file_running_action()

static void file_running_action ( MSIPACKAGE *  package,
HANDLE  Handle,
BOOL  process,
LPCWSTR  name 
)
static

Definition at line 304 of file custom.c.

306{
307 struct running_action *action;
308
309 action = malloc( sizeof(*action) );
310
311 action->handle = Handle;
312 action->process = process;
313 action->name = wcsdup(name);
314
315 list_add_tail( &package->RunningActions, &action->entry );
316}
ULONG Handle
Definition: gdb_input.c:15
Definition: name.c:39
BOOL process
Definition: custom.c:56

Referenced by wait_process_handle().

◆ find_action_by_guid()

static custom_action_info * find_action_by_guid ( const GUID *  guid)
static

Definition at line 434 of file custom.c.

435{
437 BOOL found = FALSE;
438
440
442 {
443 if (IsEqualGUID( &info->guid, guid ))
444 {
445 found = TRUE;
446 break;
447 }
448 }
449
451
452 if (!found)
453 return NULL;
454
455 return info;
456}
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236

Referenced by ACTION_CallScript(), and s_remote_GetActionInfo().

◆ free_custom_action_data()

static void free_custom_action_data ( custom_action_info *  info)
static

Definition at line 395 of file custom.c.

396{
398
399 list_remove( &info->entry );
400 if (info->handle)
401 CloseHandle( info->handle );
402 free( info->action );
403 free( info->source );
404 free( info->target );
405 msiobj_release( &info->package->hdr );
406 free( info );
407
409}

Referenced by ACTION_FinishCustomActions(), do_msidbCustomActionTypeDll(), do_msidbCustomActionTypeScript(), and wait_thread_handle().

◆ get_admin_token()

static HANDLE get_admin_token ( void  )
static

Definition at line 596 of file custom.c.

597{
599 TOKEN_LINKED_TOKEN linked;
600 DWORD size;
601
602#ifdef __REACTOS__
603#ifndef GetCurrentThreadEffectiveToken
604#define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3)
605#define GetCurrentThreadEffectiveToken() GetCurrentProcessToken()
606#endif
607#endif
608
609 if (!GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenElevationType, &type, sizeof(type), &size)
611 return NULL;
612
613 if (!GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenLinkedToken, &linked, sizeof(linked), &size))
614 return NULL;
615 return linked.LinkedToken;
616}
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
enum _TOKEN_ELEVATION_TYPE TOKEN_ELEVATION_TYPE
@ TokenElevationTypeFull
Definition: winnt_old.h:2718
@ TokenElevationType
Definition: setypes.h:995
@ TokenLinkedToken
Definition: setypes.h:996

Referenced by custom_start_server().

◆ get_binary_type()

static BOOL get_binary_type ( const WCHAR *  name,
DWORD *  type 
)
static

Definition at line 747 of file custom.c.

748{
749 HANDLE hfile, mapping;
751
753 if (hfile == INVALID_HANDLE_VALUE)
754 return FALSE;
755
757 SEC_IMAGE, hfile );
758 CloseHandle( hfile );
759
760 switch (status)
761 {
762 case STATUS_SUCCESS:
763 {
765
768 if (status) return FALSE;
769 switch (info.Machine)
770 {
774 return TRUE;
778 return TRUE;
779 default:
780 return FALSE;
781 }
782 }
785 return TRUE;
786 default:
787 return FALSE;
788 }
789}
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3090
LONG NTSTATUS
Definition: precomp.h:26
#define IMAGE_FILE_MACHINE_ARMNT
Definition: compat.h:127
#define PAGE_READONLY
Definition: compat.h:138
#define GENERIC_READ
Definition: compat.h:135
#define IMAGE_FILE_MACHINE_ARM64
Definition: compat.h:129
#define FILE_SHARE_READ
Definition: compat.h:136
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
#define SEC_IMAGE
Definition: mmtypes.h:97
@ SectionImageInformation
Definition: mmtypes.h:196
#define SECTION_QUERY
Definition: nt_native.h:1290
#define STANDARD_RIGHTS_REQUIRED
Definition: nt_native.h:63
#define IMAGE_FILE_MACHINE_AMD64
Definition: ntimage.h:17
#define STATUS_INVALID_IMAGE_WIN_64
Definition: ntstatus.h:1029
#define IMAGE_FILE_MACHINE_I386
Definition: pedump.c:174
NTSTATUS NTAPI NtQuerySection(_In_ HANDLE SectionHandle, _In_ SECTION_INFORMATION_CLASS SectionInformationClass, _Out_ PVOID SectionInformation, _In_ SIZE_T SectionInformationLength, _Out_opt_ PSIZE_T ResultLength)
Definition: section.c:3812
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by do_msidbCustomActionTypeDll(), HANDLE_CustomType1(), and HANDLE_CustomType17().

◆ get_deferred_action()

static WCHAR * get_deferred_action ( const WCHAR *  action,
const WCHAR *  actiondata,
const WCHAR *  usersid,
const WCHAR *  prodcode 
)
static

Definition at line 180 of file custom.c.

182{
183 LPWSTR deferred;
184 DWORD len;
185
186 if (!actiondata)
187 return wcsdup(action);
188
189 len = lstrlenW(action) + lstrlenW(actiondata) +
190 lstrlenW(usersid) + lstrlenW(prodcode) +
191 lstrlenW(L"[%s<=>%s<=>%s]%s") - 7;
192 deferred = malloc(len * sizeof(WCHAR));
193
194 swprintf(deferred, len, L"[%s<=>%s<=>%s]%s", actiondata, usersid, prodcode, action);
195 return deferred;
196}

Referenced by defer_custom_action().

◆ get_temp_binary()

static MSIBINARY * get_temp_binary ( MSIPACKAGE *  package,
LPCWSTR  source 
)
static

Definition at line 291 of file custom.c.

292{
294
296 {
297 if (!wcscmp( binary->source, source ))
298 return binary;
299 }
300
301 return create_temp_binary(package, source);
302}
static MSIBINARY * create_temp_binary(MSIPACKAGE *package, LPCWSTR source)
Definition: custom.c:243

Referenced by HANDLE_CustomType1(), and HANDLE_CustomType2().

◆ HANDLE_CustomType1()

static UINT HANDLE_CustomType1 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 861 of file custom.c.

863{
866
867 if (!(binary = get_temp_binary(package, source)))
869
870#if defined(__REACTOS__) && defined(_M_AMD64)
871 {
872 DWORD arch;
873 get_binary_type(binary->tmpfile, &arch);
874 if (arch == SCS_32BIT_BINARY) {
875 ERR("%s is a 32 bit custom action. Returning as ERROR_SUCCESS\n", debugstr_w(source));
876 return ERROR_SUCCESS; // HACK: NO WOW64! return as executed though it's not true
877 }
878 }
879#endif
880
881 TRACE("Calling function %s from %s\n", debugstr_w(target), debugstr_w(binary->tmpfile));
882
883 if (!(info = do_msidbCustomActionTypeDll( package, type, binary->tmpfile, target, action )))
885 return wait_thread_handle( info );
886}
static UINT wait_thread_handle(custom_action_info *info)
Definition: custom.c:411
static custom_action_info * do_msidbCustomActionTypeDll(MSIPACKAGE *package, INT type, LPCWSTR source, LPCWSTR target, LPCWSTR action)
Definition: custom.c:791
static MSIBINARY * get_temp_binary(MSIPACKAGE *package, LPCWSTR source)
Definition: custom.c:291

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType17()

static UINT HANDLE_CustomType17 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 974 of file custom.c.

976{
978 MSIFILE *file;
979
980 TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
981
982 file = msi_get_loaded_file( package, source );
983 if (!file)
984 {
985 ERR("invalid file key %s\n", debugstr_w( source ));
987 }
988
989#if defined(__REACTOS__) && defined(_M_AMD64)
990 {
991 DWORD arch;
992 get_binary_type(file->TargetPath, &arch);
993 if (arch == SCS_32BIT_BINARY) {
994 ERR("%s is a 32 bit custom action. Returning as ERROR_SUCCESS\n", debugstr_w(source));
995 return ERROR_SUCCESS; // HACK: NO WOW64! return as executed though it's not true
996 }
997 }
998#endif
999
1000 if (!(info = do_msidbCustomActionTypeDll( package, type, file->TargetPath, target, action )))
1001 return ERROR_FUNCTION_FAILED;
1002 return wait_thread_handle( info );
1003}
MSIFILE * msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *key)
Definition: action.c:571

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType18()

static UINT HANDLE_CustomType18 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 1005 of file custom.c.

1007{
1008 MSIFILE *file;
1009 HANDLE handle;
1010 WCHAR *arg;
1011
1012 if (!(file = msi_get_loaded_file( package, source ))) return ERROR_FUNCTION_FAILED;
1013
1014 deformat_string( package, target, &arg );
1015 TRACE("exe %s arg %s\n", debugstr_w(file->TargetPath), debugstr_w(arg));
1016
1017 handle = execute_command( file->TargetPath, arg, L"C:\\" );
1018 free( arg );
1020 return wait_process_handle( package, type, handle, action );
1021}
static HANDLE execute_command(const WCHAR *app, WCHAR *arg, const WCHAR *dir)
Definition: custom.c:888
static UINT wait_process_handle(MSIPACKAGE *package, UINT type, HANDLE ProcessHandle, LPCWSTR name)
Definition: custom.c:353

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType19()

static UINT HANDLE_CustomType19 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 1023 of file custom.c.

1025{
1026 MSIRECORD *row = 0;
1027 LPWSTR deformated = NULL;
1028
1029 deformat_string( package, target, &deformated );
1030
1031 /* first try treat the error as a number */
1032 row = MSI_QueryGetRecord( package->db, L"SELECT `Message` FROM `Error` WHERE `Error` = '%s'", deformated );
1033 if( row )
1034 {
1038 msiobj_release( &row->hdr );
1039 }
1040 else if ((package->ui_level & INSTALLUILEVEL_MASK) != INSTALLUILEVEL_NONE)
1041 MessageBoxW( NULL, deformated, NULL, MB_OK );
1042
1043 free( deformated );
1044
1045 return ERROR_INSTALL_FAILURE;
1046}
@ INSTALLUILEVEL_NONE
Definition: msi.h:66
#define INSTALLUILEVEL_MASK
Definition: msipriv.h:60
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_OK
Definition: winuser.h:801
INSTALLUILEVEL ui_level
Definition: msipriv.h:466
const uint16_t * LPCWSTR
Definition: typedefs.h:57

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType2()

static UINT HANDLE_CustomType2 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 955 of file custom.c.

957{
960 WCHAR *arg;
961
962 if (!(binary = get_temp_binary(package, source)))
964
965 deformat_string( package, target, &arg );
966 TRACE("exe %s arg %s\n", debugstr_w(binary->tmpfile), debugstr_w(arg));
967
968 handle = execute_command( binary->tmpfile, arg, L"C:\\" );
969 free( arg );
971 return wait_process_handle( package, type, handle, action );
972}

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType21_22()

static UINT HANDLE_CustomType21_22 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 1354 of file custom.c.

1356{
1358 MSIFILE *file;
1359 HANDLE hFile;
1360 DWORD sz, szHighWord = 0, read;
1361 CHAR *buffer=NULL;
1362 WCHAR *bufferw=NULL;
1363 BOOL bRet;
1364 UINT r;
1365
1366 TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
1367
1368 file = msi_get_loaded_file(package, source);
1369 if (!file)
1370 {
1371 ERR("invalid file key %s\n", debugstr_w(source));
1372 return ERROR_FUNCTION_FAILED;
1373 }
1374
1375 hFile = msi_create_file( package, file->TargetPath, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 );
1377
1378 sz = GetFileSize(hFile, &szHighWord);
1379 if (sz == INVALID_FILE_SIZE || szHighWord != 0)
1380 {
1382 return ERROR_FUNCTION_FAILED;
1383 }
1384 buffer = malloc( sz + 1 );
1385 if (!buffer)
1386 {
1388 return ERROR_FUNCTION_FAILED;
1389 }
1390 bRet = ReadFile(hFile, buffer, sz, &read, NULL);
1392 if (!bRet)
1393 {
1395 goto done;
1396 }
1397 buffer[read] = 0;
1398 bufferw = strdupAtoW(buffer);
1399 if (!bufferw)
1400 {
1402 goto done;
1403 }
1404 info = do_msidbCustomActionTypeScript( package, type, bufferw, target, action );
1406
1407done:
1408 free(bufferw);
1409 free(buffer);
1410 return r;
1411}
#define read
Definition: acwin.h:97
static WCHAR * strdupAtoW(const char *str)
Definition: main.c:61
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
static custom_action_info * do_msidbCustomActionTypeScript(MSIPACKAGE *package, INT type, LPCWSTR script, LPCWSTR function, LPCWSTR action)
Definition: custom.c:1264
HANDLE msi_create_file(MSIPACKAGE *package, const WCHAR *filename, DWORD access, DWORD sharing, DWORD creation, DWORD flags)
Definition: files.c:60
_In_ HANDLE hFile
Definition: mswsock.h:90
#define INVALID_FILE_SIZE
Definition: winbase.h:528

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType23()

static UINT HANDLE_CustomType23 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 1065 of file custom.c.

1067{
1068 WCHAR *dir, *filename, *args, *p;
1069 UINT len_dir, len_source = lstrlenW( source );
1070 HANDLE handle;
1071
1072 if (!(dir = msi_dup_property( package->db, L"OriginalDatabase" ))) return ERROR_OUTOFMEMORY;
1073 if (!(p = wcsrchr( dir, '\\' )) && !(p = wcsrchr( dir, '/' )))
1074 {
1075 free( dir );
1076 return ERROR_FUNCTION_FAILED;
1077 }
1078 *p = 0;
1079 len_dir = p - dir;
1080 if (!(filename = malloc( (len_dir + len_source + 2) * sizeof(WCHAR) )))
1081 {
1082 free( dir );
1083 return ERROR_OUTOFMEMORY;
1084 }
1085 memcpy( filename, dir, len_dir * sizeof(WCHAR) );
1086 filename[len_dir++] = '\\';
1087 memcpy( filename + len_dir, source, len_source * sizeof(WCHAR) );
1088 filename[len_dir + len_source] = 0;
1089
1091 {
1092 free( dir );
1093 free( filename );
1094 return ERROR_OUTOFMEMORY;
1095 }
1096
1097 TRACE("installing %s concurrently\n", debugstr_w(source));
1098
1099 handle = execute_command( L"msiexec", args, dir );
1100 free( dir );
1101 free( filename );
1102 free( args );
1104 return wait_process_handle( package, type, handle, action );
1105}
static WCHAR * build_msiexec_args(const WCHAR *filename, const WCHAR *params)
Definition: custom.c:1048
#define args
Definition: format.c:66
Definition: match.c:390

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType34()

static UINT HANDLE_CustomType34 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 1198 of file custom.c.

1200{
1201 const WCHAR *workingdir = NULL;
1202 HANDLE handle;
1203 WCHAR *cmd;
1204
1205 if (source)
1206 {
1207 workingdir = msi_get_target_folder( package, source );
1208 if (!workingdir) return ERROR_FUNCTION_FAILED;
1209 }
1210 deformat_string( package, target, &cmd );
1211 if (!cmd) return ERROR_FUNCTION_FAILED;
1212
1213 TRACE("cmd %s dir %s\n", debugstr_w(cmd), debugstr_w(workingdir));
1214
1215 handle = execute_command( NULL, cmd, workingdir );
1216 free( cmd );
1218 return wait_process_handle( package, type, handle, action );
1219}
const WCHAR * msi_get_target_folder(MSIPACKAGE *package, const WCHAR *name)
Definition: install.c:232

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType37_38()

static UINT HANDLE_CustomType37_38 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 1295 of file custom.c.

1297{
1299
1300 TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
1301
1303 return wait_thread_handle( info );
1304}

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType50()

static UINT HANDLE_CustomType50 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 1180 of file custom.c.

1182{
1183 WCHAR *exe, *arg;
1184 HANDLE handle;
1185
1186 if (!(exe = msi_dup_property( package->db, source ))) return ERROR_SUCCESS;
1187
1188 deformat_string( package, target, &arg );
1189 TRACE("exe %s arg %s\n", debugstr_w(exe), debugstr_w(arg));
1190
1191 handle = execute_command( exe, arg, L"C:\\" );
1192 free( exe );
1193 free( arg );
1195 return wait_process_handle( package, type, handle, action );
1196}

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType53_54()

static UINT HANDLE_CustomType53_54 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 1413 of file custom.c.

1415{
1417 WCHAR *prop;
1418
1419 TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
1420
1421 prop = msi_dup_property( package->db, source );
1422 if (!prop) return ERROR_SUCCESS;
1423
1424 info = do_msidbCustomActionTypeScript( package, type, prop, NULL, action );
1425 free(prop);
1426 return wait_thread_handle( info );
1427}

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType5_6()

static UINT HANDLE_CustomType5_6 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 1306 of file custom.c.

1308{
1309 MSIRECORD *row = NULL;
1311 CHAR *buffer = NULL;
1312 WCHAR *bufferw = NULL;
1313 DWORD sz = 0;
1314 UINT r;
1315
1316 TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
1317
1318 row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Binary` WHERE `Name` = '%s'", source);
1319 if (!row)
1320 return ERROR_FUNCTION_FAILED;
1321
1322 r = MSI_RecordReadStream(row, 2, NULL, &sz);
1323 if (r != ERROR_SUCCESS) goto done;
1324
1325 buffer = malloc( sz + 1 );
1326 if (!buffer)
1327 {
1329 goto done;
1330 }
1331
1332 r = MSI_RecordReadStream(row, 2, buffer, &sz);
1333 if (r != ERROR_SUCCESS)
1334 goto done;
1335
1336 buffer[sz] = 0;
1337 bufferw = strdupAtoW(buffer);
1338 if (!bufferw)
1339 {
1341 goto done;
1342 }
1343
1344 info = do_msidbCustomActionTypeScript( package, type, bufferw, target, action );
1346
1347done:
1348 free(bufferw);
1349 free(buffer);
1350 msiobj_release(&row->hdr);
1351 return r;
1352}

Referenced by ACTION_CustomAction().

◆ HANDLE_CustomType7()

static UINT HANDLE_CustomType7 ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  target,
INT  type,
const WCHAR *  action 
)
static

Definition at line 1146 of file custom.c.

1148{
1149 WCHAR *tmpfile, *args;
1151 HANDLE handle;
1152 UINT r;
1153
1154 if (!(tmpfile = msi_create_temp_file( package->db ))) return ERROR_FUNCTION_FAILED;
1155
1157 if (r != ERROR_SUCCESS)
1158 goto error;
1159
1160 if (!(binary = malloc( sizeof(*binary) ))) goto error;
1161 binary->source = NULL;
1162 binary->tmpfile = tmpfile;
1163 list_add_tail( &package->binaries, &binary->entry );
1164
1166
1167 TRACE("installing %s concurrently\n", debugstr_w(source));
1168
1169 handle = execute_command( L"msiexec", args, L"C:\\" );
1170 free( args );
1172 return wait_process_handle( package, type, handle, action );
1173
1174error:
1176 free( tmpfile );
1177 return ERROR_FUNCTION_FAILED;
1178}
static UINT write_substorage_to_file(MSIPACKAGE *package, const WCHAR *source, const WCHAR *filename)
Definition: custom.c:1107

Referenced by ACTION_CustomAction().

◆ handle_msi_break()

static void handle_msi_break ( const WCHAR *  action)
static

Definition at line 458 of file custom.c.

459{
460 const WCHAR fmt[] = L"To debug your custom action, attach your debugger to process %u (0x%x) and press OK";
461 WCHAR val[MAX_PATH], msg[100];
462
463 if (!GetEnvironmentVariableW( L"MsiBreak", val, MAX_PATH ) || wcscmp( val, action )) return;
464
466 MessageBoxW( NULL, msg, L"Windows Installer", MB_OK );
467 DebugBreak();
468}
#define msg(x)
Definition: auth_time.c:54
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
GLuint GLfloat * val
Definition: glext.h:7180
Definition: dsound.c:943
void WINAPI DebugBreak(void)

Referenced by __wine_msi_call_dll_function().

◆ MIDL_user_allocate()

void __RPC_FAR *__RPC_USER MIDL_user_allocate ( SIZE_T  len)

Definition at line 74 of file custom.c.

75{
76 return malloc(len);
77}

◆ MIDL_user_free()

void __RPC_USER MIDL_user_free ( void __RPC_FAR *  ptr)

Definition at line 79 of file custom.c.

80{
81 free(ptr);
82}

◆ msi_action_is_unique()

BOOL msi_action_is_unique ( const MSIPACKAGE *  package,
const WCHAR *  action 
)

Definition at line 130 of file custom.c.

131{
132 UINT i;
133
134 for (i = 0; i < package->unique_actions_count; i++)
135 {
136 if (!wcscmp( package->unique_actions[i], action )) return TRUE;
137 }
138 return FALSE;
139}
int unique_actions_count
Definition: msipriv.h:450
LPWSTR * unique_actions
Definition: msipriv.h:449

Referenced by ACTION_AppSearch(), ACTION_CCPSearch(), ACTION_FindRelatedProducts(), and check_execution_scheduling_options().

◆ msi_create_temp_file()

WCHAR * msi_create_temp_file ( MSIDATABASE *  db)

Definition at line 214 of file custom.c.

215{
216 WCHAR *ret;
217
218 if (!db->tempfolder)
219 {
220 WCHAR tmp[MAX_PATH];
221 DWORD len = ARRAY_SIZE( tmp );
222
223 if (msi_get_property( db, L"TempFolder", tmp, &len ) ||
225 {
226 GetTempPathW( MAX_PATH, tmp );
227 }
228 if (!(db->tempfolder = wcsdup( tmp ))) return NULL;
229 }
230
231 if ((ret = malloc( (wcslen( db->tempfolder ) + 20) * sizeof(WCHAR) )))
232 {
233 if (!GetTempFileNameW( db->tempfolder, L"msi", 0, ret ))
234 {
235 free( ret );
236 return NULL;
237 }
238 }
239
240 return ret;
241}
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2098
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
UINT msi_get_property(MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD)
Definition: package.c:2282
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
LPWSTR tempfolder
Definition: msipriv.h:114

Referenced by create_temp_binary(), HANDLE_CustomType7(), load_image(), patch_file(), and patchfiles_cb().

◆ msi_register_unique_action()

UINT msi_register_unique_action ( MSIPACKAGE *  package,
const WCHAR *  action 
)

Definition at line 112 of file custom.c.

113{
114 UINT count;
115 WCHAR **newbuf = NULL;
116
117 TRACE("Registering %s as unique action\n", debugstr_w(action));
118
119 count = package->unique_actions_count;
120 package->unique_actions_count++;
121 if (count != 0) newbuf = realloc( package->unique_actions,
122 package->unique_actions_count * sizeof(WCHAR *) );
123 else newbuf = malloc( sizeof(WCHAR *) );
124
125 newbuf[count] = wcsdup( action );
126 package->unique_actions = newbuf;
127 return ERROR_SUCCESS;
128}
#define realloc
Definition: debug_ros.c:6
GLuint GLuint GLsizei count
Definition: gl.h:1545

Referenced by ACTION_AppSearch(), ACTION_CCPSearch(), ACTION_FindRelatedProducts(), and check_execution_scheduling_options().

◆ msi_schedule_action()

UINT msi_schedule_action ( MSIPACKAGE *  package,
UINT  script,
const WCHAR *  action 
)

Definition at line 89 of file custom.c.

90{
91 UINT count;
92 WCHAR **newbuf = NULL;
93
94 if (script >= SCRIPT_MAX)
95 {
96 FIXME("Unknown script requested %u\n", script);
98 }
99 TRACE("Scheduling action %s in script %u\n", debugstr_w(action), script);
100
102 package->script_actions_count[script]++;
103 if (count != 0) newbuf = realloc( package->script_actions[script],
104 package->script_actions_count[script] * sizeof(WCHAR *) );
105 else newbuf = malloc( sizeof(WCHAR *) );
106
107 newbuf[count] = wcsdup( action );
108 package->script_actions[script] = newbuf;
109 return ERROR_SUCCESS;
110}
@ SCRIPT_MAX
Definition: msipriv.h:401
LPWSTR * script_actions[SCRIPT_MAX]
Definition: msipriv.h:447
int script_actions_count[SCRIPT_MAX]
Definition: msipriv.h:448

Referenced by ACTION_CreateFolders(), ACTION_CreateShortcuts(), ACTION_DeleteServices(), ACTION_DuplicateFiles(), ACTION_HandleStandardAction(), ACTION_InstallFiles(), ACTION_InstallODBC(), ACTION_InstallServices(), ACTION_MoveFiles(), ACTION_MsiPublishAssemblies(), ACTION_MsiUnpublishAssemblies(), ACTION_PatchFiles(), ACTION_ProcessComponents(), ACTION_PublishComponents(), ACTION_PublishFeatures(), ACTION_PublishProduct(), ACTION_RegisterClassInfo(), ACTION_RegisterExtensionInfo(), ACTION_RegisterFonts(), ACTION_RegisterMIMEInfo(), ACTION_RegisterProduct(), ACTION_RegisterProgIdInfo(), ACTION_RegisterTypeLibraries(), ACTION_RegisterUser(), ACTION_RemoveDuplicateFiles(), ACTION_RemoveEnvironmentStrings(), ACTION_RemoveFiles(), ACTION_RemoveFolders(), ACTION_RemoveIniValues(), ACTION_RemoveODBC(), ACTION_RemoveRegistryValues(), ACTION_RemoveShortcuts(), ACTION_SelfRegModules(), ACTION_SelfUnregModules(), ACTION_StartServices(), ACTION_StopServices(), ACTION_UnpublishComponents(), ACTION_UnpublishFeatures(), ACTION_UnregisterClassInfo(), ACTION_UnregisterExtensionInfo(), ACTION_UnregisterFonts(), ACTION_UnregisterMIMEInfo(), ACTION_UnregisterProgIdInfo(), ACTION_UnregisterTypeLibraries(), ACTION_WriteEnvironmentStrings(), ACTION_WriteIniValues(), ACTION_WriteRegistryValues(), and defer_custom_action().

◆ rpc_filter()

LONG WINAPI rpc_filter ( EXCEPTION_POINTERS *  eptr)

Definition at line 84 of file custom.c.

85{
87}
RPCRTAPI int RPC_ENTRY I_RpcExceptionFilter(ULONG)
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
DWORD ExceptionCode
Definition: compat.h:208

◆ s_remote_GetActionInfo()

UINT __cdecl s_remote_GetActionInfo ( const GUID *  guid,
WCHAR **  name,
int *  type,
WCHAR **  dll,
char **  func,
MSIHANDLE *  hinst 
)

Definition at line 1682 of file custom.c.

1683{
1685
1687 if (!info)
1688 return ERROR_INVALID_DATA;
1689
1690 *name = wcsdup(info->action);
1691 *type = info->type;
1692 *hinst = alloc_msihandle(&info->package->hdr);
1693 *dll = wcsdup(info->source);
1694 *func = strdupWtoA(info->target);
1695
1696 return ERROR_SUCCESS;
1697}
static char * strdupWtoA(const WCHAR *str)
GLenum func
Definition: glext.h:6028
#define ERROR_INVALID_DATA
Definition: winerror.h:238

◆ ScriptThread()

static DWORD WINAPI ScriptThread ( LPVOID  arg)
static

Definition at line 1249 of file custom.c.

1250{
1251 LPGUID guid = arg;
1252 DWORD rc;
1253
1254 TRACE("custom action (%#lx) started\n", GetCurrentThreadId() );
1255
1256 rc = ACTION_CallScript( guid );
1257
1258 TRACE("custom action (%#lx) returned %lu\n", GetCurrentThreadId(), rc );
1259
1261 return rc;
1262}
static DWORD ACTION_CallScript(const GUID *guid)
Definition: custom.c:1221
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459

Referenced by do_msidbCustomActionTypeScript().

◆ set_deferred_action_props()

static void set_deferred_action_props ( MSIPACKAGE *  package,
const WCHAR *  deferred_data 
)
static

Definition at line 198 of file custom.c.

199{
200 const WCHAR *end, *beg = deferred_data + 1;
201
202 end = wcsstr(beg, L"<=>");
203 msi_set_property( package->db, L"CustomActionData", beg, end - beg );
204 beg = end + 3;
205
206 end = wcsstr(beg, L"<=>");
207 msi_set_property( package->db, L"UserSID", beg, end - beg );
208 beg = end + 3;
209
210 end = wcschr(beg, ']');
211 msi_set_property( package->db, L"ProductCode", beg, end - beg );
212}
_ACRTIMP wchar_t *__cdecl wcsstr(const wchar_t *, const wchar_t *)
Definition: wcs.c:2998

Referenced by ACTION_CustomAction().

◆ wait_process_handle()

static UINT wait_process_handle ( MSIPACKAGE *  package,
UINT  type,
HANDLE  ProcessHandle,
LPCWSTR  name 
)
static

Definition at line 353 of file custom.c.

355{
356 UINT rc = ERROR_SUCCESS;
357
359 {
360 TRACE("waiting for %s\n", debugstr_w(name));
361
363
366
368 }
369 else
370 {
371 TRACE("%s running in background\n", debugstr_w(name));
372
375 else
377 }
378
379 return rc;
380}
static UINT custom_get_process_return(HANDLE process)
Definition: custom.c:318
static void file_running_action(MSIPACKAGE *package, HANDLE Handle, BOOL process, LPCWSTR name)
Definition: custom.c:304
@ msidbCustomActionTypeContinue
Definition: msidefs.h:128
@ msidbCustomActionTypeAsync
Definition: msidefs.h:129
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:407

Referenced by HANDLE_CustomType18(), HANDLE_CustomType2(), HANDLE_CustomType23(), HANDLE_CustomType34(), HANDLE_CustomType50(), and HANDLE_CustomType7().

◆ wait_thread_handle()

static UINT wait_thread_handle ( custom_action_info *  info)
static

Definition at line 411 of file custom.c.

412{
413 UINT rc = ERROR_SUCCESS;
414
415 if (!(info->type & msidbCustomActionTypeAsync))
416 {
417 TRACE("waiting for %s\n", debugstr_w( info->action ));
418
420
421 if (!(info->type & msidbCustomActionTypeContinue))
422 rc = custom_get_thread_return( info->package, info->handle );
423
425 }
426 else
427 {
428 TRACE("%s running in background\n", debugstr_w( info->action ));
429 }
430
431 return rc;
432}
static UINT custom_get_thread_return(MSIPACKAGE *package, HANDLE thread)
Definition: custom.c:329

Referenced by HANDLE_CustomType1(), HANDLE_CustomType17(), HANDLE_CustomType21_22(), HANDLE_CustomType37_38(), HANDLE_CustomType53_54(), and HANDLE_CustomType5_6().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msi  )

◆ write_substorage_to_file()

static UINT write_substorage_to_file ( MSIPACKAGE *  package,
const WCHAR *  source,
const WCHAR *  filename 
)
static

Definition at line 1107 of file custom.c.

1108{
1109 IStorage *src = NULL, *dst = NULL;
1111 HRESULT hr;
1112
1114 if (FAILED( hr ))
1115 {
1116 WARN( "can't open destination storage %s (%#lx)\n", debugstr_w(filename), hr );
1117 goto done;
1118 }
1119
1120 hr = IStorage_OpenStorage( package->db->storage, source, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &src );
1121 if (FAILED( hr ))
1122 {
1123 WARN( "can't open source storage %s (%#lx)\n", debugstr_w(source), hr );
1124 goto done;
1125 }
1126
1127 hr = IStorage_CopyTo( src, 0, NULL, NULL, dst );
1128 if (FAILED( hr ))
1129 {
1130 ERR( "failed to copy storage %s (%#lx)\n", debugstr_w(source), hr );
1131 goto done;
1132 }
1133
1134 hr = IStorage_Commit( dst, 0 );
1135 if (FAILED( hr ))
1136 ERR( "failed to commit storage (%#lx)\n", hr );
1137 else
1138 r = ERROR_SUCCESS;
1139
1140done:
1141 if (src) IStorage_Release( src );
1142 if (dst) IStorage_Release( dst );
1143 return r;
1144}
HRESULT hr
Definition: delayimp.cpp:582
HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8597
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
#define FAILED(hr)
Definition: intsafe.h:51
#define STGM_CREATE
Definition: objbase.h:945
#define STGM_TRANSACTED
Definition: objbase.h:934
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:942
#define STGM_WRITE
Definition: objbase.h:937
IStorage * storage
Definition: msipriv.h:109

Referenced by HANDLE_CustomType7().

Variable Documentation

◆ custom_action_cs

◆ custom_action_cs_debug

CRITICAL_SECTION_DEBUG custom_action_cs_debug
static
Initial value:
=
{
0, 0, { (DWORD_PTR)(__FILE__ ": custom_action_cs") }
}
static CRITICAL_SECTION_DEBUG custom_action_cs_debug
Definition: custom.c:63
#define DWORD_PTR
Definition: treelist.c:76

Definition at line 63 of file custom.c.

◆ pending_custom_actions

struct list pending_custom_actions = LIST_INIT( pending_custom_actions )
static