WinINet InternetGetProxyInfo:错误 1003 ERROR_CAN_NOT_COMPLETE

发布于 2024-12-11 04:43:47 字数 2070 浏览 0 评论 0原文

我正在尝试使应用程序与 WinINet 库提供的自动代理 API 兼容,以便使本地 pac 文件正常工作,并且尝试调用 InternetGetProxyInfo 时遇到错误 ERROR_CAN_NOT_COMPLETE...

我一直在关注 Eric Loewenthal 的帖子(dev @Microsoft,所以我希望他的建议是 A-OK ;p) 在此处 思路应该是:

  • 调用InternetInitializeAutoProxyDll函数;
  • 调用 InternetGetProxyInfo 获取每个给定请求 URL 的代理 URL;
  • 最后调用 InternetDeInitializeAutoProxyDll。

这是我的代码的样子:

// 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

我看不出有什么问题,并且在网上找不到任何令人信服的示例(并且文档严重缺乏......)。

请注意,我尝试为 proxyURL 分配一个缓冲区并将其大小设置为 proxyURLLength,因为文档不清楚如何处理内存,但它不起作用,我的理解是我应该让 WinINet 处理它,并且如果成功,请在 proxyURL 上使用 GlobalFree。

我还尝试使用 InternetCrackUrlA 来获取主机名,以防万一我用来从请求的 URL 获取主机名的类不能使用此 API(事实上,InternetCrackUrlA 认为端口是主机名的一部分) ...),但这也没有帮助。

请让我知道任何可能帮助我让它工作的建议;)

PS:我一直在使用 WinHTTP 在代码的同一部分做同样的事情,并且它工作正常。 PPS:我正在安装了 IE8 的 Windows XP 上进行测试。

编辑==========>我编写了另一个仅调用这些函数的程序,在这种情况下我没有遇到任何问题,所以我想我的问题不是来自我调用 InternetGetProxyInfo 的方式,而是来自我调用它时所处的状态,即是在 用于我们嵌入式 IE 的事件接收器的实现,除非我的包含内容有问题或类似的问题..?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

秉烛思 2024-12-18 04:43:47

WinHTTP 不应该是更好的 WinINet,引用 [MSDN][1]:

Microsoft Windows HTTP 服务 (WinHTTP) 面向需要访问 HTTP 客户端堆栈的中间层和后端服务器应用程序。 Microsoft Windows Internet (WinINet) 为客户端应用程序提供 HTTP 客户端堆栈,以及对文件传输协议 (FTP)、SOCKSv4 和 Gopher 协议的访问。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384068(v=vs.85).aspx

如果你真的想使用WinHTTP,你绝对可以得到它动态加载“jsproxy.dll”时工作,然后使用此动态加载的 DLL 中的 InternetGetProxyInfo,如所述 此处。

不过,为了完全支持复杂 PAC 文件的解析,您必须实现所有(或至少大部分)“自动代理回调函数”并将函数指针数组传递给 InternetInitializeAutoProxyDll 动态加载 DLL 的函数。

最重要的是,请注意,您必须处理代理身份验证的部分质询/响应处理(“域代理”除外),因为 WinHTTP 不会自动处理407 代理密码质询并像 WinINet 一样选择最佳身份验证方案 这

也是相当多的手动工作,只有当我真的无法使用 WinINet 时,我才会经历这些工作。

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.

ˉ厌 2024-12-18 04:43:47

确保它适用于新项目后,我追踪了问题的原因,并且在调用 OleInitialize 后,获取代理信息的调用开始失败。现在,这里有一条关于它的评论< /a>,但我不知道这家伙在说什么(上帝知道我希望我永远不知道),所以当我第一次读到它时它对我没有帮助。

简而言之,如果您使用 OleInitialize 初始化 COM,您将拥有一个“单线程单元”线程,这意味着 InternetGetProxyInfo 将失败并出现神秘错误 ERROR_CAN_NOT_COMPLETE。我使用的解决方案是让另一个线程来完成这项工作。

PS 关于 InternetGetProxyInfo 的签名:

  • 似乎最后两个参数应该按照我的预期设置为 NULL 和 0,并且如果需要,应该在字符串上调用 GlobalFree 以释放其内存。

  • 主机名和主机名长度是可选的。

感谢您的帮助 :)

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文