msi: Create the custom action thread inside msiexec.exe.
This patch is effectively a no-op by itself, but makes the next patch architecturally much simpler. We need the main thread to be non-blocking to allow nested custom actions to work, so creating the thread inside of msiexec allows the custom action thread to write the result of the action to the server pipe while the main thread simply reads from it. Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5c7cf0a47d
commit
7908d6ee39
|
@ -484,6 +484,29 @@ static void handle_msi_break(LPCSTR target)
|
||||||
static WCHAR ncalrpcW[] = {'n','c','a','l','r','p','c',0};
|
static WCHAR ncalrpcW[] = {'n','c','a','l','r','p','c',0};
|
||||||
static WCHAR endpoint_lrpcW[] = {'m','s','i',0};
|
static WCHAR endpoint_lrpcW[] = {'m','s','i',0};
|
||||||
|
|
||||||
|
#ifdef __i386__
|
||||||
|
/* wrapper for apps that don't declare the thread function correctly */
|
||||||
|
extern UINT custom_proc_wrapper( MsiCustomActionEntryPoint entry, MSIHANDLE hinst );
|
||||||
|
__ASM_GLOBAL_FUNC(custom_proc_wrapper,
|
||||||
|
"pushl %ebp\n\t"
|
||||||
|
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||||
|
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
|
||||||
|
"movl %esp,%ebp\n\t"
|
||||||
|
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
|
||||||
|
"subl $4,%esp\n\t"
|
||||||
|
"pushl 12(%ebp)\n\t"
|
||||||
|
"call *8(%ebp)\n\t"
|
||||||
|
"leave\n\t"
|
||||||
|
__ASM_CFI(".cfi_def_cfa %esp,4\n\t")
|
||||||
|
__ASM_CFI(".cfi_same_value %ebp\n\t")
|
||||||
|
"ret" )
|
||||||
|
#else
|
||||||
|
static UINT custom_proc_wrapper( MsiCustomActionEntryPoint entry, MSIHANDLE hinst )
|
||||||
|
{
|
||||||
|
return entry(hinst);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UINT CDECL __wine_msi_call_dll_function(const GUID *guid)
|
UINT CDECL __wine_msi_call_dll_function(const GUID *guid)
|
||||||
{
|
{
|
||||||
MsiCustomActionEntryPoint fn;
|
MsiCustomActionEntryPoint fn;
|
||||||
|
@ -494,7 +517,6 @@ UINT CDECL __wine_msi_call_dll_function(const GUID *guid)
|
||||||
LPWSTR dll = NULL;
|
LPWSTR dll = NULL;
|
||||||
LPSTR proc = NULL;
|
LPSTR proc = NULL;
|
||||||
HANDLE hModule;
|
HANDLE hModule;
|
||||||
HANDLE thread;
|
|
||||||
INT type;
|
INT type;
|
||||||
UINT r;
|
UINT r;
|
||||||
|
|
||||||
|
@ -514,9 +536,6 @@ UINT CDECL __wine_msi_call_dll_function(const GUID *guid)
|
||||||
}
|
}
|
||||||
RpcStringFreeW(&binding_str);
|
RpcStringFreeW(&binding_str);
|
||||||
|
|
||||||
/* We need this to unmarshal streams, and some apps expect it to be present. */
|
|
||||||
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
|
||||||
|
|
||||||
r = remote_GetActionInfo(guid, &type, &dll, &proc, &remote_package);
|
r = remote_GetActionInfo(guid, &type, &dll, &proc, &remote_package);
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
return r;
|
return r;
|
||||||
|
@ -539,9 +558,7 @@ UINT CDECL __wine_msi_call_dll_function(const GUID *guid)
|
||||||
|
|
||||||
__TRY
|
__TRY
|
||||||
{
|
{
|
||||||
thread = CreateThread(NULL, 0, (void *)fn, (void *)(ULONG_PTR) hPackage, 0, NULL);
|
r = custom_proc_wrapper(fn, hPackage);
|
||||||
WaitForSingleObject(thread, INFINITE);
|
|
||||||
GetExitCodeThread(thread, &r);
|
|
||||||
}
|
}
|
||||||
__EXCEPT_PAGE_FAULT
|
__EXCEPT_PAGE_FAULT
|
||||||
{
|
{
|
||||||
|
@ -565,8 +582,6 @@ UINT CDECL __wine_msi_call_dll_function(const GUID *guid)
|
||||||
midl_user_free(dll);
|
midl_user_free(dll);
|
||||||
midl_user_free(proc);
|
midl_user_free(proc);
|
||||||
|
|
||||||
CoUninitialize();
|
|
||||||
|
|
||||||
RpcBindingFree(&rpc_handle);
|
RpcBindingFree(&rpc_handle);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -395,11 +395,30 @@ static DWORD DoUnregServer(void)
|
||||||
|
|
||||||
extern UINT CDECL __wine_msi_call_dll_function(GUID *guid);
|
extern UINT CDECL __wine_msi_call_dll_function(GUID *guid);
|
||||||
|
|
||||||
|
static DWORD CALLBACK custom_action_thread(void *arg)
|
||||||
|
{
|
||||||
|
GUID *guid = arg;
|
||||||
|
return __wine_msi_call_dll_function(guid);
|
||||||
|
}
|
||||||
|
|
||||||
static int DoEmbedding(LPCWSTR key)
|
static int DoEmbedding(LPCWSTR key)
|
||||||
{
|
{
|
||||||
|
HANDLE thread;
|
||||||
GUID guid;
|
GUID guid;
|
||||||
|
UINT r;
|
||||||
|
|
||||||
|
/* We need this to unmarshal streams, and some apps expect it to be present. */
|
||||||
|
CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||||
|
|
||||||
CLSIDFromString(key, &guid);
|
CLSIDFromString(key, &guid);
|
||||||
return __wine_msi_call_dll_function(&guid);
|
thread = CreateThread(NULL, 0, custom_action_thread, &guid, 0, NULL);
|
||||||
|
WaitForSingleObject(thread, INFINITE);
|
||||||
|
GetExitCodeThread(thread, &r);
|
||||||
|
CloseHandle(thread);
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue