VARIANT *pvarResult,
EXCEPINFO *pExcepInfo,
UINT *puArgErr);
-static HRESULT Send(WinSendCom* obj, VARIANT vCmd, VARIANT* pvResult);
+
+static STDMETHODIMP ISupportErrorInfo_QueryInterface(ISupportErrorInfo *This,
+ REFIID riid, void **ppvObject);
+static STDMETHODIMP_(ULONG) ISupportErrorInfo_AddRef(ISupportErrorInfo *This);
+static STDMETHODIMP_(ULONG) ISupportErrorInfo_Release(ISupportErrorInfo *This);
+static STDMETHODIMP ISupportErrorInfo_InterfaceSupportsErrorInfo(ISupportErrorInfo *This,
+ REFIID riid);
+
+static HRESULT Send(WinSendCom* obj, VARIANT vCmd, VARIANT* pvResult,
+ EXCEPINFO* pExcepInfo, UINT *puArgErr);
/* ----------------------------------------------------------------------
* COM Class Helpers
WinSendCom_GetIDsOfNames,
WinSendCom_Invoke,
};
+
+ static ISupportErrorInfoVtbl vtbl2 = {
+ ISupportErrorInfo_QueryInterface,
+ ISupportErrorInfo_AddRef,
+ ISupportErrorInfo_Release,
+ ISupportErrorInfo_InterfaceSupportsErrorInfo,
+ };
+
HRESULT hr = S_OK;
WinSendCom *obj = NULL;
hr = E_OUTOFMEMORY;
} else {
obj->lpVtbl = &vtbl;
+ obj->lpVtbl2 = &vtbl2;
obj->refcount = 0;
obj->interp = interp;
*ppvObject = (void**)this;
this->lpVtbl->AddRef(This);
hr = S_OK;
+ } else if (memcmp(riid, &IID_ISupportErrorInfo, sizeof(IID)) == 0) {
+ *ppvObject = (void**)(this + 1);
+ this->lpVtbl2->AddRef((ISupportErrorInfo*)(this + 1));
+ hr = S_OK;
}
return hr;
}
if (pDispParams->cArgs != 1)
hr = DISP_E_BADPARAMCOUNT;
else
- hr = Send(this, pDispParams->rgvarg[0], pvarResult);
+ hr = Send(this, pDispParams->rgvarg[0], pvarResult, pExcepInfo, puArgErr);
}
}
return hr;
}
+/* ---------------------------------------------------------------------- */
+
+/*
+ * WinSendCom ISupportErrorInfo methods
+ */
+
+static STDMETHODIMP
+ISupportErrorInfo_QueryInterface(ISupportErrorInfo *This,
+ REFIID riid, void **ppvObject)
+{
+ WinSendCom *this = (WinSendCom*)(This - 1);
+ return this->lpVtbl->QueryInterface((IDispatch*)this, riid, ppvObject);
+}
+
+static STDMETHODIMP_(ULONG)
+ISupportErrorInfo_AddRef(ISupportErrorInfo *This)
+{
+ WinSendCom *this = (WinSendCom*)(This - 1);
+ return InterlockedIncrement(&this->refcount);
+}
+
+static STDMETHODIMP_(ULONG)
+ISupportErrorInfo_Release(ISupportErrorInfo *This)
+{
+ WinSendCom *this = (WinSendCom*)(This - 1);
+ return this->lpVtbl->Release((IDispatch*)this);
+}
+
+static STDMETHODIMP
+ISupportErrorInfo_InterfaceSupportsErrorInfo(ISupportErrorInfo *This, REFIID riid)
+{
+ WinSendCom *this = (WinSendCom*)(This - 1);
+ return S_OK; /* or S_FALSE */
+}
+
+/* ---------------------------------------------------------------------- */
+
+
/* Description:
* Evaluates the string in the assigned interpreter. If the result
* is a valid address then set to the result returned by the evaluation.
*/
static HRESULT
-Send(WinSendCom* obj, VARIANT vCmd, VARIANT* pvResult)
+Send(WinSendCom* obj, VARIANT vCmd, VARIANT* pvResult, EXCEPINFO* pExcepInfo, UINT *puArgErr)
{
HRESULT hr = S_OK;
int r = TCL_OK;
pvResult->vt = VT_BSTR;
pvResult->bstrVal = SysAllocString(Tcl_GetUnicode(Tcl_GetObjResult(obj->interp)));
}
+ if (r == TCL_ERROR)
+ {
+ hr = DISP_E_EXCEPTION;
+ if (pExcepInfo)
+ {
+ Tcl_Obj *opError, *opErrorInfo, *opErrorCode;
+ ICreateErrorInfo *pCEI;
+ IErrorInfo *pEI;
+ HRESULT ehr;
+
+ opError = Tcl_GetObjResult(obj->interp);
+ opErrorInfo = Tcl_GetVar2Ex(obj->interp, "errorInfo", NULL, TCL_GLOBAL_ONLY);
+ opErrorCode = Tcl_GetVar2Ex(obj->interp, "errorCode", NULL, TCL_GLOBAL_ONLY);
+
+ Tcl_ListObjAppendElement(obj->interp, opErrorCode, opErrorInfo);
+
+ pExcepInfo->bstrDescription = SysAllocString(Tcl_GetUnicode(opError));
+ pExcepInfo->bstrSource = SysAllocString(Tcl_GetUnicode(opErrorCode));
+ pExcepInfo->scode = E_FAIL;
+
+ ehr = CreateErrorInfo(&pCEI);
+ if (SUCCEEDED(ehr))
+ {
+ ehr = pCEI->lpVtbl->SetGUID(pCEI, &IID_IDispatch);
+ ehr = pCEI->lpVtbl->SetDescription(pCEI, pExcepInfo->bstrDescription);
+ ehr = pCEI->lpVtbl->SetSource(pCEI, pExcepInfo->bstrSource);
+ ehr = pCEI->lpVtbl->QueryInterface(pCEI, &IID_IErrorInfo, (void**)&pEI);
+ if (SUCCEEDED(ehr))
+ {
+ SetErrorInfo(0, pEI);
+ pEI->lpVtbl->Release(pEI);
+ }
+ pCEI->lpVtbl->Release(pCEI);
+ }
+ }
+ }
}
VariantClear(&v);
}
DISPPARAMS dp;
EXCEPINFO ei;
UINT uiErr = 0;
- HRESULT hr = S_OK;
+ HRESULT hr = S_OK, ehr = S_OK;
Tcl_Obj *cmd = NULL;
cmd = Tcl_ConcatObj(objc - 3, &objv[3]);
dp.rgvarg = &vCmd;
hr = pdispInterp->lpVtbl->Invoke(pdispInterp, 1, &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dp, &vResult, &ei, &uiErr);
- if (SUCCEEDED(hr))
+ ehr = VariantChangeType(&vResult, &vResult, 0, VT_BSTR);
+ if (SUCCEEDED(ehr))
+ Tcl_SetObjResult(interp, Tcl_NewUnicodeObj(vResult.bstrVal, -1));
+ if (hr == DISP_E_EXCEPTION)
{
- hr = VariantChangeType(&vResult, &vResult, 0, VT_BSTR);
- if (SUCCEEDED(hr))
- Tcl_SetObjResult(interp, Tcl_NewUnicodeObj(vResult.bstrVal, -1));
+ Tcl_Obj *opError, *opErrorCode, *opErrorInfo;
+
+ if (ei.bstrSource != NULL)
+ {
+ int len;
+ char * szErrorInfo;
+
+ opError = Tcl_NewUnicodeObj(ei.bstrSource, -1);
+ Tcl_ListObjIndex(interp, opError, 0, &opErrorCode);
+ Tcl_SetObjErrorCode(interp, opErrorCode);
+
+ Tcl_ListObjIndex(interp, opError, 1, &opErrorInfo);
+ szErrorInfo = Tcl_GetStringFromObj(opErrorInfo, &len);
+ Tcl_AddObjErrorInfo(interp, szErrorInfo, len);
+ }
}
+
+ SysFreeString(ei.bstrDescription);
+ SysFreeString(ei.bstrSource);
+ SysFreeString(ei.bstrHelpFile);
VariantClear(&vCmd);
return (SUCCEEDED(hr) ? TCL_OK : TCL_ERROR);