代码共享如下,在Win2K sp4/WinXP sp2上调试通过。
BOOL CheckFileTrust ( LPCWSTR lpFileName )
{
BOOL bRet = FALSE ;
WINTRUST_DATA wd = { 0 };
WINTRUST_FILE_INFO wfi = { 0 };
WINTRUST_CATALOG_INFO wci = { 0 };
CATALOG_INFO ci = { 0 };
HCATADMIN hCatAdmin = NULL ;
if ( ! CryptCATAdminAcquireContext ( & hCatAdmin , NULL , 0 ) )
{
return FALSE ;
}
HANDLE hFile = CreateFileW ( lpFileName , GENERIC_READ , FILE_SHARE_READ ,
NULL , OPEN_EXISTING , 0 , NULL );
if ( INVALID_HANDLE_VALUE == hFile )
{
CryptCATAdminReleaseContext ( hCatAdmin , 0 );
return FALSE ;
}
DWORD dwCnt = 100 ;
BYTE byHash [ 100 ];
CryptCATAdminCalcHashFromFileHandle ( hFile , & dwCnt , byHash , 0 );
CloseHandle ( hFile );
LPWSTR pszMemberTag = new WCHAR [ dwCnt * 2 + 1 ];
for ( DWORD dw = 0 ; dw < dwCnt ; ++ dw )
{
wsprintfW ( & pszMemberTag [ dw * 2 ], L "%02X" , byHash [ dw ] );
}
HCATINFO hCatInfo = CryptCATAdminEnumCatalogFromHash ( hCatAdmin ,
byHash , dwCnt , 0 , NULL );
if ( NULL == hCatInfo )
{
wfi . cbStruct = sizeof ( WINTRUST_FILE_INFO );
wfi . pcwszFilePath = lpFileName ;
wfi . hFile = NULL ;
wfi . pgKnownSubject = NULL ;
wd . cbStruct = sizeof ( WINTRUST_DATA );
wd . dwUnionChoice = WTD_CHOICE_FILE ;
wd . pFile = & wfi ;
wd . dwUIChoice = WTD_UI_NONE ;
wd . fdwRevocationChecks = WTD_REVOKE_NONE ;
wd . dwStateAction = WTD_STATEACTION_IGNORE ;
wd .<font co
lor="#000000">dwProvFlags = WTD_SAFER_FLAG ;
wd . hWVTStateData = NULL ;
wd . pwszURLReference = NULL ;
}
else
{
CryptCATCatalogInfoFromContext ( hCatInfo , & ci , 0 );
wci . cbStruct = sizeof ( WINTRUST_CATALOG_INFO );
wci . pcwszCatalogFilePath = ci . wszCatalogFile ;
wci . pcwszMemberFilePath = lpFileName ;
wci . pcwszMemberTag = pszMemberTag ;
wd . cbStruct = sizeof ( WINTRUST_DATA );
wd . dwUnionChoice = WTD_CHOICE_CATALOG ;
wd . pCatalog = & wci ;
wd . dwUIChoice = WTD_UI_NONE ;
wd . fdwRevocationChecks = WTD_STATEACTION_VERIFY ;
wd . dwProvFlags = 0 ;
wd . hWVTStateData = NULL ;
wd . pwszURLReference = NULL ;
}
GUID action = WINTRUST_ACTION_GENERIC_VERIFY_V2 ;
HRESULT hr = WinVerifyTrust ( NULL , & action , & wd );
bRet = SUCCEEDED ( hr );
if ( NULL != hCatInfo )
{
CryptCATAdminReleaseCatalogContext ( hCatAdmin , hCatInfo , 0 );
}
CryptCATAdminReleaseContext ( hCatAdmin , 0 );
delete [] pszMemberTag ;
return bRet ;
}
这段代码是在一个老外的论坛上不经意搜索到的,一个貌似德国人(因为他的注释不是英文写的,德国亦仅猜测尔,西班牙、葡萄牙、法兰西、俄罗斯亦都有可能)写的Delphi代码,其中使用了WinTrust.dll中的导出函数。使用VS2005的朋友们可以包含WinTrust.h、SoftPub.h和Mscat.h,并添加导入库WinTrust.lib;使用VC6的朋友们可以参考MSDN上的函数及结构体声明,并用函数指针进行调用。
本人补充一下一些类型,方便翻译成别的语言:
typedef struct _WINTRUST_DATA
{ DWORD cbStruct;
LPVOID pPolicyCallbackData;
LPVOID pSIPClientData;
DWORD dwUIChoice;
DWORD fdwRevocationChecks;
DWORD dwUnionChoice;
union {
struct WINTRUST_FILE_INFO_* pFile;
struct WINTRUST_CATALOG_INFO_* pCatalog;
struct WINTRUST_BLOB_INFO_* pBlob;
struct WINTRUST_SGNR_INFO_* pSgnr;
struct WINTRUST_CERT_INFO_* pCert;
};
DWORD dwStateAction;
HANDLE hWVTStateData;
WCHAR* <span color="
#000000" style="border: 0px; outline: 0px; vertical-align: baseline; background-color: transparent; margin: 0px; padding: 0px;">pwszURLReference;
DWORD dwProvFlags;
DWORD dwUIContext;
} WINTRUST_DATA, *PWINTRUST_DATA;
typedef struct WINTRUST_FILE_INFO_
{ DWORD cbStruct;
LPCWSTR pcwszFilePath;
HANDLE hFile;
GUID* pgKnownSubject;
} WINTRUST_FILE_INFO, *PWINTRUCT_FILE_INFO;
typedef struct WINTRUST_CATALOG_INFO_
{ DWORD cbStruct; DWORD dwCatalogVersion;
LPCWSTR pcwszCatalogFilePath;
LPCWSTR pcwszMemberTag;
LPCWSTR pcwszMemberFilePath;
HANDLE hMemberFile;
} WINTRUST_CATALOG_INFO, *PWINTRUST_CATALOG_INFO;
typedef struct CATALOG_INFO_
{ DWORD cbStruct;
WCHAR wszCatalogFile[MAX_PATH];
} CATALOG_INFO;
本人再补充一下用到的API声明:
LONG WINAPI WinVerifyTrust(
__in HWND hWnd,
__in GUID* pgActionID,
__in LPVOID pWVTData
);