[pywin32-checkins] /hgroot/pywin32/pywin32: 2 new changesets
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
From: <pyw...@li...> - 2012-08-22 01:34:36
|
changeset d6e31fa65434 in /hgroot/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgroot/pywin32/pywin32?cmd=changeset;node=d6e31fa65434 summary: Fix a couple of places where BSTR used for WCHAR changeset cb8d7cb7982e in /hgroot/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgroot/pywin32/pywin32?cmd=changeset;node=cb8d7cb7982e summary: Allow property functions to accept full range of ULONG, and make sure no exception is left hanging diffstat: com/win32com/src/extensions/PyIPropertyBag.cpp | 25 +-- com/win32com/src/extensions/PyIPropertySetStorage.cpp | 44 +++--- com/win32com/src/extensions/PyIPropertyStorage.cpp | 106 +++++++---------- win32/src/PyWinTypesmodule.cpp | 5 +- 4 files changed, 81 insertions(+), 99 deletions(-) diffs (truncated from 365 to 300 lines): diff -r d6adf5a1b26e -r cb8d7cb7982e com/win32com/src/extensions/PyIPropertyBag.cpp --- a/com/win32com/src/extensions/PyIPropertyBag.cpp Mon Aug 20 19:51:40 2012 -0400 +++ b/com/win32com/src/extensions/PyIPropertyBag.cpp Tue Aug 21 21:32:33 2012 -0400 @@ -24,7 +24,7 @@ int varType = VT_EMPTY; PyObject *obLog = NULL; PyObject *obName; - // @pyparm string|propName||Name of the property to read. + // @pyparm str|propName||Name of the property to read. // @pyparm int|propType||The type of the object to read. Must be a VT_* Variant Type constant. // @pyparm <o PyIErrorLog>|errorLog|None|The caller's <o PyIErrorLog> object in which the property bag stores any errors that occur during reads. Can be None in which case the caller is not interested in errors. if ( !PyArg_ParseTuple(args, "O|iO:Read", &obName, &varType, &obLog) ) @@ -34,24 +34,22 @@ if ( pIPB == NULL ) return NULL; - BSTR bstrName; - if (!PyWinObject_AsBstr(obName, &bstrName)) return NULL; + TmpWCHAR Name; + if (!PyWinObject_AsWCHAR(obName, &Name)) + return NULL; IErrorLog *pIEL = NULL; if ( obLog != NULL && obLog != Py_None && - !PyCom_InterfaceFromPyObject(obLog, IID_IErrorLog, (LPVOID*)&pIEL, FALSE) ) { - PyWinObject_FreeBstr(bstrName); + !PyCom_InterfaceFromPyObject(obLog, IID_IErrorLog, (LPVOID*)&pIEL, FALSE) ) return NULL; - } VARIANT var; VariantInit(&var); V_VT(&var) = varType; // ### do we need to set anything more? PY_INTERFACE_PRECALL; - HRESULT hr = pIPB->Read(bstrName, &var, pIEL); + HRESULT hr = pIPB->Read(Name, &var, pIEL); if ( pIEL != NULL ) pIEL->Release(); - PyWinObject_FreeBstr(bstrName); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIPB, IID_IPropertyBag); @@ -67,7 +65,7 @@ { PyObject *obName; PyObject *obValue; - // @pyparm string|propName||Name of the property to read. + // @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; @@ -76,17 +74,16 @@ if ( pIPB == NULL ) return NULL; + TmpWCHAR Name; + if ( !PyWinObject_AsWCHAR(obName, &Name)) + return NULL; VARIANT var; if ( !PyCom_VariantFromPyObject(obValue, &var) ) return NULL; - BSTR bstrName; - if ( !PyWinObject_AsBstr(obName, &bstrName)) - return NULL; PY_INTERFACE_PRECALL; - HRESULT hr = pIPB->Write(bstrName, &var); + HRESULT hr = pIPB->Write(Name, &var); VariantClear(&var); - PyWinObject_FreeBstr(bstrName); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ) return PyCom_BuildPyException(hr, pIPB, IID_IPropertyBag); diff -r d6adf5a1b26e -r cb8d7cb7982e com/win32com/src/extensions/PyIPropertySetStorage.cpp --- a/com/win32com/src/extensions/PyIPropertySetStorage.cpp Mon Aug 20 19:51:40 2012 -0400 +++ b/com/win32com/src/extensions/PyIPropertySetStorage.cpp Tue Aug 21 21:32:33 2012 -0400 @@ -27,7 +27,7 @@ return (IPropertySetStorage *)PyIUnknown::GetI(self); } -// @pymethod |PyIPropertySetStorage|Create|Description of Create. +// @pymethod <o PyIPropertyStorage>|PyIPropertySetStorage|Create|Creates a new property set in the storage object PyObject *PyIPropertySetStorage::Create(PyObject *self, PyObject *args) { IPropertySetStorage *pIPSS = GetI(self); @@ -37,10 +37,10 @@ PyObject *obrfmtid; CLSID pclsid; PyObject *obpclsid; - // @pyparm <o PyIID>|fmtid||Description for fmtid - // @pyparm <o PyIID>|clsid>||Description for clsid - // @pyparm int|grfFlags||Description for grfFlags - // @pyparm int|grfMode||Description for grfMode + // @pyparm <o PyIID>|fmtid||GUID identifying a property set, pythoncom.FMTID_* + // @pyparm <o PyIID>|clsid||CLSID of property set handler, usually same as fmtid + // @pyparm int|Flags||Specifies behaviour of property set, storagecon.PROPSETFLAG_* + // @pyparm int|Mode||Access mode, combination of storagecon.STGM_* flags DWORD grfFlags; DWORD grfMode; IPropertyStorage * ppprstg; @@ -61,7 +61,7 @@ return PyCom_PyObjectFromIUnknown(ppprstg, IID_IPropertyStorage, FALSE); } -// @pymethod |PyIPropertySetStorage|Open|Description of Open. +// @pymethod <o PyIPropertyStorage>|PyIPropertySetStorage|Open|Opens an existing property set PyObject *PyIPropertySetStorage::Open(PyObject *self, PyObject *args) { IPropertySetStorage *pIPSS = GetI(self); @@ -69,15 +69,14 @@ return NULL; FMTID rfmtid; PyObject *obrfmtid; - // @pyparm <o PyIID>|fmtid||Description for fmtid - // @pyparm int|grfMode|STGM_READ \| STGM_SHARE_EXCLUSIVE|Description for grfMode + // @pyparm <o PyIID>|fmtid||GUID of a property set, pythoncom.FMTID_* + // @pyparm int|Mode|STGM_READ \| STGM_SHARE_EXCLUSIVE|Access mode, combination of storagecon.STGM_* flags DWORD grfMode=STGM_READ | STGM_SHARE_EXCLUSIVE; IPropertyStorage * ppprstg; if ( !PyArg_ParseTuple(args, "O|l:Open", &obrfmtid, &grfMode) ) return NULL; - BOOL bPythonIsHappy = TRUE; - if (bPythonIsHappy && !PyWinObject_AsIID( obrfmtid, &rfmtid )) bPythonIsHappy = FALSE; - if (!bPythonIsHappy) return NULL; + if (!PyWinObject_AsIID( obrfmtid, &rfmtid )) + return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIPSS->Open( rfmtid, grfMode, &ppprstg ); @@ -89,7 +88,7 @@ return PyCom_PyObjectFromIUnknown(ppprstg, IID_IPropertyStorage, FALSE); } -// @pymethod |PyIPropertySetStorage|Delete|Description of Delete. +// @pymethod |PyIPropertySetStorage|Delete|Removes a property set from this storage object PyObject *PyIPropertySetStorage::Delete(PyObject *self, PyObject *args) { IPropertySetStorage *pIPSS = GetI(self); @@ -97,12 +96,11 @@ return NULL; FMTID rfmtid; PyObject *obrfmtid; - // @pyparm <o PyIID>|fmtid||Description for fmtid + // @pyparm <o PyIID>|fmtid||GUID of a property set, pythoncom.FMTID_* if ( !PyArg_ParseTuple(args, "O:Delete", &obrfmtid) ) return NULL; - BOOL bPythonIsHappy = TRUE; - if (bPythonIsHappy && !PyWinObject_AsIID( obrfmtid, &rfmtid )) bPythonIsHappy = FALSE; - if (!bPythonIsHappy) return NULL; + if (!PyWinObject_AsIID( obrfmtid, &rfmtid )) + return NULL; HRESULT hr; PY_INTERFACE_PRECALL; hr = pIPSS->Delete( rfmtid ); @@ -112,10 +110,9 @@ return PyCom_BuildPyException(hr, pIPSS, IID_IPropertySetStorage); Py_INCREF(Py_None); return Py_None; - } -// @pymethod |PyIPropertySetStorage|Enum|Description of Enum. +// @pymethod <o PyIEnumSTATPROPSETSTG>|PyIPropertySetStorage|Enum|Creates an iterator to enumerate contained property sets PyObject *PyIPropertySetStorage::Enum(PyObject *self, PyObject *args) { IPropertySetStorage *pIPSS = GetI(self); @@ -135,13 +132,14 @@ return PyCom_PyObjectFromIUnknown(ppenum, IID_IEnumSTATPROPSETSTG, FALSE); } -// @object PyIPropertySetStorage|Description of the interface +// @object PyIPropertySetStorage|Container for a collection of property sets. +// Can be iterated over to enumerate property sets. static struct PyMethodDef PyIPropertySetStorage_methods[] = { - { "Create", PyIPropertySetStorage::Create, 1 }, // @pymeth Create|Description of Create - { "Open", PyIPropertySetStorage::Open, 1 }, // @pymeth Open|Description of Open - { "Delete", PyIPropertySetStorage::Delete, 1 }, // @pymeth Delete|Description of Delete - { "Enum", PyIPropertySetStorage::Enum, 1 }, // @pymeth Enum|Description of Enum + { "Create", PyIPropertySetStorage::Create, 1 }, // @pymeth Create|Creates a new property set in the storage object + { "Open", PyIPropertySetStorage::Open, 1 }, // @pymeth Open|Opens an existing property set + { "Delete", PyIPropertySetStorage::Delete, 1 }, // @pymeth Delete|Removes a property set from this storage object + { "Enum", PyIPropertySetStorage::Enum, 1 }, // @pymeth Enum|Creates an iterator to enumerate contained property sets { NULL } }; diff -r d6adf5a1b26e -r cb8d7cb7982e com/win32com/src/extensions/PyIPropertyStorage.cpp --- a/com/win32com/src/extensions/PyIPropertyStorage.cpp Mon Aug 20 19:51:40 2012 -0400 +++ b/com/win32com/src/extensions/PyIPropertyStorage.cpp Tue Aug 21 21:32:33 2012 -0400 @@ -10,67 +10,49 @@ // @doc - This file contains autoduck documentation // --------------------------------------------------- +void PyObject_FreePROPSPECs(PROPSPEC *pFree, ULONG cFree) +{ + if (!pFree) + return; + for (ULONG i=0; i<cFree; i++) + if (pFree[i].ulKind == PRSPEC_LPWSTR && pFree[i].lpwstr) + PyWinObject_FreeWCHAR(pFree[i].lpwstr); + free(pFree); +} + // @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); + TmpPyObject tuple=PyWinSequence_Tuple(ob, pcRet); 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 = 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; + } + } } - } - 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; -} - -void PyObject_FreePROPSPECs(PROPSPEC *pFree, ULONG /*cFree*/) -{ - if (pFree) - free(pFree); + return TRUE; } // Generic conversion from VT_VECTOR arrays to list. @@ -428,7 +410,8 @@ return (IPropertyStorage *)PyIUnknown::GetI(self); } -// @pymethod |PyIPropertyStorage|ReadMultiple|Reads specified properties from the current property set. +// @pymethod (object, ...)|PyIPropertyStorage|ReadMultiple|Reads specified properties from the current property set. |