// 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);
}
Exemple #3
0
// @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");
}
Exemple #5
0
// @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);
};
Exemple #10
0
// @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);
}
Exemple #13
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;
}