I am trying to extend the azure WinHttpRequest python binding to be able to modify the request options. Ideally, I'd simply like to set the global options through winhttp.dll WinHttpSetOptions function, but I can't quite figure out how to do that. Anyway, I decided to venture on this approach, but am getting a "NULL COM pointer access" error. Is it something to do with the invalid ordinal I have assigned to the _put_Option declaration? i.e. the (30, 'put_Option')
or is it simply that the symbol can't be found? I am using the IWinHttpRequest documentation for guidance:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa383998(v=vs.85).aspx
class _WinHttpRequestOption(object):
MaxResponseHeaderSize = 15
class _WinHttpRequestExtension(_WinHttpRequest):
_put_Option = WINFUNCTYPE(HRESULT, c_int, VARIANT)(30, 'put_Option')
def _SetOption(self, name, value):
logging.getLogger(self.__class__.__name__).debug(
"SetOption %s = %s" % (name, value)
)
enum_name = getattr(_WinHttpRequestOption, name)
var_value = VARIANT()
var_value.vt = VT_I4
var_value.vdata.lval = long(value)
_WinHttpRequestExtension._put_Option(self, enum_name, var_value)
Oh yeah, the code that sets the property:
http_request = _WinHttpRequestExtension()
http_request._SetOption("MaxResponseHeaderSize", 128 * 1024)
Update:
Found this link:
It defined a dispatch ID for the function. Since I am no Windows developer, I have no idea what a dispatch ID is. Although replacing my ordinal with this still doesn't work.
#define DISPID_HTTPREQUEST_BASE 0x00000001
#define DISPID_HTTPREQUEST_OPTION (DISPID_HTTPREQUEST_BASE + 5)
_put_Option = WINFUNCTYPE(HRESULT, c_int, VARIANT)(6, 'Option')
Also
I found this, which would indicate self
is not a reference to the correct thing. Look at the COM error in this code. if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
#ifdef MS_WIN32
if (self->index) {
/* It's a COM method */
CDataObject *this;
this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
if (!this) {
PyErr_SetString(PyExc_ValueError,
"native com method call without 'this' parameter");
return NULL;
}
if (!CDataObject_Check(this)) {
PyErr_SetString(PyExc_TypeError,
"Expected a COM this pointer as first argument");
return NULL;
}
/* there should be more checks? No, in Python */
/* First arg is an pointer to an interface instance */
if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
PyErr_SetString(PyExc_ValueError,
"NULL COM pointer access");
return NULL;
}
I can get the "Expected a COM this pointer as first argument"
error if I do this:
_WinHttpRequestExtension._put_Option(super(_WinHttpRequestExtension, self), enum_name, var_value)
Finally figured out that I was accessing methods on the object before it had been CoInitialised()
. Moving the calls beyond the call to CoInitialise seems to have got me further, but now I get the error:
ValueError: Procedure probably called with too many arguments (16 bytes in excess)