unit TrustCheckMod;
 
interface
 
function FileIsTrusted(const sFilename: string): Boolean;
 
implementation
 
uses
  Windows, SysUtils;
 
const
  
  WTD_CHOICE_FILE = 1;
  WTD_CHOICE_CATALOG = 2;
 
  
  WTD_STATEACTION_IGNORE = 0;
  WTD_STATEACTION_VERIFY = 1;
 
  
  WTD_UI_NONE = 2; 
 
  
  WTD_REVOKE_NONE = 0; 
 
  
  WTD_SAFER_FLAG = 256; 
 
  
  WINTRUST_ACTION_GENERIC_VERIFY_V2: TGUID = '{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}';
 
type
 
  CATALOG_INFO = record
    cbStruct: DWORD; 
    sCatalogFile: array[0..MAX_PATH] of WCHAR; 
  end;
  PCATALOG_INFO = ^CATALOG_INFO;
 
  WINTRUST_CATALOG_INFO = record
    cbStruct: DWORD; 
    dwCatalogVersion: DWORD; 
    pcwszCatalogFilePath: LPCWSTR; 
    pcwszMemberTag: LPCWSTR; 
    pcwszMemberFilePath: LPCWSTR; 
    hMemberFile: THANDLE; 
  end;
  PWINTRUST_CATALOG_INFO = ^WINTRUST_CATALOG_INFO;
 
  WINTRUST_FILE_INFO = record
    cbStruct: DWORD; 
    pcwszFilePath: LPCWSTR; 
    pgKnownSubject: PGUID; 
    hFile: THANDLE; 
  end;
  PWINTRUST_FILE_INFO = ^WINTRUST_FILE_INFO;
 
  WINTRUST_DATA = packed record
    cbStruct: DWORD; 
    pPolicyCallbackData: pointer; 
    pSIPClientData: pointer; 
    dwUIChoice: DWORD; 
    fdwRevocationChecks: DWORD; 
    dwUnionChoice: DWORD; 
    pWTDINFO: pointer; 
    pFake: pointer; 
    pFake1: pointer; 
    pFake2: pointer; 
    pFake3: pointer; 
    dwStateAction: DWORD;
    hWVTStateData: THANDLE;
    pwszURLReference: PWChar;
    dwProvFlags: DWORD;
    dwUIContext: DWORD;
 
  end;
  PWINTRUST_DATA = ^WINTRUST_DATA;
 
  
  HCatAdmin = THANDLE;
  PHCatAdmin = ^HCatAdmin;
 
var
  hLibWintrust: THANDLE;
 
  
  CryptCATAdminAcquireContext: function(PHCatAdmin: PHCatAdmin; pgSubsystem: PGUID; dwFlags: DWORD): BOOL; stdcall;
  CryptCATAdminReleaseContext: function(HCatAdmin: HCatAdmin; dwFlags: DWORD): BOOL; stdcall;
  CryptCATAdminCalcHashFromFileHandle: function(hFile: THANDLE; pHashSize: PDWORD; pbHash: PByteArray; dwFlags: DWORD): BOOL; stdcall;
  CryptCATAdminEnumCatalogFromHash: function(HCatAdmin: HCatAdmin; pbHash: PByteArray; pHashSize: DWORD; dwFlags: DWORD; phPrevCatInfo: PHandle): THANDLE; stdcall;
  CryptCATCatalogInfoFromContext: function(hCatInfo: THANDLE; psCatInfo: PCATALOG_INFO; dwFlags: DWORD): BOOL; stdcall;
  CryptCATAdminReleaseCatalogContext: function(HCatAdmin: HCatAdmin; hCatInfo: THANDLE; dwFlags: DWORD): BOOL; stdcall;
  WinVerifyTrust: function(hwnd: THANDLE; pgActionID: PGUID; pWintrustData: PWINTRUST_DATA): Longint; stdcall;
 
function FileIsTrusted(const sFilename: string): Boolean;
var
  
  aByteHash: array[0..255] of Byte;
  iByteCount: Integer;
  hCatAdminContext: HCatAdmin;
  WTrustData: WINTRUST_DATA;
  WTDCatalogInfo: WINTRUST_CATALOG_INFO;
  WTDFileInfo: WINTRUST_FILE_INFO;
  CatalogInfo: CATALOG_INFO;
  hFile: THANDLE;
  hCatalogContext: THANDLE;
  swFilename: WideString;
  swMemberTag: WideString;
  ilRet: Longint;
  x: Integer;
begin
  
  Result := False;
  
  if FileExists(sFilename) = False then Exit;
  
  swFilename := sFilename;
  ZeroMemory(@CatalogInfo, SizeOf(CatalogInfo));
  ZeroMemory(@WTDFileInfo, SizeOf(WTDFileInfo));
  ZeroMemory(@WTDCatalogInfo, SizeOf(WTDCatalogInfo));
  ZeroMemory(@WTrustData, SizeOf(WTrustData));
  
  if CryptCATAdminAcquireContext(@hCatAdminContext, nil, 0) = False then Exit;
  
  hFile := CreateFile(PChar(string(sFilename)), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  
  if hFile = INVALID_HANDLE_VALUE then Exit;
  
  iByteCount := SizeOf(aByteHash);
  
  CryptCATAdminCalcHashFromFileHandle(hFile, @iByteCount, @aByteHash, 0);
  
  for x := 0 to iByteCount - 1 do
  begin
    swMemberTag := swMemberTag + IntToHex(aByteHash[x], 2);
  end;
  
  CloseHandle(hFile);
  
  
  
  
  hCatalogContext := CryptCATAdminEnumCatalogFromHash(hCatAdminContext, @aByteHash, iByteCount, 0, nil);
  
  
  if hCatalogContext = 0 then
  begin
    
    
    
    WTDFileInfo.cbStruct := SizeOf(WTDFileInfo);
    WTDFileInfo.pcwszFilePath := PWideChar(swFilename);
    WTDFileInfo.pgKnownSubject := nil;
    WTDFileInfo.hFile := 0;
    
    WTrustData.cbStruct := SizeOf(WTrustData);
    WTrustData.dwUnionChoice := WTD_CHOICE_FILE; 
    WTrustData.pWTDINFO := @WTDFileInfo; 
    WTrustData.dwUIChoice := WTD_UI_NONE;
    WTrustData.fdwRevocationChecks := WTD_REVOKE_NONE;
    WTrustData.dwStateAction := WTD_STATEACTION_IGNORE;
    WTrustData.dwProvFlags := WTD_SAFER_FLAG; 
    WTrustData.hWVTStateData := 0;
    WTrustData.pwszURLReference := nil;
  end
  else
  begin
    
    
    
    CryptCATCatalogInfoFromContext(hCatalogContext, @CatalogInfo, 0);
    
    WTDCatalogInfo.cbStruct := SizeOf(WTDCatalogInfo);
    WTDCatalogInfo.pcwszCatalogFilePath := CatalogInfo.sCatalogFile;
    WTDCatalogInfo.pcwszMemberFilePath := PWideChar(swFilename);
    WTDCatalogInfo.pcwszMemberTag := PWideChar(swMemberTag);
    
    WTrustData.cbStruct := SizeOf(WTrustData);
    WTrustData.dwUnionChoice := WTD_CHOICE_CATALOG; 
    WTrustData.pWTDINFO := @WTDCatalogInfo; 
    WTrustData.dwUIChoice := WTD_UI_NONE;
    WTrustData.fdwRevocationChecks := WTD_REVOKE_NONE;
    WTrustData.pPolicyCallbackData := nil;
    WTrustData.pSIPClientData := nil;
    WTrustData.dwStateAction := WTD_STATEACTION_VERIFY;
    WTrustData.dwProvFlags := 0; 
    WTrustData.hWVTStateData := 0;
    WTrustData.pwszURLReference := nil;
  end;
  
  ilRet := WinVerifyTrust(INVALID_HANDLE_VALUE, @WINTRUST_ACTION_GENERIC_VERIFY_V2, @WTrustData);
  
  if ilRet = 0 then
  begin
    Result := True
  end
  else
    Result := False;
  
  CryptCATAdminReleaseCatalogContext(hCatAdminContext, hCatalogContext, 0);
  
  CryptCATAdminReleaseContext(hCatAdminContext, 0);
end;
 
initialization
  
  hLibWintrust := LoadLibrary('wintrust.dll');
  if hLibWintrust >= 32 then 
  begin
    CryptCATAdminAcquireContext := GetProcAddress(hLibWintrust, 'CryptCATAdminAcquireContext');
    CryptCATAdminReleaseContext := GetProcAddress(hLibWintrust, 'CryptCATAdminReleaseContext');
    CryptCATAdminCalcHashFromFileHandle := GetProcAddress(hLibWintrust, 'CryptCATAdminCalcHashFromFileHandle');
    CryptCATAdminEnumCatalogFromHash := GetProcAddress(hLibWintrust, 'CryptCATAdminEnumCatalogFromHash');
    CryptCATCatalogInfoFromContext := GetProcAddress(hLibWintrust, 'CryptCATCatalogInfoFromContext');
    CryptCATAdminReleaseCatalogContext := GetProcAddress(hLibWintrust, 'CryptCATAdminReleaseCatalogContext');
    WinVerifyTrust := GetProcAddress(hLibWintrust, 'WinVerifyTrust');
  end;
finalization
  FreeLibrary(hLibWintrust);
end.