SAMPLE: Calling WinVerifyTrust and Authenticating Files

Last reviewed: January 19, 1998
Article ID: Q165021
The information in this article applies to:
  • Microsoft ActiveX SDK, version 1.0
  • Microsoft Internet Client SDK, versions 4.0, 4.01
  • Internet Explorer (Programming), versions 4.0, 4.01

SUMMARY

This sample demonstrates how to programmatically authenticate files using the WinVerifyTrust function. This allows a programmer to verify whether a file is signed and allows a user to trust or not trust the signing authority.

The following file is available for download from the Microsoft Software Library:

 ~ VFiles.exe (size: 57247 bytes) 

For more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q119591
   TITLE     : How to Obtain Microsoft Support Files from Online Services

MORE INFORMATION

This sample is written with visual C++ 4.2b and requires the supporting MFC DLLs.

If you do not want to install and run the sample, the following function is all that you really need to illustrate how to call the WinVerifyTrust function. If you are not using MFC, you need to substitute several small details (CString, method of obtaining file name, etc.) with code appropriate to your framework.

   #include <afxpriv.h> // Needed for CONVERSION macros.

   void CGetHttpFileView::OnGitAndVerify()
   {
       USES_CONVERSION;

       CString message;

       typedef HRESULT
           (WINAPI *WINVERIFYTRUST)
               (HWND hwnd, GUID *ActionID, LPVOID ActionData);

       #define WINTRUST "wintrust.dll"

       WINVERIFYTRUST pwvt = NULL;
       HINSTANCE hinst;

       // Load wintrust.dll and locate the WinVerifyTrust function.

       if(hinst = LoadLibrary(WINTRUST))
           pwvt = (WINVERIFYTRUST)GetProcAddress(hinst,
   _T("WinVerifyTrust"));
       else
           return;

       if(NULL == pwvt)
       {
           FreeLibrary(hinst);
           return;
       }

       // Get the name of the file (m_strHttpFile) to test from the dialog
       // box.
       UpdateData(TRUE);

       TCHAR lpFileName[MAX_PATH];

       m_ctlStatusEdit.SetWindowText(_T("Loading File"));

       // It would make sense to put a Cancel button on the form to abort
       // long downloads. In fact, URLDownloadToCacheFile is a blocking
       // call so the button would be dead until the download is complete.

       // It is not necessary to use URLDownloadToCacheFile to
       // download the file.

       HRESULT hr = URLDownloadToCacheFile(NULL, m_strHttpFile,
         lpFileName, MAX_PATH, 0, m_pBindStatusCallback);

       if(FAILED(hr))
       {
           message.Format("Failed to Locate file.  Error: %X", hr);
           m_ctlStatusEdit.SetWindowText(message);
           FreeLibrary(hinst);
           return;
       }

       // Now verify the file.

       // For now, it is necessary to define this.
       #define WIN_SPUB_ACTION_PUBLISHED_SOFTWARE_NOBADUI         {
   0xc6b2e8d0, 0xe005, 0x11cf,             { 0xa1, 0x34, 0x0, 0xc0, 0x4f,
   0xd7, 0xbf, 0x43 } }

       GUID PublishedSoftware =
               WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
       GUID PublishedSoftwareNoBadUI =
               WIN_SPUB_ACTION_PUBLISHED_SOFTWARE_NOBADUI;

       // See winbase.h for available Subject Type Identifiers.
       GUID SubjectPeImage = WIN_TRUST_SUBJTYPE_PE_IMAGE;
       GUID SubjectCAB      = WIN_TRUST_SUBJTYPE_CABINET;
       GUID SubjectJava    = WIN_TRUST_SUBJTYPE_JAVA_CLASS;

       GUID * ActionGUID;

       if(0 == m_nUIOnBadVerification)
           ActionGUID = &PublishedSoftware;
       else
           ActionGUID = &PublishedSoftwareNoBadUI;

       WIN_TRUST_SUBJECT_FILE Subject;

       Subject.lpPath = T2OLE(lpFileName);
       // If hFile is set to the value INVALID_HANDLE_VALUE (defined in
       // WINBASE.H), then the trust provider will open the subject using
       // the lpPath field.
       Subject.hFile = INVALID_HANDLE_VALUE;

       // For now, WIN_TRUST_ACTDATA_SUBJECT_ONLY is not used.
       WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT ActionData;

       ActionData.Subject = &Subject;
       ActionData.hClientToken = NULL;

       switch(m_nFileType)
       {
       case 0:
           ActionData.SubjectType = &SubjectPeImage;
           break;
       case 1:
           ActionData.SubjectType = &SubjectJava;
           break;
       case 2:
           ActionData.SubjectType = &SubjectCAB;
       }

       hr =  pwvt( 0, ActionGUID, &ActionData);

       // hr will tell you if the user accepted the certificate.
       // return codes include S_OK (user accepted),
       // TRUST_E_NOSIGNATURE (no certificate at all -- includes test
       // certificates!), etc.

       message.Format("WinVerifyTrust Returned Error: %X", hr);
       m_ctlStatusEdit.SetWindowText(message);

       FreeLibrary(hinst);
       return;
   }

(c) Microsoft Corporation 1996, All Rights Reserved. Contributions by Robert Duke, Microsoft Corporation


Additional query words: URLDownloadToCacheFile
WIN_SPUB_ACTION_PUBLISHED_SOFTWARE_NOBADUI wintrust.dll
Keywords : AXSDKCodeSign kbprg kbsample
Version : Win:1.0,4.01
Platform : WINDOWS
Solution Type : kbfile


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: January 19, 1998
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.