[Bug 45073] MSI custom-action server process crashes in remote_GetActionInfo while unmarshalling data (affects many MSI installers)

wine-bugs at winehq.org wine-bugs at winehq.org
Fri Apr 27 06:59:01 CDT 2018


https://bugs.winehq.org/show_bug.cgi?id=45073

--- Comment #2 from Anastasius Focht <focht at 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#l864

--- 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#l2114

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

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list