4

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:

https://chromium.googlesource.com/chromium/deps/perl/+/master%5E/c/i686-w64-mingw32/include/httprequestid.h

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)
0

1 Answer 1

1

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)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.