title: What is the difference between WinVerifyTrust() and WinVerifyTrustEx()?
body: <p>MSDN documents the <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa388208(v=vs.85).aspx" rel="nofollow noreferrer"><code>WinVerifyTrust()</code></a> and <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa388209(v=vs.85).aspx" rel="nofollow noreferrer"><code>WinVerifyTrustEx()</code></a> functions, and it isn't very clear what the difference between them is.</p>
  
  <p>The function signatures are the same except for the last parameter:</p>
  
  <pre class="lang-c prettyprint-override"><code>LONG WINAPI WinVerifyTrust(
    _In_ HWND   hWnd,
    _In_ GUID   *pgActionID,
    _In_ LPVOID pWVTData
  );
  </code></pre>
  
  <pre class="lang-c prettyprint-override"><code>HRESULT WinVerifyTrustEx(
    _In_ HWND          hwnd,
    _In_ GUID          *pgActionID,
    _In_ WINTRUST_DATA *pWinTrustData
  );
  </code></pre>
  
  <p>However, the <code>LPVOID pWVTData</code> parameter to <code>WinVerifyTrust()</code> is actually a <code>WINTRUST_DATA*</code> just like the  <code>WinVerifyTrustEx()</code>:</p>
  
  <blockquote>
    <p><em>pWVTData</em> [in]<br>
    A pointer that, when cast as a WINTRUST_DATA structure, contains information that the trust provider needs to process the specified action identifier.</p>
  </blockquote>
  
  <p>I diffed the two documentation pages to look for any other differences, and here's what I found, omitting trivial differences:</p>
  
  <p><code>WinVerifyTrust()</code>:</p>
  
  <blockquote>
    <p>If the trust provider does not verify that the subject is trusted for the specified action, the function returns a status code from the trust provider.
    Note  The return value is a LONG, not an HRESULT as previously documented. Do not use HRESULT macros such as SUCCEEDED to determine whether the function succeeded. Instead, check the return value for equality to zero.</p>
    
    <p>Remarks</p>
    
    <p>The WinVerifyTrust function enables applications to invoke a trust provider to verify that a specified object satisfies the criteria of a specified verification operation. The pgActionID parameter identifies the verification operation, and the pWinTrustData parameter identifies the object whose trust is to be verified. A trust provider is a DLL registered with the operating system. A call to WinVerifyTrust forwards that call to the registered trust provider, if there is one, that supports that specified action identifier.<br>
    For example, the Software Publisher Trust Provider can verify that an executable image file comes from a trusted software publisher and that the file has not been modified since it was published. In this case, the pWinTrustData parameter specifies the name of the file and the type of file, such as a Microsoft Portable Executable image file.<br>
    Each trust provider supports a specific set of actions that it can evaluate. Each action has a GUID that identifies it. A trust provider can support any number of action identifiers, but two trust providers cannot support the same action identifier.<br>
    For an example that demonstrates how to use this function to verify the signature of a portable executable (PE) file, see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa382384(v=vs.85).aspx" rel="nofollow noreferrer">Example C Program: Verifying the Signature of a PE File</a>.</p>
  </blockquote>
  
  <p><code>WinVerifyTrustEx()</code>:</p>
  
  <blockquote>
    <p>This function has no associated import library. You must use the LoadLibrary and GetProcAddress functions to dynamically link to Wintrust.dll.</p>
    
    <p>WINTRUST_ACTION_GENERIC_CERT_VERIFY<br>
    Verify a certificate chain only. This is only valid when passing in a certificate context in the WinVerifyTrust input structures.<br>
    Note: We do not recommend using this function to perform certificate verification. To perform certificate verification, use the CertGetCertificateChain and CertVerifyCertificateChainPolicy functions.</p>
    
    <p>If the trust provider verifies that the subject is trusted for the specified action, the return value is ERROR_SUCCESS. Otherwise, the function returns a status code from the trust provider.</p>
  </blockquote>
  
  <p>As a test, I took the example program listed for <code>WinVerifyTrust()</code> and changed it to use <code>WinVerifyTrustEx()</code> instead. It gives identical results with either API call.</p>
  
  <p>If anyone is familiar with these two functions and knows what is really different between them, any insights would be appreciated!</p>