https://bugs.winehq.org/show_bug.cgi?id=45073
--- Comment #2 from Anastasius Focht focht@gmx.net --- Hello folks,
again .. holy moly :|
The culprit is another instance of "use of uninitialized data from stack" problem.
Relevant part of trace log:
--- snip --- ... 0073:Ret PE DLL (proc=0x474d04,module=0x470000 L"msi9e8b.tmp",reason=THREAD_ATTACH,res=(nil)) retval=1 0072:Call KERNEL32.InitializeCriticalSection(0018ca30) ret=7e4e33c3 0072:Ret KERNEL32.InitializeCriticalSection() retval=00000001 ret=7e4e33c3 0072:Call rpcrt4.NdrServerInitializeNew(0018c678,009cfab4,7ec53f20) ret=7ec11342 0072:trace:rpc:NdrServerInitializeNew (pRpcMsg == ^0x18c678, pStubMsg == ^0x9cfab4, pStubDesc == ^0x7ec53f20) 0073:Starting thread proc 0x7bca2c9d (arg=0x18c960) 0072:Ret rpcrt4.NdrServerInitializeNew() retval=00000000 ret=7ec11342 0072:Call rpcrt4.NdrSimpleStructUnmarshall(009cfab4,009cfb94,7ec53d06,00000000) ret=7ec1148f 0072:trace:ole:NdrSimpleStructUnmarshall (0x9cfab4,0x9cfb94,0x7ec53d06,0) 0072:trace:ole:NdrSimpleStructUnmarshall copying 0x18c770 to 0x18c770 0072:Ret rpcrt4.NdrSimpleStructUnmarshall() retval=00000000 ret=7ec1148f 0072:Call ntdll.RtlAllocateHeap(00110000,00000008,00000c00) ret=7ebc473f 0072:Ret ntdll.RtlAllocateHeap() retval=0018d6a0 ret=7ebc473f 0072:trace:msi:alloc_msihandle 0x1756f8 -> 1 0072:Call ntdll.RtlAllocateHeap(00110000,00000000,00000040) ret=7eba9ca3 0072:Ret ntdll.RtlAllocateHeap() retval=0018ca88 ret=7eba9ca3 0072:Call KERNEL32.WideCharToMultiByte(00000000,00000000,001b6028 L"SkipInstall",ffffffff,00000000,00000000,00000000,00000000) ret=7eba9d4b 0072:Ret KERNEL32.WideCharToMultiByte() retval=0000000c ret=7eba9d4b 0072:Call ntdll.RtlAllocateHeap(00110000,00000000,0000000c) ret=7eba9ca3 0072:Ret ntdll.RtlAllocateHeap() retval=0018e2a8 ret=7eba9ca3 0072:Call KERNEL32.WideCharToMultiByte(00000000,00000000,001b6028 L"SkipInstall",ffffffff,0018e2a8,0000000c,00000000,00000000) ret=7eba9d7e 0072:Ret KERNEL32.WideCharToMultiByte() retval=0000000c ret=7eba9d7e 0072:Call rpcrt4.NdrPointerBufferSize(009cfab4,009cfba0,7ec53d1a) ret=7ec115cb 0072:trace:ole:NdrPointerBufferSize (0x9cfab4,0x9cfba0,0x7ec53d1a) 0072:trace:ole:PointerBufferSize (0x9cfab4,0x9cfba0,0x7ec53d1a) 0072:trace:ole:PointerBufferSize type=0x11, attr= RPC_FC_P_ONSTACK RPC_FC_P_DEREF 0072:trace:ole:PointerBufferSize deref => 0x18ca88 0072:trace:ole:NdrPointerBufferSize (0x9cfab4,0x18ca88,0x7ec53d1e) 0072:trace:ole:PointerBufferSize (0x9cfab4,0x18ca88,0x7ec53d1e) 0072:trace:ole:PointerBufferSize type=0x12, attr= RPC_FC_P_SIMPLEPOINTER 0072:trace:ole:NdrConformantStringBufferSize (pStubMsg == ^0x9cfab4, pMemory == ^0x18ca88, pFormat == ^0x7ec53d20) 0072:trace:ole:array_compute_and_size_conformance string=L"C:\users\focht\Temp\msi9e8b.tmp" 0072:Ret rpcrt4.NdrPointerBufferSize() retval=009cfab4 ret=7ec115cb 0072:Call rpcrt4.NdrPointerBufferSize(009cfab4,009cfba8,7ec53d22) ret=7ec115ef 0072:trace:ole:NdrPointerBufferSize (0x9cfab4,0x9cfba8,0x7ec53d22) 0072:trace:ole:PointerBufferSize (0x9cfab4,0x9cfba8,0x7ec53d22) 0072:trace:ole:PointerBufferSize type=0x11, attr= RPC_FC_P_ONSTACK RPC_FC_P_DEREF 0072:trace:ole:PointerBufferSize deref => 0x18e2a8 0072:trace:ole:NdrPointerBufferSize (0x9cfab4,0x18e2a8,0x7ec53d26) 0072:trace:ole:PointerBufferSize (0x9cfab4,0x18e2a8,0x7ec53d26) 0072:trace:ole:PointerBufferSize type=0x12, attr= RPC_FC_P_SIMPLEPOINTER 0072:trace:ole:NdrConformantStringBufferSize (pStubMsg == ^0x9cfab4, pMemory == ^0x18e2a8, pFormat == ^0x7ec53d28) 0072:trace:ole:array_compute_and_size_conformance string="SkipInstall" 0072:Ret rpcrt4.NdrPointerBufferSize() retval=009cfab4 ret=7ec115ef 0072:Call rpcrt4.I_RpcGetBuffer(0018c678) ret=7ec11610 0072:trace:rpc:I_RpcGetBuffer (0x18c678): BufferLength=132 0072:Call ntdll.RtlAllocateHeap(00110000,00000000,00000084) ret=7e4e25ee 0072:Ret ntdll.RtlAllocateHeap() retval=0018e2c0 ret=7e4e25ee 0072:trace:rpc:I_RpcGetBuffer Buffer=0x18e2c0 0072:Ret rpcrt4.I_RpcGetBuffer() retval=00000000 ret=7ec11610 0072:Call rpcrt4.NdrPointerMarshall(009cfab4,009cfba0,7ec53d1a) ret=7ec116d8 0072:trace:ole:NdrPointerMarshall (0x9cfab4,0x9cfba0,0x7ec53d1a) 0072:trace:ole:PointerMarshall (0x9cfab4,0x18e2c4,0x9cfba0,0x7ec53d1a) 0072:trace:ole:PointerMarshall type=0x11, attr= RPC_FC_P_ONSTACK RPC_FC_P_DEREF 0072:trace:ole:PointerMarshall calling marshaller for type 0x12 0072:trace:ole:PointerMarshall deref => 0x18ca88 0072:trace:ole:NdrPointerMarshall (0x9cfab4,0x18ca88,0x7ec53d1e) 0072:trace:ole:PointerMarshall (0x9cfab4,0x18e2c4,0x18ca88,0x7ec53d1e) 0072:trace:ole:PointerMarshall type=0x12, attr= RPC_FC_P_SIMPLEPOINTER 0072:trace:ole:PointerMarshall writing 0x00020000 to buffer 0072:trace:ole:PointerMarshall calling marshaller for type 0x25 0072:trace:ole:NdrConformantStringMarshall (pStubMsg == ^0x9cfab4, pszMessage == ^0x18ca88, pFormat == ^0x7ec53d20) 0072:trace:ole:array_compute_and_write_conformance string=L"C:\users\focht\Temp\msi9e8b.tmp" 0072:trace:ole:PointerMarshall buffer=84/132 0072:trace:ole:PointerMarshall buffer=84/132 0072:Ret rpcrt4.NdrPointerMarshall() retval=00000000 ret=7ec116d8 0072:Call rpcrt4.NdrPointerMarshall(009cfab4,009cfba8,7ec53d22) ret=7ec116fc 0072:trace:ole:NdrPointerMarshall (0x9cfab4,0x9cfba8,0x7ec53d22) 0072:trace:ole:PointerMarshall (0x9cfab4,0x18e314,0x9cfba8,0x7ec53d22) 0072:trace:ole:PointerMarshall type=0x11, attr= RPC_FC_P_ONSTACK RPC_FC_P_DEREF 0072:trace:ole:PointerMarshall calling marshaller for type 0x12 0072:trace:ole:PointerMarshall deref => 0x18e2a8 0072:trace:ole:NdrPointerMarshall (0x9cfab4,0x18e2a8,0x7ec53d26) 0072:trace:ole:PointerMarshall (0x9cfab4,0x18e314,0x18e2a8,0x7ec53d26) 0072:trace:ole:PointerMarshall type=0x12, attr= RPC_FC_P_SIMPLEPOINTER 0072:trace:ole:PointerMarshall writing 0x00020004 to buffer 0072:trace:ole:PointerMarshall calling marshaller for type 0x22 0072:trace:ole:NdrConformantStringMarshall (pStubMsg == ^0x9cfab4, pszMessage == ^0x18e2a8, pFormat == ^0x7ec53d28) 0072:trace:ole:array_compute_and_write_conformance string="SkipInstall" 0072:trace:ole:PointerMarshall buffer=112/132 0072:trace:ole:PointerMarshall buffer=112/132 0072:Ret rpcrt4.NdrPointerMarshall() retval=00000000 ret=7ec116fc 0072:Call rpcrt4.NdrPointerFree(009cfab4,009cfba0,7ec53d1a) ret=7ec112db 0072:trace:ole:NdrPointerFree (0x9cfab4,0x9cfba0,0x7ec53d1a) 0072:trace:ole:PointerFree (0x9cfab4,0x9cfba0,0x7ec53d1a) 0072:trace:ole:PointerFree type=0x11, attr= RPC_FC_P_ONSTACK RPC_FC_P_DEREF 0072:trace:ole:PointerFree deref => 0x18ca88 0072:trace:ole:NdrPointerFree (0x9cfab4,0x18ca88,0x7ec53d1e) 0072:trace:ole:PointerFree (0x9cfab4,0x18ca88,0x7ec53d1e) 0072:trace:ole:PointerFree type=0x12, attr= RPC_FC_P_SIMPLEPOINTER 0072:trace:ole:PointerFree freeing 0x18ca88 0072:trace:ole:NdrFree (0x9cfab4, 0x18ca88) 0072:Call ntdll.RtlFreeHeap(00110000,00000000,0018ca88) ret=7eba9e86 0072:Ret ntdll.RtlFreeHeap() retval=00000001 ret=7eba9e86 0072:trace:ole:PointerFree not freeing stack ptr 0x9cfba0 0072:Ret rpcrt4.NdrPointerFree() retval=0000003a ret=7ec112db 0072:Call rpcrt4.NdrPointerFree(009cfab4,009cfba8,7ec53d22) ret=7ec112ff 0072:trace:ole:NdrPointerFree (0x9cfab4,0x9cfba8,0x7ec53d22) 0072:trace:ole:PointerFree (0x9cfab4,0x9cfba8,0x7ec53d22) 0072:trace:ole:PointerFree type=0x11, attr= RPC_FC_P_ONSTACK RPC_FC_P_DEREF 0072:trace:ole:PointerFree deref => 0x18e2a8 0072:trace:ole:NdrPointerFree (0x9cfab4,0x18e2a8,0x7ec53d26) 0072:trace:ole:PointerFree (0x9cfab4,0x18e2a8,0x7ec53d26) 0072:trace:ole:PointerFree type=0x12, attr= RPC_FC_P_SIMPLEPOINTER 0072:trace:ole:PointerFree freeing 0x18e2a8 0072:trace:ole:NdrFree (0x9cfab4, 0x18e2a8) 0072:Call ntdll.RtlFreeHeap(00110000,00000000,0018e2a8) ret=7eba9e86 0072:Ret ntdll.RtlFreeHeap() retval=00000001 ret=7eba9e86 0072:trace:ole:PointerFree not freeing stack ptr 0x9cfba8 0072:Ret rpcrt4.NdrPointerFree() retval=0000003a ret=7ec112ff ... 0070:Ret KERNEL32.WaitForSingleObject() retval=00000000 ret=7e4d8ccc 0072:trace:rpc:process_request_packet freeing Buffer=0x18c770 ... --- snip ---
RPC client side (custom action server process):
--- snip --- 0070:trace:rpc:RPCRT4_ReceiveWithAuth buffer length = 120 ... 0070:Ret rpcrt4.NdrSendReceive() retval=00000000 ret=7ec09128 0070:Call rpcrt4.NdrPointerUnmarshall(0033f9c8,0033fad8,7ec5355a,00000000) ret=7ec091fa 0070:trace:ole:NdrPointerUnmarshall (0x33f9c8,0x33fad8,0x7ec5355a,0) 0070:trace:ole:PointerUnmarshall (0x33f9c8,0x15a6a4,0x33fad8,0x33fbb4,0x7ec5355a,0) 0070:trace:ole:PointerUnmarshall type=0x11, attr= RPC_FC_P_ONSTACK RPC_FC_P_DEREF 0070:trace:ole:PointerUnmarshall client 0070:trace:ole:PointerUnmarshall setting *pPointer to 0x33fbb4 0070:trace:ole:PointerUnmarshall deref => 0x33fbb4 0070:trace:ole:NdrPointerUnmarshall (0x33f9c8,0x33fbb4,0x7ec5355e,0) 0070:trace:ole:PointerUnmarshall (0x33f9c8,0x15a6a4,0x33fbb4,0x7bcf9890,0x7ec5355e,0) 0070:trace:ole:PointerUnmarshall type=0x12, attr= RPC_FC_P_SIMPLEPOINTER 0070:trace:ole:PointerUnmarshall pointer_id is 0x00020000 0070:trace:ole:PointerUnmarshall client 0070:trace:ole:PointerUnmarshall setting *pPointer to 0x7bcf9890 0070:trace:ole:NdrConformantStringUnmarshall (pStubMsg == ^0x33f9c8, *pMemory == ^0x7bcf9890, pFormat == ^0x7ec53560, fMustAlloc == 0) 0070:trace:ole:ReadConformance unmarshalled conformance is 32 0070:trace:ole:ReadVariance offset is 0 0070:trace:ole:ReadVariance variance is 32 0070:trace:ole:array_read_variance_and_unmarshall string=L"C:\users\focht\Temp\msi9e8b.tmp" 0070:trace:ole:PointerUnmarshall pointer=0x7bcf9890 0070:trace:ole:PointerUnmarshall pointer=0x33fbb4 0070:trace:ole:NdrPointerUnmarshall ((nil),0x33f9c8,0x33fc34,100) 0070:trace:seh:raise_exception code=c0000005 flags=0 addr=0x7e4ae367 ip=7e4ae367 tid=0070 0070:trace:seh:raise_exception info[0]=00000000 0070:trace:seh:raise_exception info[1]=00000004 0070:trace:seh:raise_exception eax=00000004 ebx=0033f8ac ecx=00000000 edx=7bd0c528 esi=0033f8d0 edi=0033fc34 0070:trace:seh:raise_exception ebp=0033f848 esp=0033f838 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010206 0070:trace:seh:call_stack_handlers calling handler at 0x7ec02f2b code=c0000005 flags=0 0070:trace:seh:call_stack_handlers handler at 0x7ec02f2b returned 1 0070:trace:seh:call_stack_handlers calling handler at 0x7b48fd25 code=c0000005 flags=0 wine: Unhandled page fault on read access to 0x00000004 at address 0x7e4ae367 (thread 0070), starting debugger... --- snip ---
Debugger (another session):
--- snip---
Wine-dbg>bt
Backtrace: =>0 0x7e4af004 safe_copy_from_buffer+0x6(pStubMsg=0x33fa08, p=0x35, size=0x40) [/home/focht/projects/wine/wine.repo/src/dlls/rpcrt4/ndr_marshall.c:721] in rpcrt4 (0x0033f5b8) 1 0x7e4b352f array_read_variance_and_unmarshall+0x4d9(fc='%', pStubMsg=0x33fa08, ppMemory=0x33fbe0, pFormat="%\
", fMustAlloc=0, fUseBufferMemoryServer=1, fUnmarshall=1) [/home/focht/projects/wine/wine.repo/src/dlls/rpcrt4/ndr_marshall.c:2234] in rpcrt4 (0x0033f648) 2 0x7e4b41f5 NdrConformantStringUnmarshall+0x130(pStubMsg=<couldn't compute location>, ppMemory=<couldn't compute location>, pFormat=<couldn't compute location>, fMustAlloc=0) [/home/focht/projects/wine/wine.repo/src/dlls/rpcrt4/ndr_marshall.c:2539] in rpcrt4 (0x0033f698) 3 0x7e4afe7f PointerUnmarshall+0x53e(pStubMsg=0x33fa08, Buffer="", pPointer=0x33fbe0, pSrcPointer=*** invalid address 0x35 ***, pFormat="%\
", fMustAlloc=0) [/home/focht/projects/wine/wine.repo/src/dlls/rpcrt4/ndr_marshall.c:969] in rpcrt4 (0x0033f768) 4 0x7e4b1644 NdrPointerUnmarshall+0x110(pStubMsg=<couldn't compute location>, ppMemory=<couldn't compute location>, pFormat=<couldn't compute location>, fMustAlloc=0) [/home/focht/projects/wine/wine.repo/src/dlls/rpcrt4/ndr_marshall.c:1569] in rpcrt4 (0x0033f7c8) 5 0x7e4afe7f PointerUnmarshall+0x53e(pStubMsg=0x33fa08, Buffer="", pPointer=0x33fb18, pSrcPointer="5", pFormat="", fMustAlloc=0) [/home/focht/projects/wine/wine.repo/src/dlls/rpcrt4/ndr_marshall.c:969] in rpcrt4 (0x0033f898) 6 0x7e4b1644 NdrPointerUnmarshall+0x110(pStubMsg=<couldn't compute location>, ppMemory=<couldn't compute location>, pFormat=<couldn't compute location>, fMustAlloc=0) [/home/focht/projects/wine/wine.repo/src/dlls/rpcrt4/ndr_marshall.c:1569] in rpcrt4 (0x0033f8f8) 7 0x7ec09176 remote_GetActionInfo+0x251(guid=<couldn't compute location>, type=<couldn't compute location>, dllname=<couldn't compute location>, hinst=<couldn't compute location>) [/home/focht/projects/wine/wine.repo/build-x86/dlls/msi/winemsi_c.c:2562] in msi (0x0033faf8) 8 0x7ebab034 __wine_msi_call_dll_function+0x15e(guid=0x33fc70) [/home/focht/projects/wine/wine.repo/src/dlls/msi/custom.c:541] in msi (0x0033fc58) 9 0x7efee3e8 DoEmbedding+0x23(key="{E02FF412-446F-435C-A816-BDD608244195}") [/home/focht/projects/wine/wine.repo/src/programs/msiexec/msiexec.c:402] in msiexec (0x0033fc88) 10 0x7efee9a4 WinMain+0x18f(hInstance=<couldn't compute location>, hPrevInstance=<couldn't compute location>, lpCmdLine=<couldn't compute location>, nCmdShow=<couldn't compute location>) [/home/focht/projects/wine/wine.repo/src/programs/msiexec/msiexec.c:599] in msiexec (0x0033fde8) 11 0x7eff059e main+0xeb(argc=<couldn't compute location>, argv=<couldn't compute location>) [/home/focht/projects/wine/wine.repo/src/dlls/winecrt0/exe_main.c:49] in msiexec (0x0033fe68) 12 0x7eff0496 __wine_spec_exe_entry+0x56(peb=<couldn't compute location>) [/home/focht/projects/wine/wine.repo/src/dlls/winecrt0/exe_entry.c:36] in msiexec (0x0033fea8) 13 0x7b46d930 call_process_entry+0xb() in kernel32 (0x0033fec8) 14 0x7b46da71 start_process+0x132(entry=<couldn't compute location>, peb=<couldn't compute location>) [/home/focht/projects/wine/wine.repo/src/dlls/kernel32/process.c:1099] in kernel32 (0x0033ffd8) 15 0x7b46d93e start_process_wrapper+0x9() in kernel32 (0x0033ffec)
Wine-dbg>n 721 if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
Wine-dbg>info locals 0x7e4af004 safe_copy_from_buffer+0x6: (0033f5b8) MIDL_STUB_MESSAGE* pStubMsg=0x33fa08 (parameter [EBP+8]) void* p=0x35 (parameter [EBP+12]) ULONG size=0x40 (parameter [EBP+16]) --- snip ---
"out" pointer(s) on stack, uninitialized values.
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/msi/custom.c#l492
--- snip --- 492 UINT __wine_msi_call_dll_function(const GUID *guid) 493 { 494 MsiCustomActionEntryPoint fn; 495 MSIHANDLE remote_package = 0; 496 RPC_WSTR binding_str; 497 MSIHANDLE hPackage; 498 RPC_STATUS status; 499 HANDLE hModule; 500 HANDLE thread; 501 LPWSTR dll; 502 LPSTR proc; 503 INT type; 504 UINT r; 505 506 TRACE("%s\n", debugstr_guid( guid )); 507 508 status = RpcStringBindingComposeW(NULL, ncalrpcW, NULL, endpoint_lrpcW, NULL, &binding_str); 509 if (status != RPC_S_OK) 510 { 511 ERR("RpcStringBindingCompose failed: %#x\n", status); 512 return status; 513 } 514 status = RpcBindingFromStringBindingW(binding_str, &rpc_handle); 515 if (status != RPC_S_OK) 516 { 517 ERR("RpcBindingFromStringBinding failed: %#x\n", status); 518 return status; 519 } 520 RpcStringFreeW(&binding_str); 521 522 /* We need this to unmarshal streams, and some apps expect it to be present. */ 523 CoInitializeEx(NULL, COINIT_MULTITHREADED); 524 525 r = remote_GetActionInfo(guid, &type, &dll, &proc, &remote_package); 526 if (r != ERROR_SUCCESS) 527 return r; --- snip ---
build-x86/dlls/msi/winemsi_c.c:
--- snip --- UINT __cdecl remote_GetActionInfo( const GUID *guid, int *type, LPWSTR *dllname, LPSTR *function, MSIHANDLE *hinst) { struct __frame_remote_GetActionInfo __f, * const __frame = &__f; UINT _RetVal; RPC_MESSAGE _RpcMessage; __frame->_Handle = 0;
RpcExceptionInit( 0, __finally_remote_GetActionInfo ); if (!guid) RpcRaiseException(RPC_X_NULL_REF_POINTER); if (!type) RpcRaiseException(RPC_X_NULL_REF_POINTER); if (!dllname) RpcRaiseException(RPC_X_NULL_REF_POINTER); if (!function) RpcRaiseException(RPC_X_NULL_REF_POINTER); if (!hinst) RpcRaiseException(RPC_X_NULL_REF_POINTER); RpcTryFinally { NdrClientInitializeNew(&_RpcMessage, &__frame->_StubMsg, &IWineMsiRemote_StubDesc, 30); __frame->_Handle = rpc_handle;
__frame->_StubMsg.BufferLength = 20; NdrGetBuffer(&__frame->_StubMsg, __frame->_StubMsg.BufferLength, __frame->_Handle);
NdrSimpleStructMarshall( &__frame->_StubMsg, (unsigned char *)guid, (PFORMAT_STRING)&__MIDL_TypeFormatString.Format[388]);
NdrSendReceive(&__frame->_StubMsg, __frame->_StubMsg.Buffer);
__frame->_StubMsg.BufferStart = _RpcMessage.Buffer; __frame->_StubMsg.BufferEnd = __frame->_StubMsg.BufferStart + _RpcMessage.BufferLength;
if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION) NdrConvert(&__frame->_StubMsg, (PFORMAT_STRING)&__MIDL_ProcFormatString.Format[318]);
__frame->_StubMsg.Buffer = (unsigned char *)(((ULONG_PTR)__frame->_StubMsg.Buffer + 3) & ~0x3); if (__frame->_StubMsg.Buffer + sizeof(int) > __frame->_StubMsg.BufferEnd) { RpcRaiseException(RPC_X_BAD_STUB_DATA); } *type = *(int *)__frame->_StubMsg.Buffer; __frame->_StubMsg.Buffer += sizeof(int);
NdrPointerUnmarshall( &__frame->_StubMsg, (unsigned char **)&dllname, (PFORMAT_STRING)&__MIDL_TypeFormatString.Format[408], 0); ... --- snip ----
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/rpcrt4/ndr_marshall.c...
--- snip --- 864 static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, 865 unsigned char *Buffer, 866 unsigned char **pPointer, 867 unsigned char *pSrcPointer, 868 PFORMAT_STRING pFormat, 869 unsigned char fMustAlloc) 870 { 871 unsigned type = pFormat[0], attr = pFormat[1]; 872 PFORMAT_STRING desc; 873 NDR_UNMARSHALL m; 874 DWORD pointer_id = 0; 875 BOOL pointer_needs_unmarshaling; ... 925 if (pointer_needs_unmarshaling) { 926 unsigned char **current_ptr = pPointer; 927 if (pStubMsg->IsClient) { 928 TRACE("client\n"); 929 /* if we aren't forcing allocation of memory then try to use the existing 930 * (source) pointer to unmarshall the data into so that [in,out] 931 * parameters behave correctly. it doesn't matter if the parameter is 932 * [out] only since in that case the pointer will be NULL. we force 933 * allocation when the source pointer is NULL here instead of in the type 934 * unmarshalling routine for the benefit of the deref code below */ 935 if (!fMustAlloc) { 936 if (pSrcPointer) { 937 TRACE("setting *pPointer to %p\n", pSrcPointer); 938 *pPointer = pSrcPointer; 939 } else 940 fMustAlloc = TRUE; 941 } 942 } else { 943 TRACE("server\n"); 944 /* the memory in a stub is never initialised, so we have to work out here 945 * whether we have to initialise it so we can use the optimisation of 946 * setting the pointer to the buffer, if possible, or set fMustAlloc to 947 * TRUE. */ 948 if (attr & RPC_FC_P_DEREF) { 949 fMustAlloc = TRUE; 950 } else { 951 *current_ptr = NULL; 952 } 953 } 954 955 if (attr & RPC_FC_P_ALLOCALLNODES) 956 FIXME("RPC_FC_P_ALLOCALLNODES not implemented\n"); 957 958 if (attr & RPC_FC_P_DEREF) { 959 if (fMustAlloc) { 960 unsigned char *base_ptr_val = NdrAllocate(pStubMsg, sizeof(void *)); 961 *pPointer = base_ptr_val; 962 current_ptr = (unsigned char **)base_ptr_val; 963 } else 964 current_ptr = *(unsigned char***)current_ptr; 965 TRACE("deref => %p\n", current_ptr); 966 if (!fMustAlloc && !*current_ptr) fMustAlloc = TRUE; 967 } --- snip ---
https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/rpcrt4/ndr_marshall.c...
--- snip ---
2114 static inline ULONG array_read_variance_and_unmarshall( 2115 unsigned char fc, PMIDL_STUB_MESSAGE pStubMsg, unsigned char **ppMemory, 2116 PFORMAT_STRING pFormat, unsigned char fMustAlloc, 2117 unsigned char fUseBufferMemoryServer, unsigned char fUnmarshall) 2118 { 2119 ULONG bufsize, memsize; 2120 WORD esize; 2121 unsigned char alignment; 2122 unsigned char *saved_buffer, *pMemory; 2123 ULONG i, offset, count; 2124 2125 switch (fc) 2126 { ... 2190 case RPC_FC_C_CSTRING: 2191 case RPC_FC_C_WSTRING: 2192 if (fc == RPC_FC_C_CSTRING) 2193 esize = 1; 2194 else 2195 esize = 2; 2196 2197 ReadVariance(pStubMsg, NULL, pStubMsg->MaxCount); 2198 2199 if (pFormat[1] != RPC_FC_STRING_SIZED && (pStubMsg->MaxCount != pStubMsg->ActualCount)) 2200 { 2201 ERR("buffer size %d must equal memory size %ld for non-sized conformant strings\n", 2202 pStubMsg->ActualCount, pStubMsg->MaxCount); 2203 RpcRaiseException(RPC_S_INVALID_BOUND); 2204 } 2205 if (pStubMsg->Offset) 2206 { 2207 ERR("conformant strings can't have Offset (%d)\n", pStubMsg->Offset); 2208 RpcRaiseException(RPC_S_INVALID_BOUND); 2209 } 2210 2211 memsize = safe_multiply(esize, pStubMsg->MaxCount); 2212 bufsize = safe_multiply(esize, pStubMsg->ActualCount); 2213 2214 validate_string_data(pStubMsg, bufsize, esize); 2215 2216 if (fUnmarshall) 2217 { 2218 if (fMustAlloc) 2219 *ppMemory = NdrAllocate(pStubMsg, memsize); 2220 else 2221 { 2222 if (fUseBufferMemoryServer && !pStubMsg->IsClient && 2223 !*ppMemory && (pStubMsg->MaxCount == pStubMsg->ActualCount)) 2224 /* if the data in the RPC buffer is big enough, we just point 2225 * straight into it */ 2226 *ppMemory = pStubMsg->Buffer; 2227 else if (!*ppMemory) 2228 *ppMemory = NdrAllocate(pStubMsg, memsize); 2229 } 2230 2231 if (*ppMemory == pStubMsg->Buffer) 2232 safe_buffer_increment(pStubMsg, bufsize); 2233 else 2234 safe_copy_from_buffer(pStubMsg, *ppMemory, bufsize); 2235 2236 if (*pFormat == RPC_FC_C_CSTRING) 2237 TRACE("string=%s\n", debugstr_a((char*)*ppMemory)); 2238 else 2239 TRACE("string=%s\n", debugstr_w((LPWSTR)*ppMemory)); 2240 } 2241 return bufsize; --- snip ---
If you initialize both "out" string pointers for 'remote_GetActionInfo()' in '_wine_msi_call_dll_function()' the installers work.
Regards