ReactOS 0.4.16-dev-340-g0540c21
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_s.h"
#include "wine/asm.h"
#include "wine/debug.h"
#include "wine/unicode.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(WINAPIMsiCustomActionEntryPoint) (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 WCHARget_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)
 
WCHARmsi_create_temp_file (MSIDATABASE *db)
 
static MSIBINARYcreate_temp_binary (MSIPACKAGE *package, LPCWSTR source)
 
static MSIBINARYget_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_infofind_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_infodo_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 WCHARbuild_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_infodo_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 51 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 61 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 508 of file custom.c.

509{
511 MSIHANDLE remote_package = 0;
512 RPC_WSTR binding_str;
513 MSIHANDLE hPackage;
515 WCHAR *dll = NULL, *action = NULL;
516 LPSTR proc = NULL;
518 INT type;
519 UINT r;
520
521 TRACE("%s\n", debugstr_guid( guid ));
522
523 if (!rpc_handle)
524 {
525 WCHAR endpoint[12];
526
528 status = RpcStringBindingComposeW(NULL, (WCHAR *)L"ncalrpc", NULL, endpoint, NULL, &binding_str);
529 if (status != RPC_S_OK)
530 {
531 ERR("RpcStringBindingCompose failed: %#lx\n", status);
532 return status;
533 }
534 status = RpcBindingFromStringBindingW(binding_str, &rpc_handle);
535 if (status != RPC_S_OK)
536 {
537 ERR("RpcBindingFromStringBinding failed: %#lx\n", status);
538 return status;
539 }
540 RpcStringFreeW(&binding_str);
541 }
542
543 r = remote_GetActionInfo(guid, &action, &type, &dll, &proc, &remote_package);
544 if (r != ERROR_SUCCESS)
545 return r;
546
547 hPackage = alloc_msi_remote_handle( remote_package );
548 if (!hPackage)
549 {
550 ERR( "failed to create handle for %#lx\n", remote_package );
555 }
556
558 if (!hModule)
559 {
560 ERR( "failed to load dll %s (%lu)\n", debugstr_w( dll ), GetLastError() );
564 MsiCloseHandle( hPackage );
565 return ERROR_SUCCESS;
566 }
567
569 if (!fn) WARN( "GetProcAddress(%s) failed\n", debugstr_a(proc) );
570 else
571 {
573
574 __TRY
575 {
576 r = custom_proc_wrapper( fn, hPackage );
577 }
579 {
580 ERR( "Custom action (%s:%s) caused a page fault: %#lx\n",
583 }
584 __ENDTRY;
585 }
586
588
592
594 return r;
595}
#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
const WCHAR * action
Definition: action.c:7509
static void handle_msi_break(const WCHAR *action)
Definition: custom.c:459
UINT(WINAPI * MsiCustomActionEntryPoint)(MSIHANDLE)
Definition: custom.c:61
static UINT custom_proc_wrapper(MsiCustomActionEntryPoint entry, MSIHANDLE hinst)
Definition: custom.c:502
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
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#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
const GUID * guid
static HMODULE dll
Definition: str.c:188
static DWORD client_pid
Definition: msiexec.c:401
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
static HANDLE proc()
Definition: pdb.c:34
RPC_STATUS WINAPI RpcBindingFromStringBindingW(RPC_WSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:880
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:510
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:175
#define midl_user_free
Definition: rpc.h:45
long RPC_STATUS
Definition: rpc.h:52
#define TRACE(s)
Definition: solgame.cpp:4
Definition: nis.h:10
Definition: ps.c:97
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:961
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by custom_action_thread().

◆ ACTION_CallScript()

static DWORD ACTION_CallScript ( const GUID guid)
static

Definition at line 1222 of file custom.c.

1223{
1225 MSIHANDLE hPackage;
1227
1229 if (!info)
1230 {
1231 ERR("failed to find action %s\n", debugstr_guid( guid) );
1232 return ERROR_FUNCTION_FAILED;
1233 }
1234
1235 TRACE("function %s, script %s\n", debugstr_w( info->target ), debugstr_w( info->source ) );
1236
1237 hPackage = alloc_msihandle( &info->package->hdr );
1238 if (hPackage)
1239 {
1240 r = call_script( hPackage, info->type, info->source, info->target, info->action );
1241 TRACE("script returned %u\n", r);
1242 MsiCloseHandle( hPackage );
1243 }
1244 else
1245 ERR("failed to create handle for %p\n", info->package );
1246
1247 return r;
1248}
static custom_action_info * find_action_by_guid(const GUID *guid)
Definition: custom.c:435
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:985

Referenced by ScriptThread().

◆ ACTION_CustomAction()

UINT ACTION_CustomAction ( MSIPACKAGE package,
const WCHAR action 
)

Definition at line 1485 of file custom.c.

1486{
1487 UINT rc = ERROR_SUCCESS;
1488 MSIRECORD *row;
1489 UINT type;
1490 const WCHAR *source, *target, *ptr, *deferred_data = NULL;
1491 WCHAR *deformated = NULL;
1492 int len;
1493
1494 /* deferred action: [properties]Action */
1495 if ((ptr = wcsrchr(action, ']')))
1496 {
1497 deferred_data = action;
1498 action = ptr + 1;
1499 }
1500
1501 row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `CustomAction` WHERE `Action` = '%s'", action );
1502 if (!row)
1504
1508
1509 TRACE("Handling custom action %s (%x %s %s)\n",debugstr_w(action),type,
1511
1512 /* handle some of the deferred actions */
1514 FIXME("msidbCustomActionTypeTSAware not handled\n");
1515
1517 {
1519 WARN("msidbCustomActionTypeNoImpersonate not handled\n");
1520
1521 if (!action_type_matches_script(type, package->script))
1522 {
1523 rc = defer_custom_action( package, action, type );
1524 goto end;
1525 }
1526 else
1527 {
1528 LPWSTR actiondata = msi_dup_property( package->db, action );
1529
1531 package->scheduled_action_running = TRUE;
1532
1534 package->commit_action_running = TRUE;
1535
1537 package->rollback_action_running = TRUE;
1538
1539 if (deferred_data)
1540 set_deferred_action_props(package, deferred_data);
1541 else if (actiondata)
1542 msi_set_property( package->db, L"CustomActionData", actiondata, -1 );
1543 else
1544 msi_set_property( package->db, L"CustomActionData", L"", -1 );
1545
1546 free(actiondata);
1547 }
1548 }
1550 {
1551 rc = ERROR_SUCCESS;
1552 goto end;
1553 }
1554
1555 switch (type & CUSTOM_ACTION_TYPE_MASK)
1556 {
1557 case 1: /* DLL file stored in a Binary table stream */
1558 rc = HANDLE_CustomType1( package, source, target, type, action );
1559 break;
1560 case 2: /* EXE file stored in a Binary table stream */
1561 rc = HANDLE_CustomType2( package, source, target, type, action );
1562 break;
1563 case 5:
1564 case 6: /* JScript/VBScript file stored in a Binary table stream */
1565 rc = HANDLE_CustomType5_6( package, source, target, type, action );
1566 break;
1567 case 7: /* Concurrent install from substorage */
1568 deformat_string( package, target, &deformated );
1569 rc = HANDLE_CustomType7( package, source, target, type, action );
1570 free( deformated );
1571 break;
1572 case 17:
1573 rc = HANDLE_CustomType17( package, source, target, type, action );
1574 break;
1575 case 18: /* EXE file installed with package */
1576 rc = HANDLE_CustomType18( package, source, target, type, action );
1577 break;
1578 case 19: /* Error that halts install */
1579 rc = HANDLE_CustomType19( package, source, target, type, action );
1580 break;
1581 case 21: /* JScript/VBScript file installed with the product */
1582 case 22:
1583 rc = HANDLE_CustomType21_22( package, source, target, type, action );
1584 break;
1585 case 23: /* Installs another package in the source tree */
1586 deformat_string( package, target, &deformated );
1587 rc = HANDLE_CustomType23( package, source, deformated, type, action );
1588 free( deformated );
1589 break;
1590 case 34: /* EXE to be run in specified directory */
1591 rc = HANDLE_CustomType34( package, source, target, type, action );
1592 break;
1593 case 35: /* Directory set with formatted text */
1594 deformat_string( package, target, &deformated );
1595 MSI_SetTargetPathW( package, source, deformated );
1596 free( deformated );
1597 break;
1598 case 37: /* JScript/VBScript text stored in target column */
1599 case 38:
1600 rc = HANDLE_CustomType37_38( package, source, target, type, action );
1601 break;
1602 case 50: /* EXE file specified by a property value */
1603 rc = HANDLE_CustomType50( package, source, target, type, action );
1604 break;
1605 case 51: /* Property set with formatted text */
1606 if (!source) break;
1607 len = deformat_string( package, target, &deformated );
1608 rc = msi_set_property( package->db, source, deformated, len );
1609 if (rc == ERROR_SUCCESS && !wcscmp( source, L"SourceDir" )) msi_reset_source_folders( package );
1610 free( deformated );
1611 break;
1612 case 53: /* JScript/VBScript text specified by a property value */
1613 case 54:
1614 rc = HANDLE_CustomType53_54( package, source, target, type, action );
1615 break;
1616 default:
1617 FIXME( "unhandled action type %u (%s %s)\n", type & CUSTOM_ACTION_TYPE_MASK, debugstr_w(source),
1618 debugstr_w(target) );
1619 }
1620
1621end:
1623 package->commit_action_running = FALSE;
1624 package->rollback_action_running = FALSE;
1625 msiobj_release(&row->hdr);
1626 return rc;
1627}
#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:862
static UINT defer_custom_action(MSIPACKAGE *package, const WCHAR *action, UINT type)
Definition: custom.c:1448
static UINT HANDLE_CustomType7(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1147
#define CUSTOM_ACTION_TYPE_MASK
Definition: custom.c:51
static UINT HANDLE_CustomType37_38(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1296
static BOOL check_execution_scheduling_options(MSIPACKAGE *package, LPCWSTR action, UINT options)
Definition: custom.c:142
static UINT HANDLE_CustomType21_22(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1355
static UINT HANDLE_CustomType23(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1066
static UINT HANDLE_CustomType17(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:975
static UINT HANDLE_CustomType2(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:956
static void set_deferred_action_props(MSIPACKAGE *package, const WCHAR *deferred_data)
Definition: custom.c:199
static BOOL action_type_matches_script(UINT type, UINT script)
Definition: custom.c:1430
static UINT HANDLE_CustomType34(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1199
static UINT HANDLE_CustomType5_6(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1307
static UINT HANDLE_CustomType18(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1006
static UINT HANDLE_CustomType50(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1181
static UINT HANDLE_CustomType53_54(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1414
static UINT HANDLE_CustomType19(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1024
DWORD deformat_string(MSIPACKAGE *package, const WCHAR *fmt, WCHAR **data)
Definition: format.c:1016
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolderPath)
Definition: install.c:564
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
GLenum target
Definition: glext.h:7315
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:2089
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT)
Definition: record.c:433
UINT msi_set_property(MSIDATABASE *, const WCHAR *, const WCHAR *, int)
Definition: package.c:2100
MSIRECORD *WINAPIV MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR query,...)
Definition: msiquery.c:201
WCHAR * msi_dup_property(MSIDATABASE *db, const WCHAR *prop)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
unsigned char commit_action_running
Definition: msipriv.h:467
MSIDATABASE * db
Definition: msipriv.h:394
unsigned char rollback_action_running
Definition: msipriv.h:468
enum script script
Definition: msipriv.h:432
unsigned char scheduled_action_running
Definition: msipriv.h:466
#define ERROR_FUNCTION_NOT_CALLED
Definition: winerror.h:984
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by ACTION_HandleCustomAction().

◆ ACTION_FinishCustomActions()

void ACTION_FinishCustomActions ( const MSIPACKAGE package)

Definition at line 1629 of file custom.c.

1630{
1631 struct list *item;
1632 HANDLE *wait_handles;
1633 unsigned int handle_count, i;
1635
1636 while ((item = list_head( &package->RunningActions )))
1637 {
1639
1640 list_remove( &action->entry );
1641
1642 TRACE("waiting for %s\n", debugstr_w( action->name ) );
1644
1645 CloseHandle( action->handle );
1646 free( action->name );
1647 free( action );
1648 }
1649
1651
1652 handle_count = list_count( &pending_custom_actions );
1653 wait_handles = malloc( handle_count * sizeof(HANDLE) );
1654
1655 handle_count = 0;
1657 {
1658 if (info->package == package )
1659 {
1660 if (DuplicateHandle(GetCurrentProcess(), info->handle, GetCurrentProcess(), &wait_handles[handle_count], SYNCHRONIZE, FALSE, 0))
1661 handle_count++;
1662 }
1663 }
1664
1666
1667 for (i = 0; i < handle_count; i++)
1668 {
1669 msi_dialog_check_messages( wait_handles[i] );
1670 CloseHandle( wait_handles[i] );
1671 }
1672 free( wait_handles );
1673
1676 {
1677 if (info->package == package)
1679 }
1681}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
Definition: list.h:37
#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:73
static CRITICAL_SECTION custom_action_cs
Definition: custom.c:63
static void free_custom_action_data(custom_action_info *info)
Definition: custom.c:396
void msi_dialog_check_messages(HANDLE handle)
Definition: dialog.c:3987
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
static ATOM item
Definition: dde.c:856
#define SYNCHRONIZE
Definition: nt_native.h:61
__WINE_SERVER_LIST_INLINE unsigned int list_count(const struct list *list)
Definition: list.h:155
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
Definition: list.h:15
struct list RunningActions
Definition: msipriv.h:440
#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 1430 of file custom.c.

1431{
1432 switch (script)
1433 {
1434 case SCRIPT_NONE:
1435 return FALSE;
1436 case SCRIPT_INSTALL:
1438 case SCRIPT_COMMIT:
1440 case SCRIPT_ROLLBACK:
1442 default:
1443 ERR("unhandled script %u\n", script);
1444 }
1445 return FALSE;
1446}
script
Definition: msipriv.h:383
@ SCRIPT_INSTALL
Definition: msipriv.h:385
@ SCRIPT_ROLLBACK
Definition: msipriv.h:387
@ SCRIPT_NONE
Definition: msipriv.h:384
@ SCRIPT_COMMIT
Definition: msipriv.h:386

Referenced by ACTION_CustomAction().

◆ build_msiexec_args()

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

Definition at line 1049 of file custom.c.

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

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 142 of file custom.c.

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

Referenced by ACTION_CustomAction().

◆ create_temp_binary()

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

Definition at line 244 of file custom.c.

245{
246 MSIRECORD *row;
248 HANDLE file;
249 CHAR buffer[1024];
250 WCHAR *tmpfile;
251 DWORD sz, write;
252 UINT r;
253
254 if (!(tmpfile = msi_create_temp_file( package->db ))) return NULL;
255
256 if (!(row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `Binary` WHERE `Name` = '%s'", source ))) goto error;
257 if (!(binary = calloc( 1, sizeof(MSIBINARY) ))) goto error;
258
260 if (file == INVALID_HANDLE_VALUE) goto error;
261
262 do
263 {
264 sz = sizeof(buffer);
265 r = MSI_RecordReadStream( row, 2, buffer, &sz );
266 if (r != ERROR_SUCCESS)
267 {
268 ERR("Failed to get stream\n");
269 break;
270 }
271 WriteFile( file, buffer, sz, &write, NULL );
272 } while (sz == sizeof buffer);
273
274 CloseHandle( file );
275 if (r != ERROR_SUCCESS) goto error;
276
277 binary->source = wcsdup( source );
278 binary->tmpfile = tmpfile;
279 list_add_tail( &package->binaries, &binary->entry );
280
281 msiobj_release( &row->hdr );
282 return binary;
283
284error:
285 if (row) msiobj_release( &row->hdr );
287 free( tmpfile );
288 free( binary );
289 return NULL;
290}
#define write
Definition: acwin.h:97
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 LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
WCHAR * msi_create_temp_file(MSIDATABASE *db)
Definition: custom.c:215
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint buffer
Definition: glext.h:5915
const GLuint GLenum const GLvoid * binary
Definition: glext.h:7538
_Check_return_ _CRTIMP FILE *__cdecl tmpfile(void)
Definition: file.c:3914
#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
#define calloc
Definition: rosglue.h:14
_Check_return_ _CRTIMP wchar_t *__cdecl wcsdup(_In_z_ const wchar_t *_Str)
Definition: fci.c:127
struct list binaries
Definition: msipriv.h:407
char CHAR
Definition: xmlstorage.h:175

Referenced by get_temp_binary().

◆ custom_client_thread()

static DWORD WINAPI custom_client_thread ( void arg)
static

Definition at line 692 of file custom.c.

693{
695 DWORD64 thread64;
698 HANDLE pipe;
699 DWORD size;
700 DWORD rc;
701
702 CoInitializeEx(NULL, COINIT_MULTITHREADED); /* needed to marshal streams */
703
704 if (info->arch == SCS_32BIT_BINARY)
705 {
706 process = info->package->custom_server_32_process;
707 pipe = info->package->custom_server_32_pipe;
708 }
709 else
710 {
711 process = info->package->custom_server_64_process;
712 pipe = info->package->custom_server_64_pipe;
713 }
714
716
717 if (!WriteFile(pipe, &info->guid, sizeof(info->guid), &size, NULL) ||
718 size != sizeof(info->guid))
719 {
720 ERR("failed to write to custom action client pipe: %lu\n", GetLastError());
722 return GetLastError();
723 }
724 if (!ReadFile(pipe, &thread64, sizeof(thread64), &size, NULL) || size != sizeof(thread64))
725 {
726 ERR("failed to read from custom action client pipe: %lu\n", GetLastError());
728 return GetLastError();
729 }
730
732
735 {
739 }
740 else
741 rc = GetLastError();
742
744 return rc;
745}
static HANDLE thread
Definition: service.c:33
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define INFINITE
Definition: serial.h:102
GLsizeiptr size
Definition: glext.h:5919
@ COINIT_MULTITHREADED
Definition: objbase.h:279
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:262
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 319 of file custom.c.

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

Referenced by wait_process_handle().

◆ custom_get_thread_return()

static UINT custom_get_thread_return ( MSIPACKAGE package,
HANDLE  thread 
)
static

Definition at line 330 of file custom.c.

331{
332 DWORD rc = 0;
333
335
336 switch (rc)
337 {
339 case ERROR_SUCCESS:
342 return rc;
344 return ERROR_SUCCESS;
346 ACTION_ForceReboot( package );
347 return ERROR_SUCCESS;
348 default:
349 ERR( "invalid Return Code %lu\n", rc );
351 }
352}
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
UINT ACTION_ForceReboot(MSIPACKAGE *package)
Definition: action.c:5219
#define ERROR_INSTALL_USEREXIT
Definition: winerror.h:960
#define ERROR_INSTALL_SUSPEND
Definition: winerror.h:962

Referenced by wait_thread_handle().

◆ custom_proc_wrapper()

static UINT custom_proc_wrapper ( MsiCustomActionEntryPoint  entry,
MSIHANDLE  hinst 
)
static

Definition at line 502 of file custom.c.

503{
504 return entry(hinst);
505}
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 619 of file custom.c.

620{
623 STARTUPINFOW si = {0};
624 WCHAR buffer[24];
626 void *cookie;
627 HANDLE pipe;
628
629 if ((arch == SCS_32BIT_BINARY && package->custom_server_32_process) ||
630 (arch == SCS_64BIT_BINARY && package->custom_server_64_process))
631 return ERROR_SUCCESS;
632
633 swprintf(buffer, ARRAY_SIZE(buffer), L"\\\\.\\pipe\\msica_%x_%d",
634 GetCurrentProcessId(), arch == SCS_32BIT_BINARY ? 32 : 64);
635 pipe = CreateNamedPipeW(buffer, PIPE_ACCESS_DUPLEX, 0, 1, sizeof(DWORD64),
636 sizeof(GUID), 0, NULL);
637 if (pipe == INVALID_HANDLE_VALUE)
638 ERR("failed to create custom action client pipe: %lu\n", GetLastError());
639
640 if ((sizeof(void *) == 8 || is_wow64) && arch == SCS_32BIT_BINARY)
642 else
643 GetSystemDirectoryW(path, MAX_PATH - ARRAY_SIZE(L"\\msiexec.exe"));
644 lstrcatW(path, L"\\msiexec.exe");
645 swprintf(cmdline, ARRAY_SIZE(cmdline), L"%s -Embedding %d", path, GetCurrentProcessId());
646
648
649 if (is_wow64 && arch == SCS_64BIT_BINARY)
650 {
654 }
655 else
657
658 if (token) CloseHandle(token);
659
660 CloseHandle(pi.hThread);
661
662 if (arch == SCS_32BIT_BINARY)
663 {
664 package->custom_server_32_process = pi.hProcess;
665 package->custom_server_32_pipe = pipe;
666 }
667 else
668 {
669 package->custom_server_64_process = pi.hProcess;
670 package->custom_server_64_pipe = pipe;
671 }
672
673 if (!ConnectNamedPipe(pipe, NULL))
674 {
675 ERR("failed to connect to custom action server: %lu\n", GetLastError());
676 return GetLastError();
677 }
678
679 return ERROR_SUCCESS;
680}
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:993
#define MAX_PATH
Definition: compat.h:34
UINT WINAPI GetSystemWow64DirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2421
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
BOOL WINAPI Wow64RevertWow64FsRedirection(IN PVOID OldValue)
Definition: utils.c:808
BOOL WINAPI Wow64DisableWow64FsRedirection(IN PVOID *OldValue)
Definition: utils.c:785
static HANDLE get_admin_token(void)
Definition: custom.c:597
BOOL is_wow64
Definition: msi.c:52
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
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
static refpint_t pi[]
Definition: server.c:96
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:443
HANDLE custom_server_32_pipe
Definition: msipriv.h:444
HANDLE custom_server_64_pipe
Definition: msipriv.h:445
HANDLE custom_server_32_process
Definition: msipriv.h:442
#define PIPE_ACCESS_DUPLEX
Definition: winbase.h:165
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define SCS_64BIT_BINARY
Definition: winbase.h:263

Referenced by do_msidbCustomActionTypeDll().

◆ custom_stop_server()

void custom_stop_server ( HANDLE  process,
HANDLE  pipe 
)

Definition at line 682 of file custom.c.

683{
684 DWORD size;
685
686 WriteFile(pipe, &GUID_NULL, sizeof(GUID_NULL), &size, NULL);
689 CloseHandle(pipe);
690}
#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 1448 of file custom.c.

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

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 792 of file custom.c.

794{
797 BOOL ret;
798
799 info = malloc( sizeof *info );
800 if (!info)
801 return NULL;
802
803 msiobj_addref( &package->hdr );
804 info->package = package;
805 info->type = type;
806 info->target = wcsdup( target );
807 info->source = wcsdup( source );
808 info->action = wcsdup( action );
809 CoCreateGuid( &info->guid );
810
814
815 if (!package->rpc_server_started)
816 {
817 WCHAR endpoint[12];
818
821 endpoint, NULL);
822 if (status != RPC_S_OK)
823 {
824 ERR("RpcServerUseProtseqEp failed: %#lx\n", status);
825 return NULL;
826 }
827
828 status = RpcServerRegisterIfEx(s_IWineMsiRemote_v0_0_s_ifspec, NULL, NULL,
830 if (status != RPC_S_OK)
831 {
832 ERR("RpcServerRegisterIfEx failed: %#lx\n", status);
833 return NULL;
834 }
835
836 info->package->rpc_server_started = 1;
837 }
838
839 ret = get_binary_type(source, &info->arch);
840 if (!ret)
841 info->arch = (sizeof(void *) == 8 ? SCS_64BIT_BINARY : SCS_32BIT_BINARY);
842
843 if (info->arch == SCS_64BIT_BINARY && sizeof(void *) == 4 && !is_wow64)
844 {
845 ERR("Attempt to run a 64-bit custom action inside a 32-bit WINEPREFIX.\n");
847 return NULL;
848 }
849
850 custom_start_server(package, info->arch);
851
853 if (!info->handle)
854 {
856 return NULL;
857 }
858
859 return info;
860}
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:619
static DWORD WINAPI custom_client_thread(void *arg)
Definition: custom.c:692
static BOOL get_binary_type(const WCHAR *name, DWORD *type)
Definition: custom.c:748
void msiobj_addref(MSIOBJECTHDR *info)
Definition: handle.c:217
HRESULT WINAPI CoCreateGuid(GUID *pguid)
Definition: compobj.c:2206
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:393
unsigned char rpc_server_started
Definition: msipriv.h:472

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 1265 of file custom.c.

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

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 889 of file custom.c.

890{
891 STARTUPINFOW si;
893 WCHAR *exe = NULL, *cmd = NULL, *p;
894 BOOL ret;
895
896 if (app)
897 {
898 int len_arg = 0;
899 DWORD len_exe;
900
901 if (!(exe = malloc( MAX_PATH * sizeof(WCHAR) ))) return INVALID_HANDLE_VALUE;
902 len_exe = SearchPathW( NULL, app, L".exe", MAX_PATH, exe, NULL );
903 if (len_exe >= MAX_PATH)
904 {
905 free( exe );
906 if (!(exe = malloc( len_exe * sizeof(WCHAR) ))) return INVALID_HANDLE_VALUE;
907 len_exe = SearchPathW( NULL, app, L".exe", len_exe, exe, NULL );
908 }
909 if (!len_exe)
910 {
911 ERR("can't find executable %lu\n", GetLastError());
912 free( exe );
914 }
915
916 if (arg) len_arg = lstrlenW( arg );
917 if (!(cmd = malloc( (len_exe + len_arg + 4) * sizeof(WCHAR) )))
918 {
919 free( exe );
921 }
922 p = cmd;
923 if (wcschr( exe, ' ' ))
924 {
925 *p++ = '\"';
926 memcpy( p, exe, len_exe * sizeof(WCHAR) );
927 p += len_exe;
928 *p++ = '\"';
929 *p = 0;
930 }
931 else
932 {
933 lstrcpyW( p, exe );
934 p += len_exe;
935 }
936 if (arg)
937 {
938 *p++ = ' ';
939 memcpy( p, arg, len_arg * sizeof(WCHAR) );
940 p[len_arg] = 0;
941 }
942 }
943 memset( &si, 0, sizeof(STARTUPINFOW) );
944 ret = CreateProcessW( exe, exe ? cmd : arg, NULL, NULL, FALSE, 0, NULL, dir, &si, &info );
945 free( cmd );
946 free( exe );
947 if (!ret)
948 {
949 ERR("unable to execute command %lu\n", GetLastError());
951 }
952 CloseHandle( info.hThread );
953 return info.hProcess;
954}
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:1298
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:4598
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 305 of file custom.c.

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

Referenced by wait_process_handle().

◆ find_action_by_guid()

static custom_action_info * find_action_by_guid ( const GUID guid)
static

Definition at line 435 of file custom.c.

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

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 396 of file custom.c.

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

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 597 of file custom.c.

598{
600 TOKEN_LINKED_TOKEN linked;
601 DWORD size;
602
603#ifdef __REACTOS__
604#ifndef GetCurrentThreadEffectiveToken
605#define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3)
606#define GetCurrentThreadEffectiveToken() GetCurrentProcessToken()
607#endif
608#endif
609
612 return NULL;
613
615 return NULL;
616 return linked.LinkedToken;
617}
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
#define GetCurrentThreadEffectiveToken()
Definition: security.c:42
enum _TOKEN_ELEVATION_TYPE TOKEN_ELEVATION_TYPE
@ TokenElevationTypeFull
Definition: winnt_old.h:2516
@ TokenElevationType
Definition: setypes.h:983
@ TokenLinkedToken
Definition: setypes.h:984

Referenced by custom_start_server().

◆ get_binary_type()

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

Definition at line 748 of file custom.c.

749{
750 HANDLE hfile, mapping;
752
754 if (hfile == INVALID_HANDLE_VALUE)
755 return FALSE;
756
758 SEC_IMAGE, hfile );
759 CloseHandle( hfile );
760
761 switch (status)
762 {
763 case STATUS_SUCCESS:
764 {
766
769 if (status) return FALSE;
770 switch (info.Machine)
771 {
775 return TRUE;
779 return TRUE;
780 default:
781 return FALSE;
782 }
783 }
786 return TRUE;
787 default:
788 return FALSE;
789 }
790}
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:3074
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:1287
#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:901
#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:3773
#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 181 of file custom.c.

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

Referenced by defer_custom_action().

◆ get_temp_binary()

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

Definition at line 292 of file custom.c.

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

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 862 of file custom.c.

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

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 975 of file custom.c.

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

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 1006 of file custom.c.

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

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 1024 of file custom.c.

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

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 956 of file custom.c.

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

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 1355 of file custom.c.

1357{
1359 MSIFILE *file;
1360 HANDLE hFile;
1361 DWORD sz, szHighWord = 0, read;
1362 CHAR *buffer=NULL;
1363 WCHAR *bufferw=NULL;
1364 BOOL bRet;
1365 UINT r;
1366
1367 TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
1368
1369 file = msi_get_loaded_file(package, source);
1370 if (!file)
1371 {
1372 ERR("invalid file key %s\n", debugstr_w(source));
1373 return ERROR_FUNCTION_FAILED;
1374 }
1375
1376 hFile = msi_create_file( package, file->TargetPath, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 );
1378
1379 sz = GetFileSize(hFile, &szHighWord);
1380 if (sz == INVALID_FILE_SIZE || szHighWord != 0)
1381 {
1383 return ERROR_FUNCTION_FAILED;
1384 }
1385 buffer = malloc( sz + 1 );
1386 if (!buffer)
1387 {
1389 return ERROR_FUNCTION_FAILED;
1390 }
1391 bRet = ReadFile(hFile, buffer, sz, &read, NULL);
1393 if (!bRet)
1394 {
1396 goto done;
1397 }
1398 buffer[read] = 0;
1399 bufferw = strdupAtoW(buffer);
1400 if (!bufferw)
1401 {
1403 goto done;
1404 }
1405 info = do_msidbCustomActionTypeScript( package, type, bufferw, target, action );
1407
1408done:
1409 free(bufferw);
1410 free(buffer);
1411 return r;
1412}
#define read
Definition: acwin.h:96
static WCHAR * strdupAtoW(const char *str)
Definition: main.c:65
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:1265
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:574

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 1066 of file custom.c.

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

1201{
1202 const WCHAR *workingdir = NULL;
1203 HANDLE handle;
1204 WCHAR *cmd;
1205
1206 if (source)
1207 {
1208 workingdir = msi_get_target_folder( package, source );
1209 if (!workingdir) return ERROR_FUNCTION_FAILED;
1210 }
1211 deformat_string( package, target, &cmd );
1212 if (!cmd) return ERROR_FUNCTION_FAILED;
1213
1214 TRACE("cmd %s dir %s\n", debugstr_w(cmd), debugstr_w(workingdir));
1215
1216 handle = execute_command( NULL, cmd, workingdir );
1217 free( cmd );
1219 return wait_process_handle( package, type, handle, action );
1220}
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 1296 of file custom.c.

1298{
1300
1301 TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
1302
1304 return wait_thread_handle( info );
1305}

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 1181 of file custom.c.

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

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 1414 of file custom.c.

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

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 1307 of file custom.c.

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

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 1147 of file custom.c.

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

Referenced by ACTION_CustomAction().

◆ handle_msi_break()

static void handle_msi_break ( const WCHAR action)
static

Definition at line 459 of file custom.c.

460{
461 const WCHAR fmt[] = L"To debug your custom action, attach your debugger to process %u (0x%x) and press OK";
462 WCHAR val[MAX_PATH], msg[100];
463
464 if (!GetEnvironmentVariableW( L"MsiBreak", val, MAX_PATH ) || wcscmp( val, action )) return;
465
467 MessageBoxW( NULL, msg, L"Windows Installer", MB_OK );
468 DebugBreak();
469}
#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 75 of file custom.c.

76{
77 return malloc(len);
78}

◆ MIDL_user_free()

void __RPC_USER MIDL_user_free ( void __RPC_FAR ptr)

Definition at line 80 of file custom.c.

81{
82 free(ptr);
83}

◆ msi_action_is_unique()

BOOL msi_action_is_unique ( const MSIPACKAGE package,
const WCHAR action 
)

Definition at line 131 of file custom.c.

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

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 215 of file custom.c.

216{
217 WCHAR *ret;
218
219 if (!db->tempfolder)
220 {
221 WCHAR tmp[MAX_PATH];
222 DWORD len = ARRAY_SIZE( tmp );
223
224 if (msi_get_property( db, L"TempFolder", tmp, &len ) ||
226 {
227 GetTempPathW( MAX_PATH, tmp );
228 }
229 if (!(db->tempfolder = wcsdup( tmp ))) return NULL;
230 }
231
232 if ((ret = malloc( (wcslen( db->tempfolder ) + 20) * sizeof(WCHAR) )))
233 {
234 if (!GetTempFileNameW( db->tempfolder, L"msi", 0, ret ))
235 {
236 free( ret );
237 return NULL;
238 }
239 }
240
241 return ret;
242}
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
UINT msi_get_property(MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD)
Definition: package.c:2250
#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 113 of file custom.c.

114{
115 UINT count;
116 WCHAR **newbuf = NULL;
117
118 TRACE("Registering %s as unique action\n", debugstr_w(action));
119
120 count = package->unique_actions_count;
121 package->unique_actions_count++;
122 if (count != 0) newbuf = realloc( package->unique_actions,
123 package->unique_actions_count * sizeof(WCHAR *) );
124 else newbuf = malloc( sizeof(WCHAR *) );
125
126 newbuf[count] = wcsdup( action );
127 package->unique_actions = newbuf;
128 return ERROR_SUCCESS;
129}
#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 90 of file custom.c.

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

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()

◆ s_remote_GetActionInfo()

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

Definition at line 1683 of file custom.c.

1684{
1686
1688 if (!info)
1689 return ERROR_INVALID_DATA;
1690
1691 *name = wcsdup(info->action);
1692 *type = info->type;
1693 *hinst = alloc_msihandle(&info->package->hdr);
1694 *dll = wcsdup(info->source);
1695 *func = strdupWtoA(info->target);
1696
1697 return ERROR_SUCCESS;
1698}
GLenum func
Definition: glext.h:6028
static LPSTR strdupWtoA(LPCWSTR str)
Definition: hhctrl.h:299
#define ERROR_INVALID_DATA
Definition: winerror.h:116

◆ ScriptThread()

static DWORD WINAPI ScriptThread ( LPVOID  arg)
static

Definition at line 1250 of file custom.c.

1251{
1252 LPGUID guid = arg;
1253 DWORD rc;
1254
1255 TRACE("custom action (%#lx) started\n", GetCurrentThreadId() );
1256
1257 rc = ACTION_CallScript( guid );
1258
1259 TRACE("custom action (%#lx) returned %lu\n", GetCurrentThreadId(), rc );
1260
1262 return rc;
1263}
static DWORD ACTION_CallScript(const GUID *guid)
Definition: custom.c:1222
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 199 of file custom.c.

200{
201 const WCHAR *end, *beg = deferred_data + 1;
202
203 end = wcsstr(beg, L"<=>");
204 msi_set_property( package->db, L"CustomActionData", beg, end - beg );
205 beg = end + 3;
206
207 end = wcsstr(beg, L"<=>");
208 msi_set_property( package->db, L"UserSID", beg, end - beg );
209 beg = end + 3;
210
211 end = wcschr(beg, ']');
212 msi_set_property( package->db, L"ProductCode", beg, end - beg );
213}
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)

Referenced by ACTION_CustomAction().

◆ wait_process_handle()

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

Definition at line 354 of file custom.c.

356{
357 UINT rc = ERROR_SUCCESS;
358
360 {
361 TRACE("waiting for %s\n", debugstr_w(name));
362
364
367
369 }
370 else
371 {
372 TRACE("%s running in background\n", debugstr_w(name));
373
376 else
378 }
379
380 return rc;
381}
static UINT custom_get_process_return(HANDLE process)
Definition: custom.c:319
static void file_running_action(MSIPACKAGE *package, HANDLE Handle, BOOL process, LPCWSTR name)
Definition: custom.c:305
@ msidbCustomActionTypeContinue
Definition: msidefs.h:128
@ msidbCustomActionTypeAsync
Definition: msidefs.h:129
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403

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 412 of file custom.c.

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

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 1108 of file custom.c.

1109{
1110 IStorage *src = NULL, *dst = NULL;
1112 HRESULT hr;
1113
1115 if (FAILED( hr ))
1116 {
1117 WARN( "can't open destination storage %s (%#lx)\n", debugstr_w(filename), hr );
1118 goto done;
1119 }
1120
1121 hr = IStorage_OpenStorage( package->db->storage, source, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &src );
1122 if (FAILED( hr ))
1123 {
1124 WARN( "can't open source storage %s (%#lx)\n", debugstr_w(source), hr );
1125 goto done;
1126 }
1127
1128 hr = IStorage_CopyTo( src, 0, NULL, NULL, dst );
1129 if (FAILED( hr ))
1130 {
1131 ERR( "failed to copy storage %s (%#lx)\n", debugstr_w(source), hr );
1132 goto done;
1133 }
1134
1135 hr = IStorage_Commit( dst, 0 );
1136 if (FAILED( hr ))
1137 ERR( "failed to commit storage (%#lx)\n", hr );
1138 else
1139 r = ERROR_SUCCESS;
1140
1141done:
1142 if (src) IStorage_Release( src );
1143 if (dst) IStorage_Release( dst );
1144 return r;
1145}
HRESULT WINAPI StgCreateDocfile(LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved, IStorage **ppstgOpen)
Definition: storage32.c:8636
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:926
#define STGM_TRANSACTED
Definition: objbase.h:915
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923
#define STGM_WRITE
Definition: objbase.h:918
HRESULT hr
Definition: shlfolder.c:183
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:64
LIST_ENTRY ProcessLocksList
Definition: winbase.h:908
#define DWORD_PTR
Definition: treelist.c:76

Definition at line 64 of file custom.c.

◆ pending_custom_actions

struct list pending_custom_actions = LIST_INIT( pending_custom_actions )
static