PyObject *PyObject_FromPROPVARIANT( PROPVARIANT *pVar ) { switch (pVar->vt) { case VT_EMPTY: case VT_NULL: case VT_ILLEGAL: Py_INCREF(Py_None); return Py_None; case VT_I1: return PyInt_FromLong(pVar->cVal); case VT_I1|VT_VECTOR: return VectorToSeq(pVar->cac.pElems, pVar->cac.cElems, PyWinObject_FromCHAR); case VT_UI1: return PyInt_FromLong(pVar->bVal); case VT_UI1|VT_VECTOR: return VectorToSeq(pVar->caub.pElems, pVar->caub.cElems, PyWinObject_FromUCHAR); case VT_I2: return PyInt_FromLong(pVar->iVal); case VT_I2|VT_VECTOR: return VectorToSeq(pVar->cai.pElems, pVar->cai.cElems, PyWinObject_FromSHORT); case VT_UI2: return PyInt_FromLong(pVar->uiVal); case VT_UI2|VT_VECTOR: return VectorToSeq(pVar->caui.pElems, pVar->caui.cElems, PyWinObject_FromUSHORT); case VT_I4: return PyInt_FromLong(pVar->lVal); case VT_I4|VT_VECTOR: return VectorToSeq(pVar->cal.pElems, pVar->cal.cElems, PyInt_FromLong); case VT_INT: return PyInt_FromLong(pVar->intVal); case VT_UI4: return PyLong_FromUnsignedLong(pVar->ulVal); case VT_UI4|VT_VECTOR: return VectorToSeq(pVar->caul.pElems, pVar->caul.cElems, PyLong_FromUnsignedLong); case VT_UINT: return PyLong_FromUnsignedLong(pVar->uintVal); case VT_I8: return PyWinObject_FromLARGE_INTEGER(pVar->hVal); case VT_I8|VT_VECTOR: return VectorToSeq<LARGE_INTEGER>(pVar->cah.pElems, pVar->cah.cElems, PyWinObject_FromLARGE_INTEGER); case VT_UI8: return PyWinObject_FromULARGE_INTEGER(pVar->uhVal); case VT_UI8|VT_VECTOR: return VectorToSeq<ULARGE_INTEGER>(pVar->cauh.pElems, pVar->cauh.cElems, PyWinObject_FromULARGE_INTEGER); case VT_R4: return PyFloat_FromDouble(pVar->fltVal); case VT_R4|VT_VECTOR: return VectorToSeq(pVar->caflt.pElems, pVar->caflt.cElems, PyWinObject_FromFLOAT); case VT_R8: return PyFloat_FromDouble(pVar->dblVal); case VT_R8|VT_VECTOR: return VectorToSeq(pVar->cadbl.pElems, pVar->cadbl.cElems, PyFloat_FromDouble); case VT_CY: return PyObject_FromCurrency(pVar->cyVal); case VT_CY|VT_VECTOR: return VectorToSeq<CY>(pVar->cacy.pElems, pVar->cacy.cElems, PyObject_FromCurrency); case VT_DATE: return PyWinObject_FromDATE(pVar->date); case VT_DATE|VT_VECTOR: return VectorToSeq(pVar->cadate.pElems, pVar->cadate.cElems, PyWinObject_FromDATE); case VT_BSTR: return PyWinObject_FromBstr(pVar->bstrVal); case VT_BSTR|VT_VECTOR: return VectorToSeq(pVar->cabstr.pElems, pVar->cabstr.cElems, PyWinObject_FromVT_BSTR); case VT_BOOL: return PyWinObject_FromVARIANT_BOOL(pVar->boolVal); case VT_BOOL|VT_VECTOR: return VectorToSeq(pVar->cabool.pElems, pVar->cabool.cElems, PyWinObject_FromVARIANT_BOOL); case VT_ERROR: return PyInt_FromLong(pVar->scode); case VT_ERROR|VT_VECTOR: return VectorToSeq(pVar->cascode.pElems, pVar->cascode.cElems, PyInt_FromLong); case VT_FILETIME: return PyWinObject_FromFILETIME(pVar->filetime); case VT_FILETIME|VT_VECTOR: return VectorToSeq<FILETIME>(pVar->cafiletime.pElems, pVar->cafiletime.cElems, PyWinObject_FromFILETIME); case VT_LPSTR: if (pVar->pszVal == NULL) { Py_INCREF(Py_None); return Py_None; } return PyWinCoreString_FromString(pVar->pszVal); case VT_LPSTR|VT_VECTOR: { PyObject *ret = PyList_New(pVar->calpstr.cElems); if (ret==NULL) return NULL; for (ULONG i=0; i<pVar->calpstr.cElems;i++){ PyObject *elem=PyWinCoreString_FromString(pVar->calpstr.pElems[i]); if (elem==NULL){ Py_DECREF(ret); return NULL; } PyList_SET_ITEM(ret, i, elem); } return ret; } case VT_LPWSTR: return PyWinObject_FromOLECHAR(pVar->pwszVal); case VT_LPWSTR|VT_VECTOR: { PyObject *ret = PyList_New(pVar->calpwstr.cElems); if (ret==NULL) return NULL; for (ULONG i=0; i<pVar->calpwstr.cElems;i++){ PyObject *elem=PyWinObject_FromWCHAR(pVar->calpwstr.pElems[i]); if (elem==NULL){ Py_DECREF(ret); return NULL; } PyList_SET_ITEM(ret, i, elem); } return ret; } case VT_CLSID: return PyWinObject_FromIID(*pVar->puuid); case VT_CLSID|VT_VECTOR: return VectorToSeq<CLSID>(pVar->cauuid.pElems, pVar->cauuid.cElems, PyWinObject_FromIID); case VT_STREAM: case VT_STREAMED_OBJECT: return PyCom_PyObjectFromIUnknown(pVar->pStream, IID_IStream, TRUE); case VT_STORAGE: case VT_STORED_OBJECT: return PyCom_PyObjectFromIUnknown(pVar->pStorage, IID_IStorage, TRUE); case VT_VECTOR | VT_VARIANT: return PyObject_FromPROPVARIANTs(pVar->capropvar.pElems, pVar->capropvar.cElems); case VT_BLOB: case VT_BLOB_OBJECT: return PyString_FromStringAndSize((const char *)pVar->blob.pBlobData, pVar->blob.cbSize); // case VT_UNKNOWN: // return PyCom_PyObjectFromIUnknown(pVar->punkVal, IID_IUnknown, TRUE); // case VT_DISPATCH: // return PyCom_PyObjectFromIUnknown(pVar->pdispVal, IID_IDispatch, TRUE); /* // Want to get VT_CF and VT_BLOB working with a test case first! case VT_CF: { // special "clipboard format" // cbSize is the size of the buffer pointed to // by pClipData, plus sizeof(ulClipFmt) // XXX - in that case, shouldn't we pass // pClipData + sizeof(DWORD) to Py_BuildValue?? ULONG cb = CBPCLIPDATA(*pVar->pclipdata); return Py_BuildValue("is#", pVar->pclipdata->ulClipFmt, pVar->pclipdata->pClipData, (int)cb); } */ default: PyErr_Format(PyExc_TypeError, "Unsupported property type 0x%x", pVar->vt); return NULL; } }
PyObject * dataconv_ReadFromInTuple(PyObject *self, PyObject *args) { PyObject *obArgTypes; PyObject *obArgType; PyObject *obPtr; BYTE *pb; BYTE *pbArg; Py_ssize_t cArgs, i; PyObject *obArgs = NULL; PyObject *obArg; VARTYPE vtArgType; UINT cb; VARIANT var; BOOL bIsByRef; if (!PyArg_ParseTuple(args, "OO:ReadFromInTuple", &obArgTypes, &obPtr)) return NULL; pbArg = (BYTE *)PyLong_AsVoidPtr(obPtr); assert(pbArg); if (!pbArg) return NULL; pb = pbArg; if (!PyTuple_Check(obArgTypes)) { PyErr_SetString(PyExc_TypeError, "OLE type description - expecting a tuple"); return NULL; } cArgs = PyTuple_Size(obArgTypes); obArgs = PyTuple_New(cArgs); if (!obArgs) return NULL; for(i = 0 ; i < cArgs; i++) { // (<type tuple>, argPtr offset, arg size) if (PyTuple_Size(PyTuple_GET_ITEM(obArgTypes, i)) != 3) { PyErr_SetString(PyExc_TypeError, "OLE type description - expecting an arg desc tuple of size 3"); goto Error; } obArgType = PyTuple_GET_ITEM(PyTuple_GET_ITEM(obArgTypes, i), 0); // Position pb to point to the current argument. pb = pbArg + PyInt_AS_LONG(PyTuple_GET_ITEM(PyTuple_GET_ITEM(obArgTypes, i), 1)); vtArgType = (VARTYPE)PyInt_AS_LONG(obArgType); #ifdef _M_IX86 bIsByRef = vtArgType & VT_BYREF; #elif _M_X64 // params > 64bits always passed by address - and the only // arg we support > 64 bits is a VARIANT structure. bIsByRef = (vtArgType==VT_VARIANT) || (vtArgType & VT_BYREF); #else #error Unknown platform #endif VARTYPE vtConversionType = vtArgType & VT_TYPEMASK; if (vtArgType & VT_ARRAY) { SAFEARRAY FAR *psa = *((SAFEARRAY **)pb); if (psa==NULL) { // A NULL array Py_INCREF(Py_None); obArg = Py_None; } else { if (vtArgType & VT_BYREF) // one more level of indirection psa = *((SAFEARRAY FAR **)psa); if (psa==NULL) { // A NULL array Py_INCREF(Py_None); obArg = Py_None; } else obArg = PyCom_PyObjectFromSAFEARRAY(psa, (VARENUM)vtConversionType); } } else { switch (vtConversionType) { // If they can fit in a VARIANT, cheat and make that code do all of the work... case VT_I2: case VT_I4: case VT_R4: case VT_R8: case VT_CY: case VT_DATE: case VT_BSTR: case VT_ERROR: case VT_BOOL: case VT_I1: case VT_UI1: case VT_UI2: case VT_UI4: case VT_INT: case VT_UINT: case VT_UNKNOWN: case VT_DISPATCH: case VT_HRESULT: VariantInit(&var); if (vtConversionType == VT_HRESULT || vtConversionType == VT_INT) { // Preserve VT_BYREF or VT_ARRAY vtArgType = VT_I4 | (vtArgType & VT_TYPEMASK); } if (vtArgType == VT_UINT) { // Preserve VT_BYREF or VT_ARRAY vtArgType = VT_UI4 | (vtArgType & VT_TYPEMASK); } V_VT(&var) = vtArgType; // Copy the data into the variant... if (!SizeOfVT(V_VT(&var), (int *)&cb, NULL)) goto Error; memcpy(&V_I4(&var), pb, cb); // Convert it into a PyObject: obArg = PyCom_PyObjectFromVariant(&var); break; case VT_VARIANT: // A _real_ variant. if (bIsByRef) obArg = PyCom_PyObjectFromVariant(*(VARIANT**)pb); else obArg = PyCom_PyObjectFromVariant((VARIANT*)pb); break; case VT_LPSTR: obArg = PyString_FromString(*(CHAR **)pb); break; case VT_LPWSTR: obArg = PyWinObject_FromOLECHAR(*(OLECHAR **)pb); break; // Special cases: case VT_UI8: if (bIsByRef) { obArg = PyWinObject_FromULARGE_INTEGER(*(ULARGE_INTEGER *)pb); } else { obArg = PyWinObject_FromULARGE_INTEGER(**(ULARGE_INTEGER **)pb); } break; case VT_I8: if (bIsByRef) { obArg = PyWinObject_FromLARGE_INTEGER(*(LARGE_INTEGER *)pb); } else { obArg = PyWinObject_FromLARGE_INTEGER(**(LARGE_INTEGER **)pb); } break; // Pointers to unhandled arguments: // neither of these will be VT_BYREF'd. case VT_RECORD: case VT_PTR: obArg = PyLong_FromVoidPtr((void *)pb); break; // None of these should ever happen: case VT_USERDEFINED: // Should have been coerced into VT_PTR. case VT_CARRAY: default: obArg = NULL; PyErr_SetString(PyExc_TypeError, "Unknown/bad type description type!"); // barf here, we don't wtf they were thinking... break; } // switch } // if ARRAY if (obArg == NULL) { goto Error; } PyTuple_SET_ITEM(obArgs, i, obArg); } return obArgs; Error: Py_XDECREF(obArgs); return NULL; }
PyObject *PyMAPIObject_FromSPropValue(SPropValue *pv) { PyObject *val; ULONG i; switch (PROP_TYPE(pv->ulPropTag)) { case PT_I2: // case PT_SHORT: val = PyInt_FromLong(pv->Value.i); break; case PT_I4: // case PT_LONG: val = PyInt_FromLong(pv->Value.l); break; case PT_R4: // case PT_FLOAT: val = PyFloat_FromDouble(pv->Value.flt); break; case PT_R8: // case PT_DOUBLE: val = PyFloat_FromDouble(pv->Value.dbl); break; case PT_BOOLEAN: val = pv->Value.b ? Py_True : Py_False; Py_INCREF(val); break; /* case PT_CURRENCY: pv->Value.cur?? break; */ case PT_APPTIME : val = PyWinObject_FromDATE(pv->Value.at); break; case PT_SYSTIME: val = PyWinObject_FromFILETIME(pv->Value.ft); break; case PT_STRING8: val = PyString_FromString(pv->Value.lpszA); break; case PT_UNICODE: val = PyWinObject_FromWCHAR(pv->Value.lpszW); break; case PT_BINARY: val = PyString_FromStringAndSize((char *)pv->Value.bin.lpb, pv->Value.bin.cb); break; case PT_CLSID: val = PyWinObject_FromIID(*pv->Value.lpguid); break; case PT_I8: // case PT_LONGLONG: val = PyWinObject_FromLARGE_INTEGER(pv->Value.li); break; case PT_ERROR: val = PyInt_FromLong(pv->Value.err); break; case PT_NULL: val = Py_None; Py_INCREF(Py_None); break; case PT_MV_I2: val = PyTuple_New(pv->Value.MVi.cValues); if (val) { for (i=0; i<pv->Value.MVi.cValues; i++) PyTuple_SET_ITEM(val, i, PyInt_FromLong(pv->Value.MVi.lpi[i])); } break; case PT_MV_LONG: val = PyTuple_New(pv->Value.MVi.cValues); if (val) { for (i=0; i<pv->Value.MVl.cValues; i++) PyTuple_SET_ITEM(val, i, PyInt_FromLong(pv->Value.MVl.lpl[i])); } break; case PT_MV_R4: val = PyTuple_New(pv->Value.MVflt.cValues); if (val) { for (i=0; i<pv->Value.MVflt.cValues; i++) PyTuple_SET_ITEM(val, i, PyFloat_FromDouble(pv->Value.MVflt.lpflt[i])); } break; case PT_MV_DOUBLE : val = PyTuple_New(pv->Value.MVdbl.cValues); if (val) { for (i=0; i<pv->Value.MVdbl.cValues; i++) PyTuple_SET_ITEM(val, i, PyFloat_FromDouble(pv->Value.MVdbl.lpdbl[i])); } break; /* case PT_MV_CURRENCY: MVcur SCurrencyArray */ case PT_MV_APPTIME : val = PyTuple_New(pv->Value.MVat.cValues); if (val) { for (i=0; i<pv->Value.MVat.cValues; i++) PyTuple_SET_ITEM(val, i, PyWinObject_FromDATE(pv->Value.MVat.lpat[i])); } break; case PT_MV_SYSTIME: val = PyTuple_New(pv->Value.MVft.cValues); if (val) { for (i=0; i<pv->Value.MVft.cValues; i++) PyTuple_SET_ITEM(val, i, PyWinObject_FromFILETIME(pv->Value.MVft.lpft[i])); } break; case PT_MV_BINARY: val = PyTuple_New(pv->Value.MVbin.cValues); if (val) { for (i=0; i<pv->Value.MVbin.cValues; i++) PyTuple_SET_ITEM(val, i, PyString_FromStringAndSize((char *)pv->Value.MVbin.lpbin[i].lpb, pv->Value.MVbin.lpbin[i].cb)); } break; case PT_MV_STRING8: val = PyTuple_New(pv->Value.MVszA.cValues); if (val) { for (i=0; i<pv->Value.MVszA.cValues; i++) PyTuple_SET_ITEM(val, i, PyString_FromString(pv->Value.MVszA.lppszA[i])); } break; case PT_MV_UNICODE: val = PyTuple_New(pv->Value.MVszW.cValues); if (val) { for (i=0; i<pv->Value.MVszW.cValues; i++) PyTuple_SET_ITEM(val, i, PyWinObject_FromWCHAR(pv->Value.MVszW.lppszW[i])); } break; /* case PT_MV_CLSID: MVguid SGuidArray case PT_MV_I8: MVli SLargeIntegerArray */ case PT_OBJECT: val = PyInt_FromLong(pv->Value.x); break; default: printf("File %s: Unsupported MAPI property type 0x%X", __FILE__, PROP_TYPE(pv->ulPropTag)); /* Dont set exception, as this prevents otherwise valid props from being returned */ val = Py_None; Py_INCREF(Py_None); break; } PyObject *rc = PyTuple_New(2); if (rc==NULL) { Py_DECREF(val); PyErr_SetString(PyExc_MemoryError, "Tuple(2) for PROP result"); return NULL; } PyTuple_SET_ITEM(rc, 0, PyInt_FromLong(pv->ulPropTag)); PyTuple_SET_ITEM(rc, 1, val); return rc; }
// @object PyADSVALUE|A tuple: // @tupleitem 0|object|value|The value as a Python object. // @tupleitem 1|int|type|The AD type of the value. PyObject *PyADSIObject_FromADSVALUE(ADSVALUE &v) { PyObject *ob = NULL; switch (v.dwType) { case ADSTYPE_DN_STRING: ob = PyWinObject_FromWCHAR(v.DNString); break; case ADSTYPE_CASE_EXACT_STRING: ob = PyWinObject_FromWCHAR(v.CaseExactString); break; case ADSTYPE_CASE_IGNORE_STRING: ob = PyWinObject_FromWCHAR(v.CaseIgnoreString); break; case ADSTYPE_PRINTABLE_STRING: ob = PyWinObject_FromWCHAR(v.PrintableString); break; case ADSTYPE_NUMERIC_STRING: ob = PyWinObject_FromWCHAR(v.NumericString); break; case ADSTYPE_BOOLEAN: ob = v.Boolean ? Py_True : Py_False; Py_INCREF(ob); break; case ADSTYPE_INTEGER: ob = PyInt_FromLong(v.Integer); break; case ADSTYPE_OCTET_STRING: { void *buf; DWORD bufSize = v.OctetString.dwLength; if (!(ob=PyBuffer_New(bufSize))) return NULL; if (!PyWinObject_AsWriteBuffer(ob, &buf, &bufSize)){ Py_DECREF(ob); return NULL; } memcpy(buf, v.OctetString.lpValue, bufSize); } break; case ADSTYPE_UTC_TIME: ob = PyWinObject_FromSYSTEMTIME(v.UTCTime); break; case ADSTYPE_LARGE_INTEGER: ob = PyWinObject_FromLARGE_INTEGER(v.LargeInteger); break; case ADSTYPE_OBJECT_CLASS: ob = PyWinObject_FromWCHAR(v.ClassName); break; case ADSTYPE_PROV_SPECIFIC: { void *buf; DWORD bufSize = v.ProviderSpecific.dwLength; if (!(ob=PyBuffer_New(bufSize))) return NULL; if (!PyWinObject_AsWriteBuffer(ob, &buf, &bufSize)){ Py_DECREF(ob); return NULL; } memcpy(buf, v.ProviderSpecific.lpValue, bufSize); break; } case ADSTYPE_NT_SECURITY_DESCRIPTOR: { // Get a pointer to the security descriptor. PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR)(v.SecurityDescriptor.lpValue); DWORD SDSize = v.SecurityDescriptor.dwLength; // eeek - we don't pass the length - pywintypes relies on // GetSecurityDescriptorLength - make noise if this may bite us. if (SDSize != GetSecurityDescriptorLength(pSD)) PyErr_Warn(PyExc_RuntimeWarning, "Security-descriptor size mis-match"); ob = PyWinObject_FromSECURITY_DESCRIPTOR(pSD); break; } default: { char msg[100]; sprintf(msg, "Unknown ADS type code 0x%x - None will be returned", v.dwType); PyErr_Warn(PyExc_RuntimeWarning, msg); ob = Py_None; Py_INCREF(ob); } } if (ob==NULL) return NULL; PyObject *ret = Py_BuildValue("Oi", ob, (int)v.dwType); Py_DECREF(ob); return ret; }