Nearly aquired line-in name

Skip to first unread message

Feb 23, 2005, 8:01:18 PM2/23/05
Hi all. Not sure how many people read this, but I'm working my way
through figuring out the UPnP API for Sonos. It's pretty slow as I'm
learning C as I go, but I think I have finally sorted out the majority
of my C problems and are now running into Sonos problems.

Well, what I mean to say is that finally I have a program that compiles
(no small feat for me), that connects to a ZonePlayer, and that even
makes a request (sheesh, that took me ages.) I'm just not getting the
desired response. To be specific: UPnP error 401. Which I believe means
"invalid action".

I assume my POST request for information, stored in XML format, is
incorrect. Here is the data I am sending:

char *PostData =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
" <s:Envelope
" <s:Body>\n"
" <u:GetAudioInputName
xmlns:u=\"urn:schemas-upnp-org:service:AudioIn:1\" />\n"
" </s:Body>\n"

Here is the relevant parts of my code:

// Specify an HTTP server.
if( hSession )
hConnect = WinHttpConnect( hSession, L"",
1400, 0 );

// Create an HTTP request handle.
if( hConnect )
hRequest = WinHttpOpenRequest( hConnect, L"POST",

// Send a request.
if( hRequest )
bResults = WinHttpSendRequest( hRequest,
PostData, 0,
0, 0 );

Anyway... from looking at the output of DeviceSpy, it looks like I may
need to include:
SOAPACTION: "urn:schemas-upnp-org:service:AudioIn:1#GetAudioInputName"
Where do I put this? Is this what's causing my 401 error? Has anyone
else enocountered it?

Steve Eisner

Feb 23, 2005, 8:21:09 PM2/23/05
Yep, you need to add the "Soapaction:___" to your request headers...
You'll need to use WinHttpAddRequestHeaders:

or change the "pwszHeaders" from its current value of


Feb 23, 2005, 9:09:44 PM2/23/05
When I change the WINHTTP_NO_ADDITIONAL_HEADERS value, I get
"assignment of pointer to const unsigned short to pointer to char"
(ugh. that is a horrible error.) Here's how I'm implementing it:

char *ExtraHeader = "SOAPACTION:

And the HTTP request.... (which is the line the error points to)

WinHttpSendRequest( hRequest, ExtraHeader, 256, PostData, 0, 0, 0 );

I put 256 as the length just so it'd have a bit of padding. I guess
I'll have to figure out how to dynamically figure this out later.

Steve Eisner

Feb 23, 2005, 9:51:31 PM2/23/05
Sounds to me like the error is trying to tell you that the char * you
passed in is of 8-bit characters and it's expecting 16-bit, or maybe
vice versa? :) an "unsigned short" is basically a 16-bit number, and
a "char" is 8-bit.

Unfortunately I've never used the WinHttp library so I don't have a
good answer for you.

Here are some google posts that might be relevant,GGLD:2004-22,GGLD:en%26sa%3DN%26tab%3Dwg%26&_doneTitle=Back+to+Search&&d#d4b9dcd583cb7d2b
(hints that maybe the string should be an L" " string?)
(more posts about WinHttpSendRequest)

Feb 25, 2005, 2:59:36 PM2/25/05
Hmm. Changing this line:

char *ExtraHeader = "SOAPACTION:
seems to fix it - I just added the word "unsigned" at the start.

Now I'm back to getting Error 87, which I think is due to an incorrect
string lenth being specified to WinHttpSendRequest. I'm trying to
calculate lengths with:
char PostLength = lstrlen(PostData)*sizeof(TCHAR);
but for some reason that gives me a length of 18, when my XML code to
be POST'd is waay longer (like 200 at a guess.) Can that method handle
escape characters? And seperate lines?

Feb 25, 2005, 4:07:10 PM2/25/05
OK I think I've broken it down some more.

Here's what I need to have in my WinHttpSendRequest statement (from the
[in] A pointer to a string that contains the additional headers to
append to the request. This parameter can be
WINHTTP_NO_ADDITIONAL_HEADERS if there are no additional headers to

It seems the POST data is a "pointer to a buffer" (char *postdata =
"post data"; works) but the headers are a "pointer to a string". I
don't know how to make a pointer to a string. God only knows why they
aren't BOTH a "pointer to a buffer". I guess I'll start googling...

Steve Eisner

Feb 25, 2005, 4:36:45 PM2/25/05
It's not too hard to make a pointer to a string (it's just a "char **")
so char *s = "string"
char **p = &s;
but are you sure they really want a "pointer to a string" or is that
just confusing terminology which really means "a string (which is a

I wish I could help more with the lstrlen issue but I left the C++
world before there was any concern about strs vs. lstrs etc. In Java
and C# all strings are unicode so there's no such distinction...

Reply all
Reply to author
0 new messages