ReactOS 0.4.15-dev-8434-g155a7c7
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  tagMSIRUNNINGACTION
 
struct  _msi_custom_action_info
 

Macros

#define COBJMACROS
 
#define WIN32_NO_STATUS
 
#define CUSTOM_ACTION_TYPE_MASK   0x3F
 

Typedefs

typedef struct tagMSIRUNNINGACTION MSIRUNNINGACTION
 
typedef UINT(WINAPIMsiCustomActionEntryPoint) (MSIHANDLE)
 
typedef struct _msi_custom_action_info msi_custom_action_info
 

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 LPWSTR msi_get_deferred_action (LPCWSTR action, LPCWSTR actiondata, LPCWSTR usersid, LPCWSTR 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 (msi_custom_action_info *info)
 
static UINT wait_thread_handle (msi_custom_action_info *info)
 
static msi_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 msi_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 msi_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 msi_custom_action_cs = { &msi_custom_action_cs_debug, -1, 0, 0, 0, 0 }
 
static CRITICAL_SECTION_DEBUG msi_custom_action_cs_debug
 
static struct list msi_pending_custom_actions = LIST_INIT( msi_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

◆ msi_custom_action_info

◆ MsiCustomActionEntryPoint

typedef UINT(WINAPI * MsiCustomActionEntryPoint) (MSIHANDLE)

Definition at line 61 of file custom.c.

◆ MSIRUNNINGACTION

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 );
554 }
555
557 if (!hModule)
558 {
559 ERR( "failed to load dll %s (%lu)\n", debugstr_w( dll ), GetLastError() );
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
591
593 return r;
594}
#define ARRAY_SIZE(A)
Definition: main.h:33
#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:7479
static void handle_msi_break(const WCHAR *action)
Definition: custom.c:458
UINT(WINAPI * MsiCustomActionEntryPoint)(MSIHANDLE)
Definition: custom.c:61
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
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#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:386
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 GetExceptionCode()
Definition: seh.h:27
#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 1219 of file custom.c.

1220{
1222 MSIHANDLE hPackage;
1224
1226 if (!info)
1227 {
1228 ERR("failed to find action %s\n", debugstr_guid( guid) );
1229 return ERROR_FUNCTION_FAILED;
1230 }
1231
1232 TRACE("function %s, script %s\n", debugstr_w( info->target ), debugstr_w( info->source ) );
1233
1234 hPackage = alloc_msihandle( &info->package->hdr );
1235 if (hPackage)
1236 {
1237 r = call_script( hPackage, info->type, info->source, info->target, info->action );
1238 TRACE("script returned %u\n", r);
1239 MsiCloseHandle( hPackage );
1240 }
1241 else
1242 ERR("failed to create handle for %p\n", info->package );
1243
1244 return r;
1245}
static msi_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) DECLSPEC_HIDDEN
Definition: script.c:288
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985

Referenced by ScriptThread().

◆ ACTION_CustomAction()

UINT ACTION_CustomAction ( MSIPACKAGE package,
const WCHAR action 
)

Definition at line 1482 of file custom.c.

1483{
1484 UINT rc = ERROR_SUCCESS;
1485 MSIRECORD *row;
1486 UINT type;
1487 const WCHAR *source, *target, *ptr, *deferred_data = NULL;
1488 WCHAR *deformated = NULL;
1489 int len;
1490
1491 /* deferred action: [properties]Action */
1492 if ((ptr = wcsrchr(action, ']')))
1493 {
1494 deferred_data = action;
1495 action = ptr + 1;
1496 }
1497
1498 row = MSI_QueryGetRecord( package->db, L"SELECT * FROM `CustomAction` WHERE `Action` = '%s'", action );
1499 if (!row)
1501
1505
1506 TRACE("Handling custom action %s (%x %s %s)\n",debugstr_w(action),type,
1508
1509 /* handle some of the deferred actions */
1511 FIXME("msidbCustomActionTypeTSAware not handled\n");
1512
1514 {
1516 WARN("msidbCustomActionTypeNoImpersonate not handled\n");
1517
1518 if (!action_type_matches_script(type, package->script))
1519 {
1520 rc = defer_custom_action( package, action, type );
1521 goto end;
1522 }
1523 else
1524 {
1525 LPWSTR actiondata = msi_dup_property( package->db, action );
1526
1528 package->scheduled_action_running = TRUE;
1529
1531 package->commit_action_running = TRUE;
1532
1534 package->rollback_action_running = TRUE;
1535
1536 if (deferred_data)
1537 set_deferred_action_props(package, deferred_data);
1538 else if (actiondata)
1539 msi_set_property( package->db, L"CustomActionData", actiondata, -1 );
1540 else
1541 msi_set_property( package->db, L"CustomActionData", L"", -1 );
1542
1543 msi_free(actiondata);
1544 }
1545 }
1547 {
1548 rc = ERROR_SUCCESS;
1549 goto end;
1550 }
1551
1552 switch (type & CUSTOM_ACTION_TYPE_MASK)
1553 {
1554 case 1: /* DLL file stored in a Binary table stream */
1555 rc = HANDLE_CustomType1( package, source, target, type, action );
1556 break;
1557 case 2: /* EXE file stored in a Binary table stream */
1558 rc = HANDLE_CustomType2( package, source, target, type, action );
1559 break;
1560 case 5:
1561 case 6: /* JScript/VBScript file stored in a Binary table stream */
1562 rc = HANDLE_CustomType5_6( package, source, target, type, action );
1563 break;
1564 case 7: /* Concurrent install from substorage */
1565 deformat_string( package, target, &deformated );
1566 rc = HANDLE_CustomType7( package, source, target, type, action );
1567 msi_free( deformated );
1568 break;
1569 case 17:
1570 rc = HANDLE_CustomType17( package, source, target, type, action );
1571 break;
1572 case 18: /* EXE file installed with package */
1573 rc = HANDLE_CustomType18( package, source, target, type, action );
1574 break;
1575 case 19: /* Error that halts install */
1576 rc = HANDLE_CustomType19( package, source, target, type, action );
1577 break;
1578 case 21: /* JScript/VBScript file installed with the product */
1579 case 22:
1580 rc = HANDLE_CustomType21_22( package, source, target, type, action );
1581 break;
1582 case 23: /* Installs another package in the source tree */
1583 deformat_string( package, target, &deformated );
1584 rc = HANDLE_CustomType23( package, source, deformated, type, action );
1585 msi_free( deformated );
1586 break;
1587 case 34: /* EXE to be run in specified directory */
1588 rc = HANDLE_CustomType34( package, source, target, type, action );
1589 break;
1590 case 35: /* Directory set with formatted text */
1591 deformat_string( package, target, &deformated );
1592 MSI_SetTargetPathW( package, source, deformated );
1593 msi_free( deformated );
1594 break;
1595 case 37: /* JScript/VBScript text stored in target column */
1596 case 38:
1597 rc = HANDLE_CustomType37_38( package, source, target, type, action );
1598 break;
1599 case 50: /* EXE file specified by a property value */
1600 rc = HANDLE_CustomType50( package, source, target, type, action );
1601 break;
1602 case 51: /* Property set with formatted text */
1603 if (!source) break;
1604 len = deformat_string( package, target, &deformated );
1605 rc = msi_set_property( package->db, source, deformated, len );
1606 if (rc == ERROR_SUCCESS && !wcscmp( source, L"SourceDir" )) msi_reset_source_folders( package );
1607 msi_free( deformated );
1608 break;
1609 case 53: /* JScript/VBScript text specified by a property value */
1610 case 54:
1611 rc = HANDLE_CustomType53_54( package, source, target, type, action );
1612 break;
1613 default:
1614 FIXME( "unhandled action type %u (%s %s)\n", type & CUSTOM_ACTION_TYPE_MASK, debugstr_w(source),
1615 debugstr_w(target) );
1616 }
1617
1618end:
1620 package->commit_action_running = FALSE;
1621 package->rollback_action_running = FALSE;
1622 msiobj_release(&row->hdr);
1623 return rc;
1624}
#define FIXME(fmt,...)
Definition: precomp.h:53
#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:1445
static UINT HANDLE_CustomType7(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1144
#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:1293
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:1352
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:199
static BOOL action_type_matches_script(UINT type, UINT script)
Definition: custom.c:1427
static UINT HANDLE_CustomType34(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1196
static UINT HANDLE_CustomType5_6(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1304
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:1178
static UINT HANDLE_CustomType53_54(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
Definition: custom.c:1411
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: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
UINT msi_set_property(MSIDATABASE *, const WCHAR *, const WCHAR *, int) DECLSPEC_HIDDEN
Definition: package.c:2100
MSIRECORD *WINAPIV MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR query,...) DECLSPEC_HIDDEN
Definition: msiquery.c:201
static void msi_free(void *mem)
Definition: msipriv.h:1159
int MSI_RecordGetInteger(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:213
void msi_reset_source_folders(MSIPACKAGE *package) DECLSPEC_HIDDEN
Definition: package.c:2089
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:433
LPWSTR msi_dup_property(MSIDATABASE *db, LPCWSTR prop) DECLSPEC_HIDDEN
Definition: package.c:2283
_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 1626 of file custom.c.

1627{
1628 struct list *item;
1629 HANDLE *wait_handles;
1630 unsigned int handle_count, i;
1632
1633 while ((item = list_head( &package->RunningActions )))
1634 {
1636
1637 list_remove( &action->entry );
1638
1639 TRACE("waiting for %s\n", debugstr_w( action->name ) );
1641
1642 CloseHandle( action->handle );
1643 msi_free( action->name );
1644 msi_free( action );
1645 }
1646
1648
1649 handle_count = list_count( &msi_pending_custom_actions );
1650 wait_handles = msi_alloc( handle_count * sizeof(HANDLE) );
1651
1652 handle_count = 0;
1654 {
1655 if (info->package == package )
1656 {
1657 if (DuplicateHandle(GetCurrentProcess(), info->handle, GetCurrentProcess(), &wait_handles[handle_count], SYNCHRONIZE, FALSE, 0))
1658 handle_count++;
1659 }
1660 }
1661
1663
1664 for (i = 0; i < handle_count; i++)
1665 {
1666 msi_dialog_check_messages( wait_handles[i] );
1667 CloseHandle( wait_handles[i] );
1668 }
1669 msi_free( wait_handles );
1670
1673 {
1674 if (info->package == package)
1676 }
1678}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
Definition: list.h:37
#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 msi_pending_custom_actions
Definition: custom.c:73
static CRITICAL_SECTION msi_custom_action_cs
Definition: custom.c:63
static void free_custom_action_data(msi_custom_action_info *info)
Definition: custom.c:395
void msi_dialog_check_messages(HANDLE handle)
Definition: dialog.c:4072
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
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
#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 1427 of file custom.c.

1428{
1429 switch (script)
1430 {
1431 case SCRIPT_NONE:
1432 return FALSE;
1433 case SCRIPT_INSTALL:
1435 case SCRIPT_COMMIT:
1437 case SCRIPT_ROLLBACK:
1439 default:
1440 ERR("unhandled script %u\n", script);
1441 }
1442 return FALSE;
1443}
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 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 = msi_alloc( (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
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 = msi_alloc_zero( 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 = strdupW( 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 msi_free( tmpfile );
288 msi_free( binary );
289 return NULL;
290}
#define write
Definition: acwin.h:97
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
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
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
UINT MSI_RecordReadStream(MSIRECORD *, UINT, char *, LPDWORD) DECLSPEC_HIDDEN
Definition: record.c:761
#define GENERIC_WRITE
Definition: nt_native.h:90
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 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
#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:236
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:5183
#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 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
659 CloseHandle(pi.hThread);
660
661 if (arch == SCS_32BIT_BINARY)
662 {
663 package->custom_server_32_process = pi.hProcess;
664 package->custom_server_32_pipe = pipe;
665 }
666 else
667 {
668 package->custom_server_64_process = pi.hProcess;
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: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:596
BOOL is_wow64
Definition: msi.c:54
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:164
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define SCS_64BIT_BINARY
Definition: winbase.h:237

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

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

Referenced by ACTION_CustomAction().

◆ do_msidbCustomActionTypeDll()

static msi_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 = msi_alloc( 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 = strdupW( target );
806 info->source = strdupW( source );
807 info->action = strdupW( 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}
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
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 msi_custom_action_info * do_msidbCustomActionTypeScript ( MSIPACKAGE package,
INT  type,
LPCWSTR  script,
LPCWSTR  function,
LPCWSTR  action 
)
static

Definition at line 1262 of file custom.c.

1264{
1266
1267 info = msi_alloc( sizeof *info );
1268 if (!info)
1269 return NULL;
1270
1271 msiobj_addref( &package->hdr );
1272 info->package = package;
1273 info->type = type;
1274 info->target = strdupW( function );
1275 info->source = strdupW( script );
1276 info->action = strdupW( action );
1277 CoCreateGuid( &info->guid );
1278
1282
1283 info->handle = CreateThread( NULL, 0, ScriptThread, &info->guid, 0, NULL );
1284 if (!info->handle)
1285 {
1287 return NULL;
1288 }
1289
1290 return info;
1291}
static DWORD WINAPI ScriptThread(LPVOID arg)
Definition: custom.c:1247

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{
890 STARTUPINFOW si;
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 = msi_alloc( 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 msi_free( exe );
905 if (!(exe = msi_alloc( 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 msi_free( exe );
913 }
914
915 if (arg) len_arg = lstrlenW( arg );
916 if (!(cmd = msi_alloc( (len_exe + len_arg + 4) * sizeof(WCHAR) )))
917 {
918 msi_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 msi_free( cmd );
945 msi_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: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:4592
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{
309
310 action = msi_alloc( sizeof(MSIRUNNINGACTION) );
311
312 action->handle = Handle;
313 action->process = process;
314 action->name = strdupW(name);
315
316 list_add_tail( &package->RunningActions, &action->entry );
317}
ULONG Handle
Definition: gdb_input.c:15
Definition: name.c:39

Referenced by wait_process_handle().

◆ find_action_by_guid()

static msi_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:198

Referenced by ACTION_CallScript(), and s_remote_GetActionInfo().

◆ free_custom_action_data()

static void free_custom_action_data ( msi_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 msi_free( info->action );
403 msi_free( info->source );
404 msi_free( info->target );
405 msiobj_release( &info->package->hdr );
406 msi_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
611 return NULL;
612
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
#define GetCurrentThreadEffectiveToken()
Definition: security.c:42
enum _TOKEN_ELEVATION_TYPE TOKEN_ELEVATION_TYPE
@ TokenElevationTypeFull
Definition: winnt_old.h:2487
@ 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 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: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:3768
#define STATUS_SUCCESS
Definition: shellext.h:65

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

◆ 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 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 msi_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:292
static UINT wait_thread_handle(msi_custom_action_info *info)
Definition: custom.c:411

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

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 msi_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: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 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 msi_free( deformated );
1044
1045 return ERROR_INSTALL_FAILURE;
1046}
@ 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:790
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 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 msi_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 1352 of file custom.c.

1354{
1356 MSIFILE *file;
1357 HANDLE hFile;
1358 DWORD sz, szHighWord = 0, read;
1359 CHAR *buffer=NULL;
1360 WCHAR *bufferw=NULL;
1361 BOOL bRet;
1362 UINT r;
1363
1364 TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
1365
1366 file = msi_get_loaded_file(package, source);
1367 if (!file)
1368 {
1369 ERR("invalid file key %s\n", debugstr_w(source));
1370 return ERROR_FUNCTION_FAILED;
1371 }
1372
1373 hFile = msi_create_file( package, file->TargetPath, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, 0 );
1375
1376 sz = GetFileSize(hFile, &szHighWord);
1377 if (sz == INVALID_FILE_SIZE || szHighWord != 0)
1378 {
1380 return ERROR_FUNCTION_FAILED;
1381 }
1382 buffer = msi_alloc( sz + 1 );
1383 if (!buffer)
1384 {
1386 return ERROR_FUNCTION_FAILED;
1387 }
1388 bRet = ReadFile(hFile, buffer, sz, &read, NULL);
1390 if (!bRet)
1391 {
1393 goto done;
1394 }
1395 buffer[read] = 0;
1396 bufferw = strdupAtoW(buffer);
1397 if (!bufferw)
1398 {
1400 goto done;
1401 }
1402 info = do_msidbCustomActionTypeScript( package, type, bufferw, target, action );
1404
1405done:
1406 msi_free(bufferw);
1408 return r;
1409}
#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 msi_custom_action_info * do_msidbCustomActionTypeScript(MSIPACKAGE *package, INT type, LPCWSTR script, LPCWSTR function, LPCWSTR action)
Definition: custom.c:1262
HANDLE msi_create_file(MSIPACKAGE *package, const WCHAR *filename, DWORD access, DWORD sharing, DWORD creation, DWORD flags)
Definition: files.c:51
_In_ HANDLE hFile
Definition: mswsock.h:90
#define INVALID_FILE_SIZE
Definition: winbase.h:548

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 msi_free( dir );
1076 return ERROR_FUNCTION_FAILED;
1077 }
1078 *p = 0;
1079 len_dir = p - dir;
1080 if (!(filename = msi_alloc( (len_dir + len_source + 2) * sizeof(WCHAR) )))
1081 {
1082 msi_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 msi_free( dir );
1093 return ERROR_OUTOFMEMORY;
1094 }
1095
1096 TRACE("installing %s concurrently\n", debugstr_w(source));
1097
1098 handle = execute_command( L"msiexec", args, dir );
1099 msi_free( dir );
1100 msi_free( args );
1102 return wait_process_handle( package, type, handle, action );
1103}
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 1196 of file custom.c.

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

1295{
1297
1298 TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
1299
1301 return wait_thread_handle( info );
1302}

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

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

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

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

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

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

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

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

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

76{
77 return malloc(len);
78}
#define malloc
Definition: debug_ros.c:4

◆ 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}
#define free
Definition: debug_ros.c:5

◆ 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 = strdupW( tmp ))) return NULL;
230 }
231
232 if ((ret = msi_alloc( (lstrlenW( db->tempfolder ) + 20) * sizeof(WCHAR) )))
233 {
234 if (!GetTempFileNameW( db->tempfolder, L"msi", 0, ret ))
235 {
236 msi_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
UINT msi_get_property(MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD) DECLSPEC_HIDDEN
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(), msi_load_image(), patch_file(), and patchfiles_cb().

◆ msi_get_deferred_action()

static LPWSTR msi_get_deferred_action ( LPCWSTR  action,
LPCWSTR  actiondata,
LPCWSTR  usersid,
LPCWSTR  prodcode 
)
static

Definition at line 181 of file custom.c.

183{
184 LPWSTR deferred;
185 DWORD len;
186
187 if (!actiondata)
188 return strdupW(action);
189
190 len = lstrlenW(action) + lstrlenW(actiondata) +
191 lstrlenW(usersid) + lstrlenW(prodcode) +
192 lstrlenW(L"[%s<=>%s<=>%s]%s") - 7;
193 deferred = msi_alloc(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().

◆ 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 = msi_realloc( package->unique_actions,
123 package->unique_actions_count * sizeof(WCHAR *) );
124 else newbuf = msi_alloc( sizeof(WCHAR *) );
125
126 newbuf[count] = strdupW( action );
127 package->unique_actions = newbuf;
128 return ERROR_SUCCESS;
129}
GLuint GLuint GLsizei count
Definition: gl.h:1545
static void * msi_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2)
Definition: msipriv.h:1154

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 = msi_realloc( package->script_actions[script],
105 package->script_actions_count[script] * sizeof(WCHAR *) );
106 else newbuf = msi_alloc( sizeof(WCHAR *) );
107
108 newbuf[count] = strdupW( 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 1680 of file custom.c.

1681{
1683
1685 if (!info)
1686 return ERROR_INVALID_DATA;
1687
1688 *name = strdupW(info->action);
1689 *type = info->type;
1690 *hinst = alloc_msihandle(&info->package->hdr);
1691 *dll = strdupW(info->source);
1692 *func = strdupWtoA(info->target);
1693
1694 return ERROR_SUCCESS;
1695}
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 1247 of file custom.c.

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

1106{
1107 IStorage *src = NULL, *dst = NULL;
1109 HRESULT hr;
1110
1112 if (FAILED( hr ))
1113 {
1114 WARN( "can't open destination storage %s (%#lx)\n", debugstr_w(filename), hr );
1115 goto done;
1116 }
1117
1118 hr = IStorage_OpenStorage( package->db->storage, source, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &src );
1119 if (FAILED( hr ))
1120 {
1121 WARN( "can't open source storage %s (%#lx)\n", debugstr_w(source), hr );
1122 goto done;
1123 }
1124
1125 hr = IStorage_CopyTo( src, 0, NULL, NULL, dst );
1126 if (FAILED( hr ))
1127 {
1128 ERR( "failed to copy storage %s (%#lx)\n", debugstr_w(source), hr );
1129 goto done;
1130 }
1131
1132 hr = IStorage_Commit( dst, 0 );
1133 if (FAILED( hr ))
1134 ERR( "failed to commit storage (%#lx)\n", hr );
1135 else
1136 r = ERROR_SUCCESS;
1137
1138done:
1139 if (src) IStorage_Release( src );
1140 if (dst) IStorage_Release( dst );
1141 return r;
1142}
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

◆ msi_custom_action_cs

◆ msi_custom_action_cs_debug

CRITICAL_SECTION_DEBUG msi_custom_action_cs_debug
static
Initial value:
=
{
0, 0, { (DWORD_PTR)(__FILE__ ": msi_custom_action_cs") }
}
static CRITICAL_SECTION_DEBUG msi_custom_action_cs_debug
Definition: custom.c:64
LIST_ENTRY ProcessLocksList
Definition: winbase.h:883
#define DWORD_PTR
Definition: treelist.c:76

Definition at line 64 of file custom.c.

◆ msi_pending_custom_actions

struct list msi_pending_custom_actions = LIST_INIT( msi_pending_custom_actions )
static