1

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:

  • Call the InternetInitializeAutoProxyDll function;
  • Call the InternetGetProxyInfo to get the proxy URL for each given requested URLs;
  • Call the InternetDeInitializeAutoProxyDll at the end.

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..?

Shautieh
  • 746
  • 10
  • 17
  • Are you seeing the same thing as I am => "This is not supported."? I stumbled into several pages like this, but I think this is because the documentation is severely lacking on msdn, not because the feature is really not supported :) – Shautieh Oct 21 '11 at 12:17
  • Oh... Do you know of another way to get local proxy pac files to work? Because the MSDN says it doesn't work with WinHTTP (which is supposed to be a better WinINet but can't work with local paths at all >_>). IE can work with local pac files so there should be something available!? Though I thought it used WinINet... – Shautieh Oct 21 '11 at 12:41

2 Answers2

1

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.

fredley
  • 32,953
  • 42
  • 145
  • 236
Oliver M
  • 19
  • 1
  • Thanks for your answer, but I'm not sure I understand it all : I have been using WinHTTP to handle the pac files, and it works quite simply with the FindProxyForURL function (see http://msdn.microsoft.com/en-us/library/windows/desktop/aa384240(v=vs.85).aspx). My problem with WinHTTP is that it doesn't work for local addresses (as stated on the previous link, "WinHTTP supports only "http:" and "https:" PAC URLs; it does not, for example, support "file:" URLS.", so my only other option as far as I know is to use **WinINet**, and thus to use InternetGetProxyInfo with jsproxy.dll, which fails :s – Shautieh Oct 22 '11 at 11:53
  • 1
    This answer is what made me take notice of the real differences between WinHTTP and WinINet. Thanks! http://msdn.microsoft.com/en-us/library/windows/desktop/hh227298(v=vs.85).aspx says, "With a few exceptions, WinINet is a superset of WinHTTP. When selecting between the two, you should use WinINet, unless you plan to run within a service or service-like process that requires impersonation and session isolation." – Kevin Condon Apr 26 '12 at 18:52
1

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

Shautieh
  • 746
  • 10
  • 17
  • 1
    Actually the host name and host name length are not optional. Or to be exact they are optional on XP but required on Win7. Otherwise I got a dreadful ERROR_CAN_NOT_COMPLETE – SparcU Sep 06 '12 at 07:01