// @pymethod int|PyIActiveScriptSite|OnScriptTerminate| PyObject *PyIActiveScriptSite::OnScriptTerminate(PyObject *self, PyObject *args) { PY_INTERFACE_METHOD; PyObject *obResult, *obException; if (!PyArg_ParseTuple(args, "OO:OnScriptTerminate", &obResult, &obException)) return NULL; IActiveScriptSite *pMySite = GetI(self); if (pMySite==NULL) return NULL; VARIANT varResult; VARIANT *pVarResult = NULL; if (obResult!=Py_None) { pVarResult = &varResult; VariantInit(&varResult); if (!PyCom_VariantFromPyObject(obResult, pVarResult)) return NULL; } EXCEPINFO excep; EXCEPINFO *pExcep = NULL; if (obException!=Py_None) { pExcep = &excep; memset(pExcep, 0, sizeof(EXCEPINFO)); if (!PyCom_ExcepInfoFromPyObject(obException, pExcep)) return NULL; } PY_INTERFACE_PRECALL; SCODE sc = pMySite->OnScriptTerminate(pVarResult, pExcep); PY_INTERFACE_POSTCALL; if (pVarResult) VariantClear(pVarResult); if (FAILED(sc)) return SetPythonCOMError(self, sc); return PyInt_FromLong(sc); }
// @pymethod |PyIPropertyBag|Write|Called by the control to write each property in turn to the storage provided by the container. PyObject *PyIPropertyBag::Write(PyObject *self, PyObject *args) { PyObject *obName; PyObject *obValue; // @pyparm str|propName||Name of the property to read. // @pyparm object|value||The value for the property. The value must be able to be converted to a COM VARIANT. if ( !PyArg_ParseTuple(args, "OO:Write", &obName, &obValue) ) return NULL; IPropertyBag *pIPB = GetI(self); if ( pIPB == NULL ) return NULL; TmpWCHAR Name; if ( !PyWinObject_AsWCHAR(obName, &Name)) return NULL; VARIANT var; if ( !PyCom_VariantFromPyObject(obValue, &var) ) return NULL; PY_INTERFACE_PRECALL; HRESULT hr = pIPB->Write(Name, &var); VariantClear(&var); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIPB, IID_IPropertyBag); Py_INCREF(Py_None); return Py_None; }
// @pymethod |PyIADs|Put|Description of Put. PyObject *PyIADs::Put(PyObject *self, PyObject *args) { IADs *pIAD = GetI(self); if ( pIAD == NULL ) return NULL; // @pyparm <o PyUnicode>|property||The property name to set // @pyparm object|val||The value to set. PyObject *obbstrName; PyObject *obvProp; BSTR bstrName; VARIANT vProp; VariantInit(&vProp); if ( !PyArg_ParseTuple(args, "OO:Put", &obbstrName, &obvProp) ) return NULL; BOOL bPythonIsHappy = TRUE; if (bPythonIsHappy && !PyWinObject_AsBstr(obbstrName, &bstrName)) bPythonIsHappy = FALSE; if ( !PyCom_VariantFromPyObject(obvProp, &vProp) ) bPythonIsHappy = FALSE; if (!bPythonIsHappy) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIAD->Put( bstrName, vProp ); SysFreeString(bstrName); VariantClear(&vProp); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIAD, IID_IADs ); Py_INCREF(Py_None); return Py_None; }
BOOL PyObject_AsVARDESC(PyObject *ob, VARDESC *v, void *pMore) { if (ob->ob_type != &PyVARDESC::Type) { PyErr_SetString(PyExc_TypeError, "Object is not a VARDESC."); return FALSE; } PyVARDESC *pyv = (PyVARDESC *)ob; v->memid = pyv->memid; v->wVarFlags = pyv->wVarFlags; v->varkind = (VARKIND)pyv->varkind; if (!PyObject_AsELEMDESC(pyv->elemdescVar, &v->elemdescVar, pMore)) return FALSE; if (v->varkind == VAR_PERINSTANCE) { if (!PyInt_Check(pyv->value)) { PyErr_SetString(PyExc_TypeError, "If varkind==VAR_PERINSTANCE, value attribute must be an integer"); return FALSE; } v->oInst = PyInt_AsLong(pyv->value); } else if (v->varkind == VAR_CONST) { VARIANT *pVar = (VARIANT *)AllocMore(pMore, sizeof(VARIANT), TRUE); if (pVar==NULL) return NULL; VariantInit(pVar); if (!PyCom_VariantFromPyObject(pyv->value, pVar)) return NULL; v->lpvarValue = pVar; } else if (v->varkind == VAR_DISPATCH) { // nothing to do - memid is all that is needed by the caller. ; } else { PyCom_LoggerWarning(NULL, "PyObject_AsVARDESC has unknown varkind (%d) - None will be used", v->varkind); } // else ignore value. return TRUE; }
STDMETHODIMP PyGEnumVARIANT::Next( /* [in] */ ULONG celt, /* [length_is][size_is][out] */ VARIANT __RPC_FAR *rgVar, /* [out] */ ULONG __RPC_FAR *pCeltFetched) { PY_GATEWAY_METHOD; PyObject *result; HRESULT hr = InvokeViaPolicy("Next", &result, "i", celt); if ( FAILED(hr) ) return hr; if ( !PySequence_Check(result) ) goto error; int len; len = PyObject_Length(result); if ( len == -1 ) goto error; if ( len > (int)celt) len = celt; if ( pCeltFetched ) *pCeltFetched = len; int i; for ( i = 0; i < len; ++i ) { PyObject *ob = PySequence_GetItem(result, i); if ( ob == NULL ) goto error; if ( !PyCom_VariantFromPyObject(ob, &rgVar[i]) ) { Py_DECREF(ob); Py_DECREF(result); return PyCom_SetCOMErrorFromPyException(IID_IEnumVARIANT); } Py_DECREF(ob); } Py_DECREF(result); return len < (int)celt ? S_FALSE : S_OK; error: PyErr_Clear(); // just in case PyCom_LogF("PyGEnumVariant::Next got a bad return value"); Py_DECREF(result); return PyCom_SetCOMErrorFromSimple(E_FAIL, IID_IEnumVARIANT, "Next() did not return a sequence of objects"); }
// @pymethod |PyIOleCommandTarget|Exec|Description of Exec. PyObject *PyIOleCommandTarget::Exec(PyObject *self, PyObject *args) { PyObject *ret; int cmdid, cmdopt; PyObject *obVar; PyObject *obGUID; VARIANT varIn, varOut; IOleCommandTarget *pIOCT = GetI(self); if ( pIOCT == NULL ) return NULL; if (!PyArg_ParseTuple(args, "OiiO", &obGUID, &cmdid, &cmdopt, &obVar)) return NULL; GUID guid; GUID *pguid; if (obGUID == Py_None) { pguid = NULL; } else { if (!PyWinObject_AsIID(obGUID, &guid)) return FALSE; pguid = &guid; } VariantInit(&varIn); VariantInit(&varOut); if (!PyCom_VariantFromPyObject(obVar, &varIn)) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIOCT->Exec( pguid, cmdid, cmdopt, &varIn, &varOut); PY_INTERFACE_POSTCALL; VariantClear(&varIn); if ( FAILED(hr) ) { PyCom_BuildPyException(hr, pIOCT, IID_IOleCommandTarget ); ret = NULL; } else { ret = PyCom_PyObjectFromVariant(&varOut); } VariantClear(&varOut); return ret; }
STDMETHODIMP PyGPropertyBag::Read( /* [in] */ LPCOLESTR pszPropName, /* [out][in] */ VARIANT __RPC_FAR *pVar, /* [in] */ IErrorLog __RPC_FAR *pErrorLog) { if ( pszPropName == NULL || pVar == NULL ) return E_POINTER; PY_GATEWAY_METHOD; PyObject *obLog; if ( pErrorLog ) { obLog = PyCom_PyObjectFromIUnknown(pErrorLog, IID_IErrorLog, TRUE); if ( !obLog ) return PyCom_SetCOMErrorFromPyException(GetIID()); } else { Py_INCREF(Py_None); obLog = Py_None; } PyObject *obName = PyWinObject_FromWCHAR(pszPropName); PyObject *result; HRESULT hr = InvokeViaPolicy("Read", &result, "OiO", obName, (int)V_VT(pVar), obLog); Py_DECREF(obLog); Py_XDECREF(obName); if (FAILED(hr)) return hr; if (!PyCom_VariantFromPyObject(result, pVar)) hr = PyCom_SetCOMErrorFromPyException(GetIID()); Py_DECREF(result); return hr; }
///////////////////////////////////////////////////////////////////////////// // // ELEMDESC support // ///////////////////////////////////////////////////////////////////////////// BOOL PyObject_AsELEMDESC( PyObject *ob, ELEMDESC *pDesc, void *pMore ) { // pMore must have come from AllocateMoreBlock() BOOL rc = FALSE; if (!PySequence_Check(ob) || PySequence_Length(ob)!=3) { PyErr_SetString(PyExc_TypeError, "The object is not an ELEMDESC"); return FALSE; } PyObject *obtd = PySequence_GetItem(ob, 0); PyObject *obParamFlags = PySequence_GetItem(ob, 1); PyObject *obDefaultVal = PySequence_GetItem(ob, 2); if (!PyInt_Check(obParamFlags)) { PyErr_SetString(PyExc_TypeError, "The second sequence item must be an integer"); goto done; } pDesc->paramdesc.wParamFlags = (WORD)PyInt_AsLong(obParamFlags); if (obDefaultVal != Py_None) { pDesc->paramdesc.wParamFlags |= PARAMFLAG_FHASDEFAULT; pDesc->paramdesc.pparamdescex = (LPPARAMDESCEX)AllocMore( pMore, sizeof(PARAMDESCEX), TRUE); pDesc->paramdesc.pparamdescex->cBytes = sizeof(PARAMDESCEX); /// XXX - this leaks this variant :-( // To avoid, we could maybe alloc a new More block with VARIANT set // to True, then memcpy this variant into it?? // Or have PyObject_FreeFUNCDESC() do the right thing, looking down // each elemdesc freeing the variant? // However, this is very very rarely used (possibly never in the real world!) VariantInit(&pDesc->paramdesc.pparamdescex->varDefaultValue); if (!PyCom_VariantFromPyObject(obDefaultVal, &pDesc->paramdesc.pparamdescex->varDefaultValue)) goto done; } rc = PyObject_AsTYPEDESC( obtd, &pDesc->tdesc, pMore ); done: Py_XDECREF(obtd); Py_XDECREF(obParamFlags); Py_XDECREF(obDefaultVal); return rc; }
STDMETHODIMP PyGOleCommandTarget::Exec( /* [unique][in] */ const GUID * pguidCmdGroup, /* [in] */ DWORD nCmdID, /* [in] */ DWORD nCmdexecopt, /* [unique][in] */ VARIANT * pvaIn, /* [unique][out][in] */ VARIANT * pvaOut) { PY_GATEWAY_METHOD; PyObject *obGUID; if (pguidCmdGroup == NULL) { obGUID = Py_None; Py_INCREF(obGUID); } else { obGUID = PyWinObject_FromIID(*pguidCmdGroup); } PyObject *obpvaIn = PyCom_PyObjectFromVariant(pvaIn); PyObject *result; HRESULT hr=InvokeViaPolicy("Exec", &result, "NllN", obGUID, nCmdID, nCmdexecopt, obpvaIn); if (FAILED(hr)) return hr; hr = pvaOut ? PyCom_VariantFromPyObject(result, pvaOut) : S_OK; Py_DECREF(result); return hr; }
int PyRecord::setattro(PyObject *self, PyObject *obname, PyObject *v) { VARIANT val; VariantInit(&val); PyRecord *pyrec = (PyRecord *)self; if (!PyCom_VariantFromPyObject(v, &val)) return -1; WCHAR *wname; if (!PyWinObject_AsWCHAR(obname, &wname, FALSE)) return -1; PY_INTERFACE_PRECALL; HRESULT hr = pyrec->pri->PutField(INVOKE_PROPERTYPUT, pyrec->pdata, wname, &val); PY_INTERFACE_POSTCALL; PyWinObject_FreeWCHAR(wname); VariantClear(&val); if (FAILED(hr)) { PyCom_BuildPyException(hr, pyrec->pri, IID_IRecordInfo); return -1; } return 0; }
PyObject * dataconv_WriteFromOutTuple(PyObject *self, PyObject *args) { PyObject *obArgTypes; PyObject *obArgType; PyObject *obRetValues; PyObject *obPtr; PyObject *obOutValue; VARTYPE vtArgType; BYTE *pbArgs; BYTE *pbArg; Py_ssize_t cArgs; UINT uiIndirectionLevel = 0; Py_ssize_t i; if (!PyArg_ParseTuple(args, "OOO:WriteFromOutTuple", &obRetValues, &obArgTypes, &obPtr)) return NULL; pbArgs = (BYTE *)PyLong_AsVoidPtr(obPtr); assert(pbArgs); if (!pbArgs) return NULL; // Nothing to do, oh darn. if (obRetValues == Py_None || obArgTypes == Py_None) { Py_INCREF(Py_None); return Py_None; } if (!PyTuple_Check(obArgTypes)) { PyErr_SetString(PyExc_TypeError, "OLE type description - expecting a tuple"); return NULL; } cArgs = PyTuple_Size(obArgTypes); if (!PyTuple_Check(obRetValues) && (UINT)PyTuple_Size(obRetValues) != cArgs) { PyErr_Format(PyExc_TypeError, "Expecting a tuple of length %d or None.", cArgs); return NULL; } for(i = 0 ; i < cArgs; i++) { obArgType = PyTuple_GET_ITEM(PyTuple_GET_ITEM(obArgTypes, i), 0); vtArgType = (VARTYPE)PyInt_AS_LONG(obArgType); // The following types aren't supported: // SAFEARRAY *: This requires support for SAFEARRAYs as a // Python extensions type so we can update the SAFEARRAY // in place. // VT_LPWSTR: This just hasn't been written yet. // VT_LPSTR: This just hasn't been written yet. // VT_LPWSTR | VT_BYREF: // VT_LPSTR | VT_BYREF: // These can't be supported since we don't know the correct // memory allocation policy. // Find the start of the argument. pbArg = pbArgs + PyInt_AS_LONG(PyTuple_GET_ITEM(PyTuple_GET_ITEM(obArgTypes, i), 1)); obOutValue = PyTuple_GET_ITEM(obRetValues, i); if (vtArgType & VT_ARRAY) { VARENUM rawVT = (VARENUM)(vtArgType & VT_TYPEMASK); if (vtArgType & VT_BYREF) { SAFEARRAY **ppsa = *(SAFEARRAY ***)pbArg; SAFEARRAY *psa; if (!VALID_BYREF_MISSING(obOutValue)) { if (!PyCom_SAFEARRAYFromPyObject(obOutValue, ppsa, rawVT)) { goto Error; } } else { SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 0; rgsabound[0].cElements = 1; psa = SafeArrayCreate(rawVT, 1, rgsabound); *ppsa = psa; } } else { // We can't convert this in place... Ack... PyErr_SetString( PyExc_TypeError, "Inplace SAFEARRAY mucking isn't allowed, doh!"); goto Error; SAFEARRAY *psa = *(SAFEARRAY **)pbArg; // Here we're updating an existing SafeArray. // so we need to handle it very carefully.... SafeArrayDestroy(psa); if (!PyCom_SAFEARRAYFromPyObject(obOutValue, &psa, rawVT)) return NULL; } } // All done with safe array handling. PyObject *obUse = NULL; switch (vtArgType) { case VT_VARIANT | VT_BYREF: { VARIANT *pvar = *(VARIANT **)pbArg; VariantClear(pvar); if (!VALID_BYREF_MISSING(obOutValue)) { PyCom_VariantFromPyObject(obOutValue, pvar); } else { V_VT(pvar) = VT_NULL; } break; } case VT_BSTR: { // This is the normal "BSTR" case, we can't // allocate a new BSTR we have to back patch the one // thats already there... BSTR bstr = *(BSTR *)pbArg; BSTR bstrT; UINT cch = SysStringLen(bstr); if ( PyString_Check(obOutValue) || PyUnicode_Check(obOutValue) ) { if ( !PyWinObject_AsBstr(obOutValue, &bstrT) ) { goto Error; } } else { // Use str(object) instead! obUse = PyObject_Str(obOutValue); if (obUse == NULL) { goto Error; } if ( !PyWinObject_AsBstr(obUse, &bstrT) ) { goto Error; } } if (SysStringLen(bstrT) > cch) { PyErr_Format( PyExc_ValueError, "Return value[%d] with type BSTR was " "longer than the input value: %d", i, cch); goto Error; } // Ok, now we know theres enough room in the source BSTR to // modify the sucker in place. wcscpy(bstr, bstrT); // Free the temp BSTR. SysFreeString(bstrT); break; } case VT_BSTR | VT_BYREF: { BSTR *pbstr = *(BSTR **)pbArg; BSTR bstrT = NULL; SysFreeString(*pbstr); *pbstr = NULL; if ( PyString_Check(obOutValue) || PyUnicode_Check(obOutValue) ) { if ( !PyWinObject_AsBstr(obOutValue, &bstrT) ) { goto Error; } } else { // Use str(object) instead! obUse = PyObject_Str(obOutValue); if (obUse == NULL) { goto Error; } if (!PyWinObject_AsBstr(obUse, &bstrT) ) { goto Error; } } *pbstr = bstrT; break; } case VT_ERROR | VT_BYREF: case VT_HRESULT | VT_BYREF: case VT_I4 | VT_BYREF: { INT *pi = *(INT **)pbArg; obUse = PyNumber_Int(obOutValue); if (obUse == NULL) { goto Error; } *pi = PyInt_AsLong(obUse); if (*pi == (UINT)-1 && PyErr_Occurred()) goto Error; break; } case VT_UI4 | VT_BYREF: { UINT *pui = *(UINT **)pbArg; // special care here as we could be > sys.maxint, // in which case we must work with longs. // Avoiding PyInt_AsUnsignedLongMask as it doesn't // exist in 2.2. if (PyLong_Check(obOutValue)) { *pui = PyLong_AsUnsignedLong(obOutValue); } else { // just do the generic "number" thing. obUse = PyNumber_Int(obOutValue); if (obUse == NULL) { goto Error; } *pui = (UINT)PyInt_AsLong(obUse); } if (*pui == (UINT)-1 && PyErr_Occurred()) goto Error; break; } case VT_I2 | VT_BYREF: { short *ps = *(short **)pbArg; obUse = PyNumber_Int(obOutValue); if (obUse == NULL) { goto Error; } *ps = (short)PyInt_AsLong(obUse); if (*ps == (UINT)-1 && PyErr_Occurred()) goto Error; break; } case VT_UI2 | VT_BYREF: { unsigned short *pus = *(unsigned short **)pbArg; obUse = PyNumber_Int(obOutValue); if (obUse == NULL) { goto Error; } *pus = (unsigned short)PyInt_AsLong(obUse); if (*pus == (UINT)-1 && PyErr_Occurred()) goto Error; break; } case VT_I1 | VT_BYREF: { signed char *pb = *(signed char **)pbArg; obUse = PyNumber_Int(obOutValue); if (obUse == NULL) { goto Error; } *pb = (signed char)PyInt_AsLong(obUse); if (*pb == (UINT)-1 && PyErr_Occurred()) goto Error; break; } case VT_UI1 | VT_BYREF: { BYTE *pb = *(BYTE **)pbArg; BYTE *pbOutBuffer = NULL; if (PyString_Check(obOutValue)) { pbOutBuffer = (BYTE *)PyString_AS_STRING(obOutValue); Py_ssize_t cb = PyString_GET_SIZE(obOutValue); memcpy(pb, pbOutBuffer, cb); } // keep this after string check since string can act as buffers else if (obOutValue->ob_type->tp_as_buffer) { DWORD cb; if (!PyWinObject_AsReadBuffer(obOutValue, (void **)&pbOutBuffer, &cb)) goto Error; memcpy(pb, pbOutBuffer, cb); } else { obUse = PyNumber_Int(obOutValue); if (obUse == NULL) { goto Error; } *pb = (BYTE)PyInt_AsLong(obUse); if (*pb == (UINT)-1 && PyErr_Occurred()) goto Error; } break; } case VT_BOOL | VT_BYREF: { VARIANT_BOOL *pbool = *(VARIANT_BOOL **)pbArg; obUse = PyNumber_Int(obOutValue); if (obUse == NULL) { goto Error; } *pbool = PyInt_AsLong(obUse) ? VARIANT_TRUE : VARIANT_FALSE; if (*pbool == (UINT)-1 && PyErr_Occurred()) goto Error; break; } case VT_R8 | VT_BYREF: { double *pdbl = *(double **)pbArg; obUse = PyNumber_Float(obOutValue); if (obUse == NULL) { goto Error; } *pdbl = PyFloat_AsDouble(obUse); break; } case VT_R4 | VT_BYREF: { float *pfloat = *(float **)pbArg; obUse = PyNumber_Float(obOutValue); if (obUse == NULL) { goto Error; } *pfloat = (float)PyFloat_AsDouble(obUse); break; } case VT_DISPATCH | VT_BYREF: { PyObject *obIID = PyTuple_GET_ITEM(PyTuple_GET_ITEM(obArgTypes, i), 3); IID iid = IID_IDispatch; if (obIID != NULL && obIID!=Py_None) PyWinObject_AsIID(obIID, &iid); IDispatch **pdisp = *(IDispatch ***)pbArg; if (!PyCom_InterfaceFromPyInstanceOrObject( obOutValue, iid, (void **)pdisp, TRUE)) { goto Error; } // COM Reference added by InterfaceFrom... break; } case VT_UNKNOWN | VT_BYREF: { PyObject *obIID = PyTuple_GET_ITEM(PyTuple_GET_ITEM(obArgTypes, i), 3); IID iid = IID_IUnknown; if (obIID != NULL && obIID!=Py_None) PyWinObject_AsIID(obIID, &iid); IUnknown **punk = *(IUnknown ***)pbArg; if (!PyCom_InterfaceFromPyInstanceOrObject( obOutValue, iid, (void **)punk, TRUE)) { goto Error; } // COM Reference added by InterfaceFrom... break; } case VT_DATE | VT_BYREF: { DATE *pdbl = *(DATE **)pbArg; if ( !PyWinObject_AsDATE(obOutValue, pdbl) ) { goto Error; } break; } case VT_CY | VT_BYREF: { CY *pcy = *(CY **)pbArg; if (!PyObject_AsCurrency(obOutValue, pcy)) goto Error; break; } case VT_I8 | VT_BYREF: { LARGE_INTEGER *pi64 = *(LARGE_INTEGER **)pbArg; if (!PyWinObject_AsLARGE_INTEGER(obOutValue, pi64)) { goto Error; } break; } case VT_UI8 | VT_BYREF: { ULARGE_INTEGER *pui64 = *(ULARGE_INTEGER **)pbArg; if (!PyWinObject_AsULARGE_INTEGER(obOutValue, pui64)) { goto Error; } break; } default: // could try default, but this error indicates we need to // beef up the VARIANT support, rather than default. PyErr_Format(PyExc_TypeError, "The VARIANT type is unknown (0x%x).", vtArgType); goto Error; } Py_XDECREF(obUse); } Py_INCREF(Py_None); return Py_None; Error: return NULL; }