BOOL PyObject_AsPROPVARIANTs(PyObject *ob, PROPVARIANT **ppRet, ULONG *pcRet) { BOOL ret=FALSE; DWORD len, i; PyObject *tuple=PyWinSequence_Tuple(ob, &len); if (tuple==NULL) return FALSE; PROPVARIANT *pRet = new PROPVARIANT[len]; if (pRet==NULL){ PyErr_NoMemory(); goto cleanup; } for (i=0;i<len;i++) PropVariantInit(pRet+i); for (i=0;i<len;i++) { PyObject *sub = PyTuple_GET_ITEM(tuple, i); if (!PyObject_AsPROPVARIANT(sub, pRet+i)) goto cleanup; } ret=TRUE; cleanup: if (ret){ *ppRet = pRet; *pcRet = len; } else if (pRet) PyObject_FreePROPVARIANTs(pRet, len); Py_DECREF(tuple); return ret; }
// @object PROPSPEC|Identifies a property. Can be either an int property id, or a str/unicode property name. BOOL PyWinObject_AsPROPSPECs( PyObject *ob, PROPSPEC **ppRet, ULONG *pcRet) { TmpPyObject tuple=PyWinSequence_Tuple(ob, pcRet); if (tuple==NULL) return FALSE; size_t numBytes = sizeof(PROPSPEC) * *pcRet; *ppRet = (PROPSPEC *)malloc(numBytes); if (*ppRet==NULL) { PyErr_NoMemory(); return FALSE; } ZeroMemory(*ppRet, numBytes); for (DWORD i=0; i<*pcRet; i++) { PyObject *sub = PyTuple_GET_ITEM((PyObject *)tuple, i); (*ppRet)[i].propid = PyInt_AsUnsignedLongMask(sub); if ((*ppRet)[i].propid != (ULONG)-1 || !PyErr_Occurred()) (*ppRet)[i].ulKind = PRSPEC_PROPID; else{ PyErr_Clear(); (*ppRet)[i].lpwstr = NULL; if (PyWinObject_AsWCHAR(sub, &(*ppRet)[i].lpwstr)) (*ppRet)[i].ulKind = PRSPEC_LPWSTR; else{ PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "PROPSPECs must be a sequence of strings or integers"); PyObject_FreePROPSPECs(*ppRet, *pcRet); *ppRet=NULL; return FALSE; } } } return TRUE; }
BOOL PyWinObject_AsCharArray(PyObject *str_seq, char ***pchars, DWORD *str_cnt, BOOL bNoneOK) { BOOL ret=FALSE; PyObject *str_tuple=NULL, *tuple_item; DWORD bufsize, tuple_index; *pchars=NULL; *str_cnt=0; if (bNoneOK && str_seq==Py_None) return TRUE; if ((str_tuple=PyWinSequence_Tuple(str_seq, str_cnt))==NULL) return FALSE; bufsize=*str_cnt * sizeof(char *); *pchars=(char **)malloc(bufsize); if (*pchars==NULL){ PyErr_Format(PyExc_MemoryError, "Unable to allocate %d bytes", bufsize); goto done; } ZeroMemory(*pchars, bufsize); for (tuple_index=0;tuple_index<*str_cnt;tuple_index++){ tuple_item=PyTuple_GET_ITEM(str_tuple, tuple_index); if (!PyWinObject_AsString(tuple_item, &((*pchars)[tuple_index]), FALSE)){ PyWinObject_FreeCharArray(*pchars, *str_cnt); *pchars=NULL; *str_cnt=0; goto done; } } ret=TRUE; done: Py_DECREF(str_tuple); return ret; }
// @object PROPSPEC|Identifies a property. Can be either an int property id, or a str/unicode property name. BOOL PyObject_AsPROPSPECs( PyObject *ob, PROPSPEC **ppRet, ULONG *pcRet) { BOOL ret=FALSE; DWORD len, i; PyObject *tuple=PyWinSequence_Tuple(ob, &len); if (tuple==NULL) return FALSE; // First count the items, and the total string space we need. size_t cChars = 0; for (i=0;i<len;i++) { PyObject *sub = PyTuple_GET_ITEM(tuple, i); if (PyUnicode_Check(sub)) cChars += PyUnicode_GET_SIZE(sub) + 1; else if (PyString_Check(sub)) cChars += PyString_Size(sub) + 1; else if (PyInt_Check(sub)) ; // PROPID is a ULONG, so this may fail for values that require a python long else { PyErr_SetString(PyExc_TypeError, "PROPSPECs must be a sequence of strings or integers"); goto cleanup; } } size_t numBytes; numBytes = (sizeof(PROPSPEC) * len) + (sizeof(WCHAR) * cChars); PROPSPEC *pRet; pRet = (PROPSPEC *)malloc(numBytes); if (pRet==NULL) { PyErr_SetString(PyExc_MemoryError, "allocating PROPSPECs"); goto cleanup; } WCHAR *curBuf; curBuf = (WCHAR *)(pRet+len); for (i=0;i<len;i++) { PyObject *sub = PyTuple_GET_ITEM(tuple, i); BSTR bstr; if (PyWinObject_AsBstr(sub, &bstr)) { pRet[i].ulKind = PRSPEC_LPWSTR; pRet[i].lpwstr = curBuf; wcscpy( curBuf, bstr); curBuf += wcslen(curBuf) + 1; PyWinObject_FreeBstr(bstr); } else { PyErr_Clear(); pRet[i].ulKind = PRSPEC_PROPID; pRet[i].propid = PyInt_AsLong(sub); } } ret=TRUE; *ppRet = pRet; *pcRet = len; cleanup: Py_DECREF(tuple); return ret; }
// Same conversion as PyObject_AsPROPVARIANTs, but PROPVARIANT array is allocated by caller BOOL PyObject_AsPreallocatedPROPVARIANTs(PyObject *ob, PROPVARIANT *propvars, ULONG cpropvars) { DWORD len, i; TmpPyObject tuple=PyWinSequence_Tuple(ob, &len); if (tuple==NULL) return FALSE; if (len != cpropvars){ PyErr_SetString(PyExc_ValueError, "Sequence not of required length"); return FALSE; } for (i=0; i<cpropvars; i++) { PyObject *sub = PyTuple_GET_ITEM((PyObject *)tuple, i); if (!PyObject_AsPROPVARIANT(sub, &propvars[i])) for (; i--;) PropVariantClear(&propvars[i]); return FALSE; } return TRUE; }
// Alocates and populates an array of DWORDS from a sequence of Python ints BOOL PyWinObject_AsDWORDArray(PyObject *obdwords, DWORD **pdwords, DWORD *item_cnt, BOOL bNoneOk) { BOOL ret=TRUE; DWORD bufsize, tuple_index; PyObject *dwords_tuple=NULL, *tuple_item; *pdwords=NULL; *item_cnt=0; if (obdwords==Py_None){ if (bNoneOk) return TRUE; PyErr_SetString(PyExc_ValueError,"Sequence of dwords cannot be None"); return FALSE; } if ((dwords_tuple=PyWinSequence_Tuple(obdwords, item_cnt))==NULL) return FALSE; // last exit without cleaning up bufsize=*item_cnt * sizeof(DWORD); *pdwords=(DWORD *)malloc(bufsize); if (*pdwords==NULL){ PyErr_Format(PyExc_MemoryError, "Unable to allocate %d bytes", bufsize); ret=FALSE; } else for (tuple_index=0; tuple_index<*item_cnt; tuple_index++){ tuple_item=PyTuple_GET_ITEM(dwords_tuple,tuple_index); // Doesn't check for overflow, but will accept a python long // greater than INT_MAX (even on python 2.3). Also accepts // negatives and converts to the correct hex representation (*pdwords)[tuple_index]=PyInt_AsUnsignedLongMask(tuple_item); if (((*pdwords)[tuple_index]==-1) && PyErr_Occurred()){ ret=FALSE; break; } } if (!ret) if (*pdwords!=NULL){ free(*pdwords); *pdwords=NULL; *item_cnt=0; } Py_XDECREF(dwords_tuple); return ret; }
// Converts a sequence of strings into a caller-allocated array of WCHAR pointers, // each of which is allocated using CoTaskMemAlloc BOOL PyWinObject_AsTaskAllocatedWCHARArray(PyObject *str_seq, LPWSTR *wchars, ULONG str_cnt) { TmpPyObject str_tuple; ULONG seq_size, tuple_index; ZeroMemory(wchars, str_cnt * sizeof(WCHAR *)); if ((str_tuple=PyWinSequence_Tuple(str_seq, &seq_size))==NULL) return FALSE; if (seq_size != str_cnt){ PyErr_SetString(PyExc_ValueError, "Sequence not of required length"); return FALSE; } for (tuple_index=0; tuple_index<str_cnt; tuple_index++){ PyObject *tuple_item=PyTuple_GET_ITEM((PyObject *)str_tuple, tuple_index); if (!PyWinObject_AsTaskAllocatedWCHAR(tuple_item, &wchars[tuple_index], FALSE)){ for (tuple_index=0; tuple_index<str_cnt; tuple_index++) if (wchars[tuple_index]) CoTaskMemFree(wchars[tuple_index]); return FALSE; } } return TRUE; }