- Don't print out cryptic message if IDispatch or IUnknown object is

just NULL.
- puArgErr is a ref pointer so we have to provide a dummy pointer if
  it is NULL.
- Fail gracefully and notify caller if we ran out of memoy or if
  variant copying failed.
This commit is contained in:
Robert Shearman 2005-06-12 10:42:36 +00:00 committed by Alexandre Julliard
parent 44246e47ec
commit 1a76541733
1 changed files with 48 additions and 31 deletions

View File

@ -210,6 +210,9 @@ static unsigned wire_extra(unsigned long *pFlags, VARIANT *pvar)
/* find the buffer size of the marshalled dispatch interface */ /* find the buffer size of the marshalled dispatch interface */
hr = CoGetMarshalSizeMax(&size, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL); hr = CoGetMarshalSizeMax(&size, &IID_IDispatch, (IUnknown*)V_DISPATCH(pvar), LOWORD(*pFlags), NULL, MSHLFLAGS_NORMAL);
if (FAILED(hr)) { if (FAILED(hr)) {
if (!V_DISPATCH(pvar))
WARN("NULL dispatch pointer\n");
else
ERR("Dispatch variant buffer size calculation failed, HRESULT=0x%lx\n", hr); ERR("Dispatch variant buffer size calculation failed, HRESULT=0x%lx\n", hr);
return 0; return 0;
} }
@ -515,6 +518,7 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy(
UINT* rgVarRefIdx = NULL; UINT* rgVarRefIdx = NULL;
VARIANTARG* rgVarRef = NULL; VARIANTARG* rgVarRef = NULL;
UINT u, cVarRef; UINT u, cVarRef;
UINT uArgErr;
TRACE("(%p)->(%ld,%s,%lx,%x,%p,%p,%p,%p)\n", This, TRACE("(%p)->(%ld,%s,%lx,%x,%p,%p,%p,%p)\n", This,
dispIdMember, debugstr_guid(riid), dispIdMember, debugstr_guid(riid),
@ -523,6 +527,7 @@ HRESULT CALLBACK IDispatch_Invoke_Proxy(
/* [out] args can't be null, use dummy vars if needed */ /* [out] args can't be null, use dummy vars if needed */
if (!pVarResult) pVarResult = &VarResult; if (!pVarResult) pVarResult = &VarResult;
if (!puArgErr) puArgErr = &uArgErr;
/* count by-ref args */ /* count by-ref args */
for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) { for (cVarRef=0,u=0; u<pDispParams->cArgs; u++) {
@ -590,26 +595,36 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
UINT* rgVarRefIdx, UINT* rgVarRefIdx,
VARIANTARG* rgVarRef) VARIANTARG* rgVarRef)
{ {
HRESULT hr; HRESULT hr = S_OK;
VARIANTARG *rgvarg, *arg; VARIANTARG *rgvarg, *arg;
UINT u; UINT u;
/* let the real Invoke operate on a copy of the in parameters,
* so we don't risk losing pointers to allocated memory */
rgvarg = pDispParams->rgvarg;
arg = CoTaskMemAlloc(sizeof(VARIANTARG)*pDispParams->cArgs);
for (u=0; u<pDispParams->cArgs; u++) {
VariantInit(&arg[u]);
VariantCopy(&arg[u], &rgvarg[u]);
}
pDispParams->rgvarg = arg;
/* initialize out parameters, so that they can be marshalled /* initialize out parameters, so that they can be marshalled
* in case the real Invoke doesn't initialize them */ * in case the real Invoke doesn't initialize them */
VariantInit(pVarResult); VariantInit(pVarResult);
memset(pExcepInfo, 0, sizeof(*pExcepInfo)); memset(pExcepInfo, 0, sizeof(*pExcepInfo));
*pArgErr = 0; *pArgErr = 0;
/* let the real Invoke operate on a copy of the in parameters,
* so we don't risk losing pointers to allocated memory */
rgvarg = pDispParams->rgvarg;
arg = CoTaskMemAlloc(sizeof(VARIANTARG)*pDispParams->cArgs);
if (!arg) return E_OUTOFMEMORY;
/* init all args so we can call VariantClear on all the args if the copy
* below fails */
for (u = 0; u < pDispParams->cArgs; u++)
VariantInit(&arg[u]);
for (u = 0; u < pDispParams->cArgs; u++) {
hr = VariantCopy(&arg[u], &rgvarg[u]);
if (FAILED(hr))
break;
}
if (SUCCEEDED(hr)) {
pDispParams->rgvarg = arg;
hr = IDispatch_Invoke(This, hr = IDispatch_Invoke(This,
dispIdMember, dispIdMember,
riid, riid,
@ -629,10 +644,12 @@ HRESULT __RPC_STUB IDispatch_Invoke_Stub(
if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i])) if (V_BYREF(&rgVarRef[u]) == V_BYREF(&rgvarg[i]))
VariantClear(&rgvarg[i]); VariantClear(&rgvarg[i]);
} }
/* clear the duplicate argument list */
for (u=0; u<pDispParams->cArgs; u++) {
VariantClear(&arg[u]);
} }
/* clear the duplicate argument list */
for (u=0; u<pDispParams->cArgs; u++)
VariantClear(&arg[u]);
pDispParams->rgvarg = rgvarg; pDispParams->rgvarg = rgvarg;
CoTaskMemFree(arg); CoTaskMemFree(arg);