Reputation: 812
I'm trying to make an application compatible with the auto proxy API provided by the WinINet library in order to make local pac files work, and am stuck with the error ERROR_CAN_NOT_COMPLETE when trying to call InternetGetProxyInfo...
I have been following the post of Eric Loewenthal (dev @Microsoft so I hope his suggestion are A-OK ;p) in here and the idea should be:
Here is how my code looks like :
// Start by initializing the Auto proxy stuff
BOOL ok = InternetInitializeAutoProxyDll(0, pathToTheProxyPACFile,
NULL, NULL, NULL);
// Here ok is true so I consider the initialization was a success
// [...]
// Later on, I try to get the proxy used for each requested URL like this:
LPSTR proxyURL = NULL;
DWORD proxyURLLength = 0;
BOOL ok = InternetGetProxyInfo(requestedURL,
requestedURLLength,
hostName,
hostNameLength,
&proxyURL,
&proxyURLLength);
// Here ok is false, the proxy url and length are left as is,
// and a call to GetLastError() returns 1003 :s
I can't see what's wrong with that, and couldn't find any convincing example on the net (and the documentation is severely lacking...).
Please note I tried allocating a buffer for proxyURL and setting its size to proxyURLLength as the documentation isn't clear about how the memory should be handled, but it doesn't work and my understanding is that I should let WinINet handle it anyway, and use GlobalFree on proxyURL in case of success.
I have also tried using InternetCrackUrlA in order to get the host name just in case the class I use to get the host name from the requested URL was not ok with this API (and indeed, InternetCrackUrlA considers the port to be part of the host name...), but it didn't help either.
Please let me know of any suggestion that might help me get this to work ;)
PS: I have been using WinHTTP to do the same thing in the same part of the code and it works correctly. PPS: I am testing this on windows XP with IE8 installed.
Edit ==========> I have coded another program that only calls these functions, and in this case I don't experience any problem, so I guess my problem comes not from the way I call InternetGetProxyInfo but from the state I'm in when I call it, that is within an implementation of the event sink used for our embedded IE, unless there is a problem with my includes or something along those lines..?
Upvotes: 1
Views: 3084
Reputation: 812
After making sure it works on a new project, I traced the cause of my problem and the call to get the proxy infos starts failing after a call to OleInitialize. Now, there was a comment about it in here, but I didn't know what this guy was talking about (and God knows I wish I never knew) so it didn't help me back then I first read it.
In short, if you initialize COM with OleInitialize, you'll have a "Single-Thread Apartment" thread and that implies InternetGetProxyInfo will fail with cryptic error ERROR_CAN_NOT_COMPLETE. The solution I used was to make another thread do the work.
PS about the signature of InternetGetProxyInfo:
it seems the last two parameters should be set to NULL and 0 as I expected, and GlobalFree should be called on the string to free its memory if necessary.
the host name and host name length are optional.
Thanks for your help :)
Upvotes: 1
Reputation: 19
WinHTTP is not supposed to be a better WinINet, to cite [MSDN][1]:
Microsoft Windows HTTP Services (WinHTTP) is targeted at middle-tier and back-end server applications that require access to an HTTP client stack. Microsoft Windows Internet (WinINet) provides an HTTP client stack for client applications, as well as access to the File Transfer Protocol (FTP), SOCKSv4, and Gopher protocols. http://msdn.microsoft.com/en-us/library/windows/desktop/aa384068(v=vs.85).aspx
If you really want to use WinHTTP, you can definitely get it working when loading the "jsproxy.dll" dynamically and then use the InternetGetProxyInfo from this dynamically loaded DLL as described here.
To completely support the parsing of complex PAC files though, you will have to implement all (or at least most) of the "Auto Proxy Callback functions and pass the array of function pointer to the InternetInitializeAutoProxyDll function of the dynamically loaded DLL.
On top of that, note that you will have to handle parts of the challenge/response processing for proxy authentication (except "domain proxies") as WinHTTP will not automatically handle the 407 proxy password challenge and pick the best authentication scheme as WinINet does. That's quite a bit of manual work coming up as well.
All this is a considerable effort I'd only go through if I really cannot use WinINet.
Upvotes: 1