简体   繁体   English

如何以编程方式清除WinInet SSL状态(是否有Windows API调用)?

[英]How to clear WinInet SSL state programmatically (is there a Windows API call)?

I need to mimic the same behavior as the "Clear SSL State" button in the "Internet Options" dialog ("Contents" tab) using an API function in Delphi. 我需要使用Delphi中的API函数模仿与“ Internet选项”对话框(“目录”选项卡)中的“清除SSL状态”按钮相同的行为。

My intention is to use this with WinInet to make subsequent independent SSL connections. 我的目的是将其与WinInet一起使用以建立后续的独立SSL连接。 Without this, two WinInet connections share the same SSL state, preventing me from correcting a wrong SSL certificate password, for example. 没有此,两个WinInet连接共享相同的SSL状态,例如,阻止我纠正错误的SSL证书密码。

Without clearing the SSL state between two connection attempts, the first one returns "wrong password", then I correct the password and try again, but the second attempt returns "Secure Channel Support Error". 在两次连接尝试之间未清除SSL状态的情况下,第一个返回“密码错误”,然后我更正密码并重试,但是第二次尝试返回“安全通道支持错误”。

The "Clear SSL State" button simply executes the following undocumented command-line command: “清除SSL状态”按钮仅执行以下未记录的命令行命令:

"C:\Windows\system32\rundll32.exe" "C:\Windows\system32\WININET.dll",DispatchAPICall 3

Use CreateProcess() to execute the same command in your Delphi code. 使用CreateProcess()在您的Delphi代码中执行相同的命令。

You're right: if rundll can do it, you can do it programmatically: 您是对的:如果rundll可以做到,则可以通过编程方式做到:

//somewhere in an interface section:
procedure DispatchAPICall(h: HWND; hinst: HINST; lpszCmdLine: PAnsiChar; nCmdShow: integer); stdcall;

//somewhere in the implementation section:
function DispatchAPICall; external 'wininet.dll';

//somewhere in your code:
DispatchAPICall(GetDesktopWindow(), GetModuleHandle('wininet.dll'), '3', SW_NORMAL);

Finally! 最后! I achieved! 我实现了!

I used the excellent API Monitor , to monitor the whole Internet Options dialog and I managed to discover what the "Clear SSL State" button do. 我使用了出色的API Monitor来监视整个“ Internet选项”对话框,并且设法找到“清除SSL状态”按钮的功能。 It executes only two API calls SslEmptyCache and IncrementUrlCacheHeaderData , in that order. 它仅按此顺序执行两个API调用SslEmptyCacheIncrementUrlCacheHeaderData

API监视器,在“清除SSL状态”按钮下方显示两个API调用

After discover this I was able to implement the following code, executed BEFORE my request: 发现这一点后,我得以实现以下代码,并在请求之前执行了该代码:

type
    TSslEmptyCache = function (pszTargetName: LPSTR; dwFlags: DWORD): BOOL; WINAPI;
    TIncrementUrlCacheHeaderData = function (nIdx: DWORD; lpdwData: LPDWORD): BOOL; WINAPI;

var
    SchannelDLLHandle, WinInetHandle: HMODULE;
    SslEmptyCache: TSslEmptyCache;
    IncrementUrlCacheHeaderData: TIncrementUrlCacheHeaderData;

SchannelDLLHandle := LoadLibrary('schannel.dll');
WinInetHandle := LoadLibrary('wininet.dll');

if (SchannelDLLHandle > 0) and (WinInetHandle > 0) then
    try
        SslEmptyCache := GetProcAddress(SchannelDLLHandle,'SslEmptyCacheW');
        IncrementUrlCacheHeaderData := GetProcAddress(WinInetHandle,'IncrementUrlCacheHeaderData');

        if Assigned(SslEmptyCache) and Assigned(IncrementUrlCacheHeaderData) then
        begin
            SslEmptyCache(nil,0);
            IncrementUrlCacheHeaderData(14,@buffer);
        end;
    finally
        FreeLibrary(SchannelDLLHandle);
        FreeLibrary(WinInetHandle);
    end;

Of course, this is a pseudo code, but It is complete ;) 当然,这是一个伪代码,但这是完整的;)

The SslEmptyCache function has documentation at MSDN, but the IncrementUrlCacheHeaderData function not, so I had to research a little more to discover that the second paramenter must be a PDWORD, wich receives, when the function returns, an increment number, wich is persistent between calls at different processes (different applications). SslEmptyCache函数在MSDN上有文档,但是IncrementUrlCacheHeaderData函数没有文档,因此我不得不多做一些研究,以发现第二个参数必须是PDWORD,该函数返回时,它会接收一个增量数,在两次调用之间,该函数是持久的。在不同的过程中(不同的应用程序)。

For more information you can access this article where I explain all my saga. 有关更多信息,您可以在我解释我所有传奇的地方访问本文 The text is in portuguese, but the site have a good translatin tool. 文字为葡萄牙语,但该网站提供了不错的翻译工具。

I wish to thank you all for the help 我要感谢大家的帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM