// Conversion for WPARAM and LPARAM // (WPARAM is defined as UINT_PTR, and LPARAM is defined as LONG_PTR - see // pywintypes.h for inline functions to resolve this) BOOL PyWinObject_AsPARAM(PyObject *ob, WPARAM *pparam) { assert(!PyErr_Occurred()); // lingering exception? if (ob==NULL || ob==Py_None){ *pparam=NULL; return TRUE; } // XXX - why this UNICODE block? Can't we just do both anyway? Maybe // just via the buffer interface? #ifdef UNICODE #define TCHAR_DESC "Unicode" if (PyUnicode_Check(ob)){ *pparam = (WPARAM)PyUnicode_AS_UNICODE(ob); return TRUE; } #else #define TCHAR_DESC "String" if (PyString_Check(ob)){ *pparam = (WPARAM)PyString_AS_STRING(ob); return TRUE; } #endif DWORD bufsize; if (PyWinObject_AsReadBuffer(ob, (VOID **)pparam, &bufsize)) return TRUE; PyErr_Clear(); if (PyWinLong_AsVoidPtr(ob, (void **)pparam)) return TRUE; PyErr_Format(PyExc_TypeError, "WPARAM must be a " TCHAR_DESC ", int, or buffer object (got %s)", ob->ob_type->tp_name); return FALSE; }
// @pymethod int|PyILockBytes|WriteAt|Writes the specified number of bytes starting at a specified offset from the beginning of the byte array. PyObject *PyILockBytes::WriteAt(PyObject *self, PyObject *args) { ILockBytes *pILB = GetI(self); if ( pILB == NULL ) return NULL; // @pyparm <o ULARGE_INTEGER>|ulOffset||Offset to write at. // @pyparm string|data||Data to write PyObject *obulOffset, *obpv; void *pv; ULONG cb; if ( !PyArg_ParseTuple(args, "OO:WriteAt", &obulOffset, &obpv)) return NULL; ULARGE_INTEGER ulOffset; if (!PyWinObject_AsULARGE_INTEGER(obulOffset, &ulOffset)) return NULL; if (!PyWinObject_AsReadBuffer(obpv, &pv, &cb, FALSE)) return NULL; ULONG pcbWritten; PY_INTERFACE_PRECALL; HRESULT hr = pILB->WriteAt( ulOffset, pv, cb, &pcbWritten ); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pILB, IID_ILockBytes); // @rdesc The result is the number of bytes actually written. return PyLong_FromUnsignedLong(pcbWritten); }
// @pymethod <o PyRecord>|pythoncom|GetRecordFromGuids|Creates a new record object from the given GUIDs PyObject *pythoncom_GetRecordFromGuids(PyObject *self, PyObject *args) { void *data = NULL; PyObject *obGuid, *obInfoGuid, *obdata=Py_None; int major, minor, lcid; int cb = 0; if (!PyArg_ParseTuple(args, "OiiiO|O:GetRecordFromGuids", &obGuid, // @pyparm <o PyIID>|iid||The GUID of the type library &major, // @pyparm int|verMajor||The major version number of the type lib. &minor, // @pyparm int|verMinor||The minor version number of the type lib. &lcid, // @pyparm int|lcid||The LCID of the type lib. &obInfoGuid, // @pyparm <o PyIID>|infoIID||The GUID of the record info in the library &obdata)) // @pyparm string or buffer|data|None|The raw data to initialize the record with. return NULL; if (!PyWinObject_AsReadBuffer(obdata, &data, &cb, TRUE)) return NULL; GUID guid, infoGuid; if (!PyWinObject_AsIID(obGuid, &guid)) return NULL; if (!PyWinObject_AsIID(obInfoGuid, &infoGuid)) return NULL; IRecordInfo *i = NULL; HRESULT hr = GetRecordInfoFromGuids(guid, major, minor, lcid, infoGuid, &i); if (FAILED(hr)) return PyCom_BuildPyException(hr); PyObject *ret = PyObject_FromRecordInfo(i, data, cb); i->Release(); return ret; }
STDMETHODIMP PyGLockBytes::ReadAt( /* [in] */ ULARGE_INTEGER ulOffset, /* [in] */ void __RPC_FAR * pv, /* [in] */ ULONG cb, /* [out] */ ULONG __RPC_FAR * pcbRead) { if (pv==NULL) return E_POINTER; if (pcbRead) *pcbRead = 0; PY_GATEWAY_METHOD; PyObject *obulOffset = PyWinObject_FromULARGE_INTEGER(ulOffset); PyObject *result; HRESULT hr=InvokeViaPolicy("ReadAt", &result, "Oi", obulOffset, cb); Py_XDECREF(obulOffset); if (FAILED(hr)) return hr; // Process the Python results, and convert back to the real params // Length of returned object must fit in buffer ! DWORD resultlen; VOID *buf; if (PyWinObject_AsReadBuffer(result, &buf, &resultlen, FALSE)){ if (resultlen > cb) PyErr_SetString(PyExc_ValueError,"PyGLockBytes::ReadAt: returned data longer than requested"); else{ memcpy(pv, buf, resultlen); if (pcbRead) *pcbRead = resultlen; hr = S_OK; } } Py_DECREF(result); return MAKE_PYCOM_GATEWAY_FAILURE_CODE("Read"); }
// @pymethod str|PyCRYPTKEY|CryptDecrypt|Decrypts data PyObject *PyCRYPTKEY::PyCryptDecrypt(PyObject *self, PyObject *args, PyObject *kwargs) { static char *keywords[]={"Final", "Data", "Hash", "Flags", NULL}; PyObject *obdata, *ret=NULL, *obcrypthash=Py_None; BOOL Final; DWORD err=0, bytes_to_decrypt=0, dwFlags=0, dwDataLen=0; BYTE *pbData=NULL, *origdata=NULL; HCRYPTHASH hcrypthash=NULL; HCRYPTKEY hcryptkey=((PyCRYPTKEY *)self)->GetHCRYPTKEY(); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "lO|Ok:CryptDecrypt", keywords, &Final, // @pyparm int|Final||Boolean, use True is this is last (or only) operation &obdata, // @pyparm buffer|Data||Data to be decrypted &obcrypthash, // @pyparm <o PyCRYPTHASH>|Hash|None|Hash to be used in signature verification, can be None &dwFlags)) // @pyparm int|Flags|0|Reserved, use only 0 return NULL; if (!PyWinObject_AsHCRYPTHASH(obcrypthash, &hcrypthash, TRUE)) return NULL; if (!PyWinObject_AsReadBuffer(obdata, (void **)&origdata, &bytes_to_decrypt, FALSE)) return NULL; // data buffer is read-write, do not pass in python's buffer pbData=(BYTE *)malloc(bytes_to_decrypt); if (pbData==NULL) return PyErr_NoMemory(); memcpy(pbData,origdata,bytes_to_decrypt); dwDataLen=bytes_to_decrypt; // read/write - receives length of plaintext // Due to padding, should never occur that buffer needed for plaintext is larger than encrypted data if (!CryptDecrypt(hcryptkey, hcrypthash, Final, dwFlags, pbData, &dwDataLen)) PyWin_SetAPIError("CryptDecrypt"); else ret=PyString_FromStringAndSize((char *)pbData, dwDataLen); free(pbData); return ret; }
// @pymethod <o PyPROPVARIANT>|propsys|PSGetNamedPropertyFromPropertyStorage|Extracts a property value from a serialized buffer by name static PyObject *PyPSGetNamedPropertyFromPropertyStorage(PyObject *self, PyObject *args) { TmpWCHAR name; void *buf; DWORD bufsize; PROPVARIANT val; PyObject *obname, *obbuf; // @pyparm buffer|ps||Bytes or buffer (or str in python 2) containing a serialized property set (see <om PyIPersistSerializedPropStorage.GetPropertyStorage>) // @pyparm str|name||Property to return if (!PyArg_ParseTuple(args, "OO:PSGetNamedPropertyFromPropertyStorage", &obbuf, &obname)) return NULL; if (!PyWinObject_AsReadBuffer(obbuf, &buf, &bufsize, FALSE)) return NULL; if (!PyWinObject_AsWCHAR(obname, &name, FALSE)) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = PSGetNamedPropertyFromPropertyStorage((PCUSERIALIZEDPROPSTORAGE)buf, bufsize, name, &val); PY_INTERFACE_POSTCALL; if (FAILED(hr)) return PyCom_BuildPyException(hr); return PyWinObject_FromPROPVARIANT(val); }
STDMETHODIMP PyGInternetSecurityManager::GetSecurityId( /* [in] */ LPCWSTR pwszUrl, /* [size_is][out] */ BYTE * pbSecurityId, /* [out][in] */ DWORD * pcbSecurityId, /* [in] */ DWORD_PTR dwReserved) { PY_GATEWAY_METHOD; PyObject *obdwReserved = PyWinObject_FromDWORD_PTR(dwReserved); if (obdwReserved==NULL) return MAKE_PYCOM_GATEWAY_FAILURE_CODE("GetSecurityId"); PyObject *obpwszUrl; obpwszUrl = MakeOLECHARToObj(pwszUrl); PyObject *result; HRESULT hr=InvokeViaPolicy("GetSecurityId", &result, "OlO", obpwszUrl, *pcbSecurityId, obdwReserved); Py_XDECREF(obpwszUrl); Py_DECREF(obdwReserved); if (FAILED(hr)) return hr; // Process the Python results, and convert back to the real params void *buf; DWORD buf_len; if (!PyWinObject_AsReadBuffer(result, &buf, &buf_len)) { Py_DECREF(result); return MAKE_PYCOM_GATEWAY_FAILURE_CODE("GetSecurityId"); } *pcbSecurityId = min(buf_len, *pcbSecurityId); memcpy(pbSecurityId, buf, *pcbSecurityId); Py_DECREF(result); return hr; }
// @pymethod <o PyUnicode>|pywintypes|UnicodeFromRaw|Creates a new Unicode object from raw binary data static PyObject *PyWin_NewUnicodeFromRaw(PyObject *self, PyObject *args) { PyObject *ob; // @pyparm string/buffer|str||The string containing the binary data. if (!PyArg_ParseTuple(args, "O", &ob)) return NULL; void *buf; DWORD nbytes; if (!PyWinObject_AsReadBuffer(ob, &buf, &nbytes, FALSE)) return NULL; return PyWinObject_FromWCHAR((WCHAR *)buf, nbytes/sizeof(OLECHAR) ); }
// @pymethod <o PyPROPVARIANT>|propsys|StgDeserializePropVariant|Creates a <o PyPROPVARIANT> from a serialized buffer static PyObject *PyStgDeserializePropVariant(PyObject *self, PyObject *args) { PROPVARIANT pv; SERIALIZEDPROPERTYVALUE *pspv; ULONG bufsize; PyObject *ob; HRESULT hr; if (!PyArg_ParseTuple(args, "O:StgDeserializePropVariant", &ob)) return NULL; // @pyparm bytes|prop||Buffer or bytes object (or str in Python 2) containing a serialized value if (!PyWinObject_AsReadBuffer(ob, (void **)&pspv, &bufsize)) return NULL; PY_INTERFACE_PRECALL; hr = StgDeserializePropVariant(pspv, bufsize, &pv); PY_INTERFACE_POSTCALL; if (FAILED(hr)) return PyCom_BuildPyException(hr); return PyWinObject_FromPROPVARIANT(&pv); };
// @pymethod str|PyCRYPTKEY|CryptEncrypt|Encrypts and optionally hashes data PyObject *PyCRYPTKEY::PyCryptEncrypt(PyObject *self, PyObject *args, PyObject *kwargs) { static char *keywords[]={"Final", "Data", "Hash", "Flags", NULL}; PyObject *obdata, *ret=NULL, *obcrypthash=Py_None; BOOL Final; DWORD err=0, bytes_to_encrypt=0, dwFlags=0, dwDataLen=0, dwBufLen=0; BYTE *pbData=NULL, *origdata; HCRYPTHASH hcrypthash=NULL; HCRYPTKEY hcryptkey=((PyCRYPTKEY *)self)->GetHCRYPTKEY(); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "lO|Ok:CryptEncrypt", keywords, &Final, // @pyparm int|Final||Boolean, use True if this is final encryption operation &obdata, // @pyparm buffer|Data||Data to be encrypted &obcrypthash, // @pyparm <o PyCRYPTHASH>|Hash|None|Hash to be updated with data passed in, can be None &dwFlags)) // @pyparm int|Flags|0|Reserved, use 0 if passed in return NULL; if (!PyWinObject_AsHCRYPTHASH(obcrypthash, &hcrypthash, TRUE)) return NULL; if (!PyWinObject_AsReadBuffer(obdata, (void **)&origdata, &bytes_to_encrypt, FALSE)) return NULL; dwDataLen=bytes_to_encrypt; // read/write - receives bytes needed for encrypted data dwBufLen=bytes_to_encrypt; // First call to get required buffer size - don't pass hash, or it will be updated twice if (!CryptEncrypt(hcryptkey, NULL, Final, dwFlags, NULL, &dwDataLen, dwBufLen)) return PyWin_SetAPIError("CryptEncrypt"); pbData=(BYTE *)malloc(dwDataLen); if (pbData==NULL) return PyErr_NoMemory(); memcpy(pbData,origdata,bytes_to_encrypt); dwBufLen=dwDataLen; dwDataLen=bytes_to_encrypt; if (!CryptEncrypt(hcryptkey, hcrypthash, Final, dwFlags, pbData, &dwDataLen, dwBufLen)) PyWin_SetAPIError("CryptEncrypt"); else ret=PyString_FromStringAndSize((char *)pbData, dwDataLen); free(pbData); return ret; }
// @pymethod |PyIPersistSerializedPropStorage|SetPropertyStorage|Initializes the store with a serialized buffer PyObject *PyIPersistSerializedPropStorage::SetPropertyStorage(PyObject *self, PyObject *args) { IPersistSerializedPropStorage *pIPSPS = GetI(self); if ( pIPSPS == NULL ) return NULL; PyObject *obbuf; void *buf; DWORD bufsize; // @pyparm buffer|ps||Bytes or buffer object containing a serialized property store if (!PyArg_ParseTuple(args, "O:SetPropertyStorage", &obbuf)) return NULL; if (!PyWinObject_AsReadBuffer(obbuf, &buf, &bufsize)) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIPSPS->SetPropertyStorage((PUSERIALIZEDPROPSTORAGE)buf, bufsize); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIPSPS, IID_IPersistSerializedPropStorage ); Py_INCREF(Py_None); return Py_None; }
// @pymethod <o PyPROPVARIANT>|propsys|PSGetPropertyFromPropertyStorage|Extracts a property value from a serialized buffer by key static PyObject *PyPSGetPropertyFromPropertyStorage(PyObject *self, PyObject *args) { PROPERTYKEY key; void *buf; DWORD bufsize; PROPVARIANT val; PyObject *obbuf; // @pyparm buffer|ps||Bytes or buffer (or str in python 2) containing a serialized property set (see <om PyIPersistSerializedPropStorage.GetPropertyStorage>) // @pyparm <o PyPROPERTYKEY>|key||Property to return if (!PyArg_ParseTuple(args, "OO&:PSGetPropertyFromPropertyStorage", &obbuf, PyWinObject_AsPROPERTYKEY, &key)) return NULL; if (!PyWinObject_AsReadBuffer(obbuf, &buf, &bufsize, FALSE)) return NULL; HRESULT hr; PY_INTERFACE_PRECALL; // PCUSERIALIZEDPROPSTORAGE psps, // IPersistSerializedPropStorage::GetPropertyStorage hr = PSGetPropertyFromPropertyStorage((PCUSERIALIZEDPROPSTORAGE)buf, bufsize, key, &val); PY_INTERFACE_POSTCALL; if (FAILED(hr)) return PyCom_BuildPyException(hr); return PyWinObject_FromPROPVARIANT(val); }
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; }