22 #include "wine/port.h" 37 #include "msiserver.h" 39 #include "wine/unicode.h" 48 #define CUSTOM_ACTION_TYPE_MASK 0x3F 66 0, 0, { (
DWORD_PTR)(__FILE__
": msi_custom_action_cs") }
132 TRACE(
"Skipping action due to dbCustomActionTypeClientRepeat option.\n");
141 TRACE(
"Skipping action due to msidbCustomActionTypeFirstSequence option.\n");
149 TRACE(
"Skipping action due to msidbCustomActionTypeOncePerProcess option.\n");
170 '[',
'%',
's',
'<',
'=',
'>',
'%',
's',
'<',
'=',
'>',
'%',
's',
']',
'%',
's',0
187 static const WCHAR sep[] = {
'<',
'=',
'>',0};
188 const WCHAR *
end, *beg = deferred_data + 1;
209 UINT len =
sizeof(tmp)/
sizeof(tmp[0]);
234 'S',
'E',
'L',
'E',
'C',
'T',
' ',
'*',
' ',
'F',
'R',
'O',
'M',
' ',
235 '`',
'B',
'i' ,
'n',
'a',
'r',
'y',
'`',
' ',
'W',
'H',
'E',
'R',
'E',
' ',
236 '`',
'N',
'a',
'm',
'e',
'`',
' ',
'=',
' ',
'\'',
'%',
's',
'\'',0};
259 ERR(
"Failed to get stream\n");
263 }
while (sz ==
sizeof buffer);
320 TRACE(
"exit code is %u\n", rc);
345 ERR(
"Invalid Return Code %d\n",rc);
469 static const WCHAR MsiBreak[] = {
'M',
's',
'i',
'B',
'r',
'e',
'a',
'k',0 };
471 'W',
'i',
'n',
'd',
'o',
'w',
's',
' ',
'I',
'n',
's',
't',
'a',
'l',
'l',
'e',
'r',0
475 'T',
'o',
' ',
'd',
'e',
'b',
'u',
'g',
' ',
'y',
'o',
'u',
'r',
' ',
476 'c',
'u',
's',
't',
'o',
'm',
' ',
'a',
'c',
't',
'i',
'o',
'n',
',',
' ',
477 'a',
't',
't',
'a',
'c',
'h',
' ',
'y',
'o',
'u',
'r',
' ',
'd',
'e',
'b',
'u',
'g',
'g',
'e',
'r',
' ',
478 't',
'o',
' ',
'p',
'r',
'o',
'c',
'e',
's',
's',
' ',
'%',
'i',
' ',
'(',
'0',
'x',
'%',
'X',
')',
' ',
479 'a',
'n',
'd',
' ',
'p',
'r',
'e',
's',
's',
' ',
'O',
'K',0
510 ERR(
"failed to get IClassFactory interface\n");
514 r = IClassFactory_CreateInstance(
cf,
NULL, &IID_IWineMsiRemoteCustomAction, (
LPVOID *)&rca );
517 ERR(
"failed to get IWineMsiRemoteCustomAction interface\n");
522 IWineMsiRemoteCustomAction_Release( rca );
525 ERR(
"GetActionInfo failed\n");
536 __ASM_CFI(
".cfi_adjust_cfa_offset 4\n\t")
539 __ASM_CFI(
".cfi_def_cfa_register %ebp\n\t")
542 "movl 8(%ebp),%eax\n\t" 587 IWineMsiRemotePackage_SetMsiHandle( remote_package,
handle );
597 ERR(
"Custom action (%s:%s) caused a page fault: %08x\n",
606 ERR(
"failed to create handle for %p\n", remote_package );
613 IWineMsiRemotePackage_Release( remote_package );
647 info->package = package;
687 static const WCHAR dotexeW[] = {
'.',
'e',
'x',
'e',0};
750 return info.hProcess;
812 'S',
'E',
'L',
'E',
'C',
'T',
' ',
'`',
'M',
'e',
's',
's',
'a',
'g',
'e',
'`',
' ',
813 'F',
'R',
'O',
'M',
' ',
'`',
'E',
'r',
'r',
'o',
'r',
'`',
' ',
814 'W',
'H',
'E',
'R',
'E',
' ',
'`',
'E',
'r',
'r',
'o',
'r',
'`',
' ',
'=',
' ',
842 static const WCHAR msiexecW[] = {
'm',
's',
'i',
'e',
'x',
'e',
'c',0};
843 static const WCHAR paramsW[] = {
'/',
'q',
'b',
' ',
'/',
'i',
' '};
845 UINT len_src, len_dir, len_tgt,
len =
sizeof(paramsW)/
sizeof(paramsW[0]);
943 TRACE(
"script returned %u\n",
r);
947 ERR(
"failed to create handle for %p\n",
info->package );
979 info->package = package;
1017 'S',
'E',
'L',
'E',
'C',
'T',
' ',
'*',
' ',
'F',
'R',
'O',
'M',
' ',
1018 '`',
'B',
'i' ,
'n',
'a',
'r',
'y',
'`',
' ',
'W',
'H',
'E',
'R',
'E',
' ',
1019 '`',
'N',
'a',
'm',
'e',
'`',
' ',
'=',
' ',
'\'',
'%',
's',
'\'',0};
1173 TRACE(
"deferring commit action\n");
1178 TRACE(
"deferring rollback action\n");
1183 TRACE(
"deferring install action\n");
1197 'S',
'E',
'L',
'E',
'C',
'T',
' ',
'*',
' ',
'F',
'R',
'O',
'M',
' ',
1198 '`',
'C',
'u',
's',
't',
'o',
'm',
'A',
'c',
't',
'i',
'o',
'n',
'`',
' ',
'W',
'H',
'E',
'R',
'E',
' ',
1199 '`',
'A',
'c',
't',
'i' ,
'o',
'n',
'`',
' ',
'=',
' ',
'\'',
'%',
's',
'\'',0};
1227 FIXME(
"msidbCustomActionTypeTSAware not handled\n");
1232 WARN(
"msidbCustomActionTypeNoImpersonate not handled\n");
1254 else if (actiondata)
1344 unsigned int handle_count,
i;
1369 if (
info->package == package )
1378 for (
i = 0;
i < handle_count;
i++)
1409 IWineMsiRemoteCustomAction_AddRef( iface );
1472 *ppObj = &
This->IWineMsiRemoteCustomAction_iface;
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
void msiobj_addref(MSIOBJECTHDR *info)
static UINT HANDLE_CustomType17(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
static BOOL check_execution_scheduling_options(MSIPACKAGE *package, LPCWSTR action, UINT options)
UINT msi_get_property(MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD) DECLSPEC_HIDDEN
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
void ACTION_FinishCustomActions(const MSIPACKAGE *package)
static UINT CUSTOMPROC_wrapper(MsiCustomActionEntryPoint proc, MSIHANDLE handle)
static UINT HANDLE_CustomType18(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
#define CUSTOM_ACTION_TYPE_MASK
UINT WINAPI MsiCloseAllHandles(void)
static UINT custom_get_process_return(HANDLE process)
static void handle_msi_break(LPCWSTR target)
HRESULT create_msi_remote_package(IUnknown *pOuter, LPVOID *ppObj) DECLSPEC_HIDDEN
static const WCHAR szUserSID[]
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
#define ERROR_NO_MORE_ITEMS
UINT ACTION_ForceReboot(MSIPACKAGE *package)
static UINT HANDLE_CustomType53_54(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
static DWORD WINAPI DllThread(LPVOID arg)
static GLenum _GLUfuncptr fn
static WCHAR * strdupW(const WCHAR *src)
GLdouble GLdouble GLdouble r
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
struct list RunningActions
GLuint GLuint GLsizei count
BOOL msi_action_is_unique(const MSIPACKAGE *package, const WCHAR *action)
static LPSTR strdupWtoA(LPCWSTR str)
static ULONG WINAPI mcr_AddRef(IWineMsiRemoteCustomAction *iface)
#define INVALID_HANDLE_VALUE
DWORD WINAPI GetLastError(VOID)
#define INVALID_FILE_SIZE
static UINT HANDLE_CustomType1(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static void * msi_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
static UINT HANDLE_CustomType19(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
UINT(WINAPI * MsiCustomActionEntryPoint)(MSIHANDLE)
__WINE_SERVER_LIST_INLINE struct list * list_head(const struct list *list)
static MSIBINARY * get_temp_binary(MSIPACKAGE *package, LPCWSTR source, BOOL dll)
#define __ASM_GLOBAL_FUNC(name, code)
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
static DWORD ACTION_CallDllFunction(const GUID *guid)
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
#define ERROR_FUNCTION_FAILED
WINE_DEFAULT_DEBUG_CHANNEL(msi)
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
static UINT HANDLE_CustomType34(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
__WINE_SERVER_LIST_INLINE unsigned int list_count(const struct list *list)
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
static UINT wait_process_handle(MSIPACKAGE *package, UINT type, HANDLE ProcessHandle, LPCWSTR name)
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
struct _msi_custom_action_info msi_custom_action_info
void WINAPI DebugBreak(void)
unsigned char rollback_action_running
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)
#define ERROR_FUNCTION_NOT_CALLED
static HRESULT WINAPI mcr_QueryInterface(IWineMsiRemoteCustomAction *iface, REFIID riid, LPVOID *ppobj)
void msi_reset_folders(MSIPACKAGE *package, BOOL source) DECLSPEC_HIDDEN
static msi_custom_action_info * do_msidbCustomActionTypeDll(MSIPACKAGE *package, INT type, LPCWSTR source, LPCWSTR target, LPCWSTR action)
BSTR WINAPI SysAllocString(LPCOLESTR str)
static void addref_custom_action_data(msi_custom_action_info *info)
MSIHANDLE alloc_msi_remote_handle(IUnknown *unk)
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
static void set_deferred_action_props(MSIPACKAGE *package, const WCHAR *deferred_data)
DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function, LPCWSTR action) DECLSPEC_HIDDEN
static UINT HANDLE_CustomType50(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
DWORD WINAPI GetCurrentThreadId(VOID)
struct tagMSIRUNNINGACTION MSIRUNNINGACTION
#define ERROR_INSTALL_USEREXIT
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)
#define FILE_ATTRIBUTE_DIRECTORY
unsigned char commit_action_running
_Check_return_ _CRTIMP FILE *__cdecl tmpfile(void)
MSIFILE * msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *key)
static const WCHAR szEmpty[]
HRESULT create_msi_custom_remote(IUnknown *pOuter, LPVOID *ppObj)
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
static void file_running_action(MSIPACKAGE *package, HANDLE Handle, BOOL process, LPCWSTR name)
static const WCHAR szProductCode[]
LPWSTR * script_actions[SCRIPT_MAX]
UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolderPath)
int WINAPI MessageBoxW(_In_opt_ HWND, _In_opt_ LPCWSTR, _In_opt_ LPCWSTR, _In_ UINT)
MSIRECORD * MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR query,...) DECLSPEC_HIDDEN
#define ERROR_INSTALL_FAILURE
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
static CRITICAL_SECTION msi_custom_action_cs
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
const GLuint GLenum const GLvoid * binary
static const WCHAR szMsi[]
int msiobj_release(MSIOBJECTHDR *info)
static UINT HANDLE_CustomType2(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
static DWORD WINAPI ScriptThread(LPVOID arg)
HRESULT WINAPI CoCreateGuid(GUID *pguid)
static const WCHAR szSourceDir[]
#define FILE_ATTRIBUTE_NORMAL
static const IWineMsiRemoteCustomActionVtbl msi_custom_remote_vtbl
#define InterlockedDecrement
static UINT defer_custom_action(MSIPACKAGE *package, const WCHAR *action, UINT type)
static UINT HANDLE_CustomType5_6(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
#define INSTALLUILEVEL_MASK
#define memcpy(s1, s2, n)
#define GetCurrentProcess()
static LPWSTR msi_get_deferred_action(LPCWSTR action, LPCWSTR actiondata, LPCWSTR usersid, LPCWSTR prodcode)
LIST_ENTRY ProcessLocksList
unsigned char scheduled_action_running
static UINT HANDLE_CustomType23(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
static UINT get_action_info(const GUID *guid, INT *type, MSIHANDLE *handle, BSTR *dll, BSTR *funcname, IWineMsiRemotePackage **package)
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script)
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
WINE_UNICODE_INLINE WCHAR * strrchrW(const WCHAR *str, WCHAR ch)
const WCHAR * msi_get_target_folder(MSIPACKAGE *package, const WCHAR *name)
int MSI_RecordGetInteger(MSIRECORD *, UINT) DECLSPEC_HIDDEN
static UINT custom_get_thread_return(MSIPACKAGE *package, HANDLE thread)
static UINT wait_thread_handle(msi_custom_action_info *info)
#define ERROR_INSTALL_SUSPEND
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
static HANDLE execute_command(const WCHAR *app, WCHAR *arg, const WCHAR *dir)
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
#define InterlockedIncrement
int script_actions_count[SCRIPT_MAX]
static const WCHAR szTempFolder[]
static const WCHAR szOriginalDatabase[]
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
GLsizei GLsizei GLchar * source
static struct list msi_pending_custom_actions
IWineMsiRemoteCustomAction IWineMsiRemoteCustomAction_iface
static ULONG WINAPI mcr_Release(IWineMsiRemoteCustomAction *iface)
MSIHANDLE alloc_msihandle(MSIOBJECTHDR *obj)
#define ReadFile(a, b, c, d, e)
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
UINT msi_set_property(MSIDATABASE *, const WCHAR *, const WCHAR *, int) DECLSPEC_HIDDEN
static MSIBINARY * create_temp_binary(MSIPACKAGE *package, LPCWSTR source, BOOL dll)
static msi_custom_action_info * find_action_by_guid(const GUID *guid)
UINT MSI_RecordReadStream(MSIRECORD *, UINT, char *, LPDWORD) DECLSPEC_HIDDEN
static const WCHAR szCRoot[]
static BOOL msi_free(void *mem)
WCHAR * msi_create_temp_file(MSIDATABASE *db)
static BOOL action_type_matches_script(UINT type, UINT script)
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
static UINT HANDLE_CustomType21_22(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
#define GetProcAddress(x, y)
static UINT HANDLE_CustomType37_38(MSIPACKAGE *package, const WCHAR *source, const WCHAR *target, INT type, const WCHAR *action)
GLuint GLuint GLsizei GLenum type
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define GetExceptionCode()
struct _msi_custom_remote_impl msi_custom_remote_impl
static HRESULT WINAPI mcr_GetActionInfo(IWineMsiRemoteCustomAction *iface, LPCGUID custom_action_guid, INT *type, MSIHANDLE *handle, BSTR *dll, BSTR *func, IWineMsiRemotePackage **remote_package)
static void release_custom_action_data(msi_custom_action_info *info)
_In_ HANDLE ProcessHandle
#define GetEnvironmentVariableW(x, y, z)
const GUID IID_IClassFactory
#define IsEqualCLSID(rclsid1, rclsid2)
static msi_custom_remote_impl * impl_from_IWineMsiRemoteCustomAction(IWineMsiRemoteCustomAction *iface)
static WCHAR * strdupAtoW(const char *str)
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
static DWORD ACTION_CallScript(const GUID *guid)
#define __EXCEPT_PAGE_FAULT
static msi_custom_action_info * do_msidbCustomActionTypeScript(MSIPACKAGE *package, INT type, LPCWSTR script, LPCWSTR function, LPCWSTR action)
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
static const WCHAR szCustomActionData[]
DWORD WINAPI GetCurrentProcessId(VOID)
void msi_dialog_check_messages(HANDLE handle)
UINT msi_schedule_action(MSIPACKAGE *package, UINT script, const WCHAR *action)
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
static CRITICAL_SECTION_DEBUG msi_custom_action_cs_debug
UINT msi_register_unique_action(MSIPACKAGE *package, const WCHAR *action)
LPWSTR msi_dup_property(MSIDATABASE *db, LPCWSTR prop) DECLSPEC_HIDDEN