typedef struct _CERT_STRONG_SIGN_SERIALIZED_INFO {
  DWORD  dwFlags;
  LPWSTR pwszCNGSignHashAlgids;
  LPWSTR pwszCNGPubKeyMinBitLengths;
} CERT_STRONG_SIGN_SERIALIZED_INFO, *PCERT_STRONG_SIGN_SERIALIZED_INFO;

typedef union TMP_CERT_STRONG_SIGN_PARA_UNION_TYPE {
    PVOID                              pvInfo;
    PCERT_STRONG_SIGN_SERIALIZED_INFO pSerializedInfo;
    LPSTR                             pszOID;
};


typedef struct _CERT_STRONG_SIGN_PARA {
  DWORD cbSize;
  DWORD dwInfoChoice;
  TMP_CERT_STRONG_SIGN_PARA_UNION_TYPE tmp_union;
} CERT_STRONG_SIGN_PARA, *PCERT_STRONG_SIGN_PARA, *PCCERT_STRONG_SIGN_PARA;


typedef struct _CRYPTOAPI_BLOB {
    DWORD   cbData;
    BYTE    *pbData;
} CRYPT_INTEGER_BLOB, *PCRYPT_INTEGER_BLOB,
CRYPT_UINT_BLOB, *PCRYPT_UINT_BLOB,
CRYPT_OBJID_BLOB, *PCRYPT_OBJID_BLOB,
CERT_NAME_BLOB, *PCERT_NAME_BLOB,
CERT_RDN_VALUE_BLOB, *PCERT_RDN_VALUE_BLOB,
CERT_BLOB, *PCERT_BLOB,
CRL_BLOB, *PCRL_BLOB,
DATA_BLOB, *PDATA_BLOB,
CRYPT_DATA_BLOB, *PCRYPT_DATA_BLOB,
CRYPT_HASH_BLOB, *PCRYPT_HASH_BLOB,
CRYPT_DIGEST_BLOB, *PCRYPT_DIGEST_BLOB,
CRYPT_DER_BLOB, *PCRYPT_DER_BLOB,
CRYPT_ATTR_BLOB, *PCRYPT_ATTR_BLOB;

typedef struct CRYPTCATATTRIBUTE_ {
  DWORD  cbStruct;
  LPWSTR pwszReferenceTag;
  DWORD  dwAttrTypeAndAction;
  DWORD  cbValue;
  BYTE   *pbValue;
  DWORD  dwReserved;
} CRYPTCATATTRIBUTE, *PCRYPTCATATTRIBUTE;

typedef struct _CRYPT_ATTRIBUTE_TYPE_VALUE {
    LPSTR               pszObjId;
    CRYPT_OBJID_BLOB    Value;
} CRYPT_ATTRIBUTE_TYPE_VALUE, *PCRYPT_ATTRIBUTE_TYPE_VALUE;

typedef struct _CRYPT_ALGORITHM_IDENTIFIER {
    LPSTR               pszObjId;
    CRYPT_OBJID_BLOB    Parameters;
} CRYPT_ALGORITHM_IDENTIFIER, *PCRYPT_ALGORITHM_IDENTIFIER;

typedef struct SIP_INDIRECT_DATA_
{
    CRYPT_ATTRIBUTE_TYPE_VALUE    Data;
    CRYPT_ALGORITHM_IDENTIFIER    DigestAlgorithm;
    CRYPT_HASH_BLOB               Digest;
} SIP_INDIRECT_DATA, *PSIP_INDIRECT_DATA;

typedef struct CRYPTCATMEMBER_ {
  DWORD                     cbStruct;
  LPWSTR                    pwszReferenceTag;
  LPWSTR                    pwszFileName;
  GUID                      gSubjectType;
  DWORD                     fdwMemberFlags;
  SIP_INDIRECT_DATA  *pIndirectData;
  DWORD                     dwCertVersion;
  DWORD                     dwReserved;
  HANDLE                    hReserved;
  CRYPT_ATTR_BLOB           sEncodedIndirectData;
  CRYPT_ATTR_BLOB           sEncodedMemberInfo;
} CRYPTCATMEMBER, *PCRYPTCATMEMBER;

typedef struct WINTRUST_FILE_INFO_
{
    DWORD           cbStruct;
    LPCWSTR         pcwszFilePath;
    HANDLE          hFile;
    GUID            *pgKnownSubject;
} WINTRUST_FILE_INFO, *PWINTRUST_FILE_INFO;


typedef struct _CRYPT_ATTRIBUTE {
    LPSTR               pszObjId;
    DWORD               cValue;
    PCRYPT_ATTR_BLOB    rgValue;
} CRYPT_ATTRIBUTE, *PCRYPT_ATTRIBUTE;


typedef struct _CTL_ENTRY {
    CRYPT_DATA_BLOB     SubjectIdentifier;
    DWORD               cAttribute;
    PCRYPT_ATTRIBUTE    rgAttribute;
} CTL_ENTRY, *PCTL_ENTRY;


typedef struct _CRYPT_ATTRIBUTE {
    LPSTR               pszObjId;
    DWORD               cValue;
    PCRYPT_ATTR_BLOB    rgValue;
} CRYPT_ATTRIBUTE, *PCRYPT_ATTRIBUTE;

typedef struct _CRYPT_ATTRIBUTES {
    DWORD                cAttr;
    PCRYPT_ATTRIBUTE     rgAttr;
} CRYPT_ATTRIBUTES, *PCRYPT_ATTRIBUTES;


typedef struct _CERT_EXTENSION {
    LPSTR               pszObjId;
    BOOL                fCritical;
    CRYPT_OBJID_BLOB    Value;
} CERT_EXTENSION, *PCERT_EXTENSION;


typedef struct _CRL_ENTRY {
    CRYPT_INTEGER_BLOB  SerialNumber;
    FILETIME            RevocationDate;
    DWORD               cExtension;
    PCERT_EXTENSION     rgExtension;
} CRL_ENTRY, *PCRL_ENTRY;

typedef struct _CRL_INFO {
    DWORD                       dwVersion;
    CRYPT_ALGORITHM_IDENTIFIER  SignatureAlgorithm;
    CERT_NAME_BLOB              Issuer;
    FILETIME                    ThisUpdate;
    FILETIME                    NextUpdate;
    DWORD                       cCRLEntry;
    PCRL_ENTRY                  rgCRLEntry;
    DWORD                       cExtension;
    PCERT_EXTENSION             rgExtension;
} CRL_INFO, *PCRL_INFO;


typedef struct _CRL_CONTEXT {
    DWORD                   dwCertEncodingType;
    BYTE                    *pbCrlEncoded;
    DWORD                   cbCrlEncoded;
    PCRL_INFO               pCrlInfo;
    HCERTSTORE              hCertStore;
} CRL_CONTEXT, *PCRL_CONTEXT, *PCCRL_CONTEXT;

typedef struct _CMSG_SIGNER_INFO {
    DWORD                       dwVersion;
    CERT_NAME_BLOB              Issuer;
    CRYPT_INTEGER_BLOB          SerialNumber;
    CRYPT_ALGORITHM_IDENTIFIER  HashAlgorithm;
    CRYPT_ALGORITHM_IDENTIFIER  HashEncryptionAlgorithm;
    CRYPT_DATA_BLOB             EncryptedHash;
    CRYPT_ATTRIBUTES            AuthAttrs;
    CRYPT_ATTRIBUTES            UnauthAttrs;
} CMSG_SIGNER_INFO, *PCMSG_SIGNER_INFO;




typedef struct _CTL_USAGE {
    DWORD               cUsageIdentifier;
    LPSTR               *rgpszUsageIdentifier;
} CTL_USAGE, *PCTL_USAGE, CERT_ENHKEY_USAGE, *PCERT_ENHKEY_USAGE;

typedef struct _CTL_INFO {
    DWORD                       dwVersion;
    CTL_USAGE                   SubjectUsage;
    CRYPT_DATA_BLOB             ListIdentifier;
    CRYPT_INTEGER_BLOB          SequenceNumber;
    FILETIME                    ThisUpdate;
    FILETIME                    NextUpdate;
    CRYPT_ALGORITHM_IDENTIFIER  SubjectAlgorithm;
    DWORD                       cCTLEntry;
    PCTL_ENTRY                  rgCTLEntry;
    DWORD                       cExtension;
    PCERT_EXTENSION             rgExtension;
} CTL_INFO, *PCTL_INFO;

typedef struct _CTL_CONTEXT {
    DWORD                   dwMsgAndCertEncodingType;
    BYTE                    *pbCtlEncoded;
    DWORD                   cbCtlEncoded;
    PCTL_INFO               pCtlInfo;
    HCERTSTORE              hCertStore;
    HCRYPTMSG               hCryptMsg;
    BYTE                    *pbCtlContent;
    DWORD                   cbCtlContent;
} CTL_CONTEXT, *PCTL_CONTEXT, *PCCTL_CONTEXT;


typedef struct WINTRUST_CATALOG_INFO_
{
    DWORD           cbStruct;
    DWORD           dwCatalogVersion;
    LPCWSTR         pcwszCatalogFilePath;
    LPCWSTR         pcwszMemberTag;
    LPCWSTR         pcwszMemberFilePath;
    HANDLE          hMemberFile;
    BYTE            *pbCalculatedFileHash;
    DWORD           cbCalculatedFileHash;
    PCCTL_CONTEXT   pcCatalogContext;
} WINTRUST_CATALOG_INFO, *PWINTRUST_CATALOG_INFO;


typedef struct WINTRUST_BLOB_INFO_
{
    DWORD           cbStruct;
    GUID            gSubject;
    LPCWSTR         pcwszDisplayName;
    DWORD           cbMemObject;
    BYTE            *pbMemObject;
    DWORD           cbMemSignedMsg;
    BYTE            *pbMemSignedMsg;
} WINTRUST_BLOB_INFO, *PWINTRUST_BLOB_INFO;


typedef struct _CRYPT_BIT_BLOB {
    DWORD   cbData;
    BYTE    *pbData;
    DWORD   cUnusedBits;
} CRYPT_BIT_BLOB, *PCRYPT_BIT_BLOB;

typedef struct _CERT_PUBLIC_KEY_INFO {
    CRYPT_ALGORITHM_IDENTIFIER    Algorithm;
    CRYPT_BIT_BLOB                PublicKey;
} CERT_PUBLIC_KEY_INFO, *PCERT_PUBLIC_KEY_INFO;

typedef struct _CERT_INFO {
    DWORD                       dwVersion;
    CRYPT_INTEGER_BLOB          SerialNumber;
    CRYPT_ALGORITHM_IDENTIFIER  SignatureAlgorithm;
    CERT_NAME_BLOB              Issuer;
    FILETIME                    NotBefore;
    FILETIME                    NotAfter;
    CERT_NAME_BLOB              Subject;
    CERT_PUBLIC_KEY_INFO        SubjectPublicKeyInfo;
    CRYPT_BIT_BLOB              IssuerUniqueId;
    CRYPT_BIT_BLOB              SubjectUniqueId;
    DWORD                       cExtension;
    PCERT_EXTENSION             rgExtension;
} CERT_INFO, *PCERT_INFO;


typedef struct _CERT_ISSUER_SERIAL_NUMBER {
  CERT_NAME_BLOB     Issuer;
  CRYPT_INTEGER_BLOB SerialNumber;
} CERT_ISSUER_SERIAL_NUMBER, *PCERT_ISSUER_SERIAL_NUMBER;

typedef union _TMPUNION_CERT_ID {
    CERT_ISSUER_SERIAL_NUMBER IssuerSerialNumber;
    CRYPT_HASH_BLOB           KeyId;
    CRYPT_HASH_BLOB           HashId;
} TMPUNION_CERT_ID;

typedef struct _CERT_ID {
  DWORD dwIdChoice;
  TMPUNION_CERT_ID DUMMYUNIONNAME;
} CERT_ID, *PCERT_ID;

typedef struct _CERT_CONTEXT {
    DWORD                   dwCertEncodingType;
    BYTE                    *pbCertEncoded;
    DWORD                   cbCertEncoded;
    PCERT_INFO              pCertInfo;
    HCERTSTORE              hCertStore;
} CERT_CONTEXT, *PCERT_CONTEXT, *PCCERT_CONTEXT;



typedef struct WINTRUST_SGNR_INFO_
{
    DWORD           cbStruct;
    LPCWSTR         pcwszDisplayName;
    CMSG_SIGNER_INFO *psSignerInfo;
    DWORD           chStores;
    HCERTSTORE      *pahStores;
} WINTRUST_SGNR_INFO, *PWINTRUST_SGNR_INFO;

typedef struct WINTRUST_CERT_INFO_
{
    DWORD           cbStruct;
    LPCWSTR         pcwszDisplayName;
    CERT_CONTEXT    *psCertContext;
    DWORD           chStores;
    HCERTSTORE      *pahStores;
    DWORD           dwFlags;
    FILETIME        *psftVerifyAsOf;
} WINTRUST_CERT_INFO, *PWINTRUST_CERT_INFO;


typedef union _TMP_WINTRUST_UNION_TYPE
{
        WINTRUST_FILE_INFO      *pFile;
        WINTRUST_CATALOG_INFO   *pCatalog;
        WINTRUST_BLOB_INFO      *pBlob;
        WINTRUST_SGNR_INFO      *pSgnr;
        WINTRUST_CERT_INFO      *pCert;
} TMP_WINTRUST_UNION_TYPE;


typedef struct _WINTRUST_DATA
{
    DWORD           cbStruct;
    LPVOID          pPolicyCallbackData;
    LPVOID          pSIPClientData;
    DWORD           dwUIChoice;
    DWORD           fdwRevocationChecks;
    DWORD           dwUnionChoice;

    TMP_WINTRUST_UNION_TYPE tmp_union;

    DWORD           dwStateAction;
    HANDLE          hWVTStateData;
    WCHAR           *pwszURLReference;
    DWORD           dwProvFlags;
    DWORD           dwUIContext;
} WINTRUST_DATA, *PWINTRUST_DATA;

typedef struct _CRYPT_SIGN_MESSAGE_PARA {
  DWORD                      cbSize;
  DWORD                      dwMsgEncodingType;
  PCCERT_CONTEXT             pSigningCert;
  CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
  PVOID                      pvHashAuxInfo;
  DWORD                      cMsgCert;
  PCCERT_CONTEXT             *rgpMsgCert;
  DWORD                      cMsgCrl;
  PCCRL_CONTEXT              *rgpMsgCrl;
  DWORD                      cAuthAttr;
  PCRYPT_ATTRIBUTE           rgAuthAttr;
  DWORD                      cUnauthAttr;
  PCRYPT_ATTRIBUTE           rgUnauthAttr;
  DWORD                      dwFlags;
  DWORD                      dwInnerContentType;
  CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
  PVOID                      pvHashEncryptionAuxInfo;
} CRYPT_SIGN_MESSAGE_PARA, *PCRYPT_SIGN_MESSAGE_PARA;


typedef struct _CRYPT_HASH_MESSAGE_PARA {
  DWORD                      cbSize;
  DWORD                      dwMsgEncodingType;
  HCRYPTPROV_LEGACY          hCryptProv;
  CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm;
  PVOID                      pvHashAuxInfo;
} CRYPT_HASH_MESSAGE_PARA, *PCRYPT_HASH_MESSAGE_PARA;


typedef struct _CRYPT_KEY_VERIFY_MESSAGE_PARA {
  DWORD             cbSize;
  DWORD             dwMsgEncodingType;
  HCRYPTPROV_LEGACY hCryptProv;
} CRYPT_KEY_VERIFY_MESSAGE_PARA, *PCRYPT_KEY_VERIFY_MESSAGE_PARA;

typedef struct _CRYPT_VERIFY_MESSAGE_PARA {
  DWORD                            cbSize;
  DWORD                            dwMsgAndCertEncodingType;
  HCRYPTPROV_LEGACY                hCryptProv;
  PFN_CRYPT_GET_SIGNER_CERTIFICATE pfnGetSignerCertificate;
  PVOID                            pvGetArg;
  PCCERT_STRONG_SIGN_PARA          pStrongSignPara;
} CRYPT_VERIFY_MESSAGE_PARA, *PCRYPT_VERIFY_MESSAGE_PARA;



typedef struct _SPC_SERIALIZED_OBJECT
{
    SPC_UUID            ClassId;
    CRYPT_DATA_BLOB     SerializedData;

} SPC_SERIALIZED_OBJECT, *PSPC_SERIALIZED_OBJECT;


typedef union _TMP_SPC_LINK_UNION
{
    LPWSTR                  pwszUrl;
    SPC_SERIALIZED_OBJECT   Moniker;
    LPWSTR                  pwszFile;
} TMP_SPC_LINK_UNION;



typedef struct SPC_LINK_
{
    DWORD dwLinkChoice;
    TMP_SPC_LINK_UNION u;
} SPC_LINK, *PSPC_LINK;


typedef struct _SPC_SP_OPUS_INFO
{
    LPCWSTR                     pwszProgramName;
    SPC_LINK            *pMoreInfo;
    SPC_LINK            *pPublisherInfo;
} SPC_SP_OPUS_INFO, *PSPC_SP_OPUS_INFO;


typedef struct _CERT_TRUST_STATUS {

    DWORD dwErrorStatus;
    DWORD dwInfoStatus;

} CERT_TRUST_STATUS, *PCERT_TRUST_STATUS;

typedef struct _CERT_TRUST_LIST_INFO {

    DWORD         cbSize;
    PCTL_ENTRY    pCtlEntry;
    PCCTL_CONTEXT pCtlContext;

} CERT_TRUST_LIST_INFO, *PCERT_TRUST_LIST_INFO;




typedef struct _CERT_REVOCATION_CRL_INFO {
    DWORD                   cbSize;
    PCCRL_CONTEXT           pBaseCrlContext;
    PCCRL_CONTEXT           pDeltaCrlContext;

    PCRL_ENTRY              pCrlEntry;
    BOOL                    fDeltaCrlEntry;
} CERT_REVOCATION_CRL_INFO, *PCERT_REVOCATION_CRL_INFO;

typedef struct _CERT_REVOCATION_INFO {

    DWORD                       cbSize;
    DWORD                       dwRevocationResult;
    LPCSTR                      pszRevocationOid;
    LPVOID                      pvOidSpecificInfo;
    BOOL                        fHasFreshnessTime;
    DWORD                       dwFreshnessTime;
    PCERT_REVOCATION_CRL_INFO   pCrlInfo;

} CERT_REVOCATION_INFO, *PCERT_REVOCATION_INFO;

typedef struct _CERT_CHAIN_ELEMENT {

    DWORD                 cbSize;
    PCCERT_CONTEXT        pCertContext;
    CERT_TRUST_STATUS     TrustStatus;
    PCERT_REVOCATION_INFO pRevocationInfo;

    PCERT_ENHKEY_USAGE    pIssuanceUsage;
    PCERT_ENHKEY_USAGE    pApplicationUsage;

    LPCWSTR               pwszExtendedErrorInfo;
} CERT_CHAIN_ELEMENT, *PCERT_CHAIN_ELEMENT, *PCCERT_CHAIN_ELEMENT;

typedef struct _CERT_SIMPLE_CHAIN {

    DWORD                 cbSize;
    CERT_TRUST_STATUS     TrustStatus;
    DWORD                 cElement;
    PCERT_CHAIN_ELEMENT*  rgpElement;
    PCERT_TRUST_LIST_INFO pTrustListInfo;

    BOOL                   fHasRevocationFreshnessTime;
    DWORD                  dwRevocationFreshnessTime;

} CERT_SIMPLE_CHAIN, *PCERT_SIMPLE_CHAIN, *PCCERT_SIMPLE_CHAIN;

typedef struct _CERT_CHAIN_CONTEXT {
    DWORD                   cbSize;
    CERT_TRUST_STATUS       TrustStatus;
    DWORD                   cChain;
    PCERT_SIMPLE_CHAIN*     rgpChain;
    DWORD                   cLowerQualityChainContext;
    PCCERT_CHAIN_CONTEXT*   rgpLowerQualityChainContext;
    BOOL                    fHasRevocationFreshnessTime;
    DWORD                   dwRevocationFreshnessTime;
    DWORD                   dwCreateFlags;
    GUID                    ChainId;
}CERT_CHAIN_CONTEXT, *PCERT_CHAIN_CONTEXT, *PCCERT_CHAIN_CONTEXT;


typedef struct _CERT_USAGE_MATCH {

    DWORD             dwType;
    CERT_ENHKEY_USAGE Usage;

} CERT_USAGE_MATCH, *PCERT_USAGE_MATCH;

typedef struct _CERT_CHAIN_PARA {

    DWORD            cbSize;
    CERT_USAGE_MATCH RequestedUsage;
    CERT_USAGE_MATCH RequestedIssuancePolicy;
    DWORD            dwUrlRetrievalTimeout;
    BOOL             fCheckRevocationFreshnessTime;
    DWORD            dwRevocationFreshnessTime;
    LPFILETIME                  pftCacheResync;

} CERT_CHAIN_PARA, *PCERT_CHAIN_PARA;


typedef struct _CERT_CHAIN_ENGINE_CONFIG {
    DWORD       cbSize;
    HCERTSTORE  hRestrictedRoot;
    HCERTSTORE  hRestrictedTrust;
    HCERTSTORE  hRestrictedOther;
    DWORD       cAdditionalStore;
    HCERTSTORE* rghAdditionalStore;
    DWORD       dwFlags;
    DWORD       dwUrlRetrievalTimeout;
    DWORD       MaximumCachedCertificates;
    DWORD       CycleDetectionModulus;
} CERT_CHAIN_ENGINE_CONFIG, *PCERT_CHAIN_ENGINE_CONFIG;


typedef struct _SYSTEMTIME {
  WORD wYear;
  WORD wMonth;
  WORD wDayOfWeek;
  WORD wDay;
  WORD wHour;
  WORD wMinute;
  WORD wSecond;
  WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;


typedef struct _CERT_EXTENSIONS {
  DWORD           cExtension;
  PCERT_EXTENSION rgExtension;
} CERT_EXTENSIONS, *PCERT_EXTENSIONS;

typedef struct _CRYPT_KEY_PROV_PARAM {
  DWORD dwParam;
  BYTE  *pbData;
  DWORD cbData;
  DWORD dwFlags;
} CRYPT_KEY_PROV_PARAM, *PCRYPT_KEY_PROV_PARAM;


typedef struct _CRYPT_KEY_PROV_INFO {
  LPWSTR                pwszContainerName;
  LPWSTR                pwszProvName;
  DWORD                 dwProvType;
  DWORD                 dwFlags;
  DWORD                 cProvParam;
  PCRYPT_KEY_PROV_PARAM rgProvParam;
  DWORD                 dwKeySpec;
} CRYPT_KEY_PROV_INFO, *PCRYPT_KEY_PROV_INFO;

typedef struct _CRYPT_ENCRYPT_MESSAGE_PARA {
  DWORD                      cbSize;
  DWORD                      dwMsgEncodingType;
  HCRYPTPROV_LEGACY          hCryptProv;
  CRYPT_ALGORITHM_IDENTIFIER ContentEncryptionAlgorithm;
  VOID                       *pvEncryptionAuxInfo;
  DWORD                      dwFlags;
  DWORD                      dwInnerContentType;
} CRYPT_ENCRYPT_MESSAGE_PARA, *PCRYPT_ENCRYPT_MESSAGE_PARA;


typedef struct _CRYPT_DECRYPT_MESSAGE_PARA {
  DWORD      cbSize;
  DWORD      dwMsgAndCertEncodingType;
  DWORD      cCertStore;
  HCERTSTORE *rghCertStore;
  DWORD      dwFlags;
} CRYPT_DECRYPT_MESSAGE_PARA, *PCRYPT_DECRYPT_MESSAGE_PARA;


typedef struct _CERT_KEY_CONTEXT {
  DWORD cbSize;
  HCRYPTPROV        hCryptProv;
  DWORD dwKeySpec;
} CERT_KEY_CONTEXT, *PCERT_KEY_CONTEXT;


typedef struct _CRYPT_ENCODE_PARA {
  DWORD           cbSize;
  PVOID pfnAlloc;
  PVOID  pfnFree;
} CRYPT_ENCODE_PARA, *PCRYPT_ENCODE_PARA;

typedef union _TMPUNION_CMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO {
    HCRYPTKEY hKeyEncryptionKey;
    PVOID     pvKeyEncryptionKey;
}TMPUNION_CMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO;

typedef struct _CMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO {
  DWORD                       cbSize;
  CRYPT_ALGORITHM_IDENTIFIER  KeyEncryptionAlgorithm;
  PVOID                       pvKeyEncryptionAuxInfo;
  HCRYPTPROV                  hCryptProv;
  DWORD                       dwKeyChoice;
  TMPUNION_CMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO DUMMYUNIONNAME;
  CRYPT_DATA_BLOB             KeyId;
  FILETIME                    Date;
  PCRYPT_ATTRIBUTE_TYPE_VALUE pOtherAttr;
} CMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO, *PCMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO;



typedef struct _CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO {
  DWORD                      cbSize;
  CRYPT_ALGORITHM_IDENTIFIER KeyEncryptionAlgorithm;
  PVOID                      pvKeyEncryptionAuxInfo;
  HCRYPTPROV_LEGACY          hCryptProv;
  CRYPT_BIT_BLOB             RecipientPublicKey;
  CERT_ID                    RecipientId;
} CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO, *PCMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO;

typedef struct _CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO {
  DWORD                      cbSize;
  CRYPT_ALGORITHM_IDENTIFIER KeyEncryptionAlgorithm;
  PVOID                      pvKeyEncryptionAuxInfo;
  HCRYPTPROV_LEGACY          hCryptProv;
  CRYPT_BIT_BLOB             RecipientPublicKey;
  CERT_ID                    RecipientId;
} CMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO, *PCMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO;


typedef union _TMPUNION_CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO {
    PCRYPT_ALGORITHM_IDENTIFIER pEphemeralAlgorithm;
    PCERT_ID                    pSenderId;
}TMPUNION_CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO;

typedef struct _CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO {
  DWORD                       cbSize;
  CRYPT_BIT_BLOB              RecipientPublicKey;
  CERT_ID                     RecipientId;
  FILETIME                    Date;
  PCRYPT_ATTRIBUTE_TYPE_VALUE pOtherAttr;
} CMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO, *PCMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO;

typedef struct _CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO {
  DWORD                                     cbSize;
  CRYPT_ALGORITHM_IDENTIFIER                KeyEncryptionAlgorithm;
  PVOID                                     pvKeyEncryptionAuxInfo;
  CRYPT_ALGORITHM_IDENTIFIER                KeyWrapAlgorithm;
  PVOID                                     pvKeyWrapAuxInfo;
  HCRYPTPROV_LEGACY                         hCryptProv;
  DWORD                                     dwKeySpec;
  DWORD                                     dwKeyChoice;
  TMPUNION_CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO DUMMYUNIONNAME;
  CRYPT_DATA_BLOB                           UserKeyingMaterial;
  DWORD                                     cRecipientEncryptedKeys;
  PCMSG_RECIPIENT_ENCRYPTED_KEY_ENCODE_INFO *rgpRecipientEncryptedKeys;
} CMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO, *PCMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO;


typedef union _TMP_CMSG_RECIPIENT_ENCODE_INFO_UNION {
    PCMSG_KEY_TRANS_RECIPIENT_ENCODE_INFO pKeyTrans;
    PCMSG_KEY_AGREE_RECIPIENT_ENCODE_INFO pKeyAgree;
    PCMSG_MAIL_LIST_RECIPIENT_ENCODE_INFO pMailList;
} TMP_CMSG_RECIPIENT_ENCODE_INFO_UNION;

typedef struct _CMSG_RECIPIENT_ENCODE_INFO {
  DWORD dwRecipientChoice;
  TMP_CMSG_RECIPIENT_ENCODE_INFO_UNION DUMMYUNIONNAME;
} CMSG_RECIPIENT_ENCODE_INFO, *PCMSG_RECIPIENT_ENCODE_INFO;


typedef struct _CMSG_ENVELOPED_ENCODE_INFO {
  DWORD                       cbSize;
  HCRYPTPROV_LEGACY           hCryptProv;
  CRYPT_ALGORITHM_IDENTIFIER  ContentEncryptionAlgorithm;
  PVOID                       pvEncryptionAuxInfo;
  DWORD                       cRecipients;
  PCERT_INFO                  *rgpRecipients;
  PCMSG_RECIPIENT_ENCODE_INFO rgCmsRecipients;
  DWORD                       cCertEncoded;
  PCERT_BLOB                  rgCertEncoded;
  DWORD                       cCrlEncoded;
  PCRL_BLOB                   rgCrlEncoded;
  DWORD                       cAttrCertEncoded;
  PCERT_BLOB                  rgAttrCertEncoded;
  DWORD                       cUnprotectedAttr;
  PCRYPT_ATTRIBUTE            rgUnprotectedAttr;
} CMSG_ENVELOPED_ENCODE_INFO, *PCMSG_ENVELOPED_ENCODE_INFO;


typedef struct _CMSG_STREAM_INFO {
  DWORD                  cbContent;
  PVOID pfnStreamOutput;
  PVOID                  pvArg;
} CMSG_STREAM_INFO, *PCMSG_STREAM_INFO;


typedef union _TMPUNION_CMSG_CTRL_DECRYPT_PARA {
    HCRYPTPROV        hCryptProv;
    NCRYPT_KEY_HANDLE hNCryptKey;
} TMPUNION_CMSG_CTRL_DECRYPT_PARA;


typedef struct _CMSG_CTRL_DECRYPT_PARA {
  DWORD cbSize;
  TMPUNION_CMSG_CTRL_DECRYPT_PARA DUMMYUNIONNAME;
  DWORD dwKeySpec;
  DWORD dwRecipientIndex;
} CMSG_CTRL_DECRYPT_PARA, *PCMSG_CTRL_DECRYPT_PARA;



typedef struct _SPC_PE_IMAGE_DATA
{
    CRYPT_BIT_BLOB            Flags;
    PSPC_LINK                 pFile;

} SPC_PE_IMAGE_DATA, *PSPC_PE_IMAGE_DATA;

typedef struct _SPC_INDIRECT_DATA_CONTENT
{
    CRYPT_ATTRIBUTE_TYPE_VALUE  Data;
    CRYPT_ALGORITHM_IDENTIFIER  DigestAlgorithm;
    CRYPT_HASH_BLOB             Digest;

} SPC_INDIRECT_DATA_CONTENT, *PSPC_INDIRECT_DATA_CONTENT;

typedef struct _PUBLICKEYSTRUC {
  BYTE   bType;
  BYTE   bVersion;
  WORD   reserved;
  ALG_ID aiKeyAlg;
} BLOBHEADER, PUBLICKEYSTRUC;

// The structure is described at https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/jj650836(v=vs.85)
// But PLAINTEXTKEYBLOB is a define '#define PLAINTEXTKEYBLOB        0x8' in WinCrypt.h
// So I guess this struct is reaaly defined no-where
// So the sample for importing a plain key
// https://docs.microsoft.com/en-us/windows/win32/seccrypto/example-c-program--importing-a-plaintext-key
// The BLOB is in a BYTE DesKeyBlob[] & not a real struct :')
typedef struct _STRUCT_PLAINTEXTKEYBLOB {
  BLOBHEADER hdr;
  DWORD      dwKeySize;
  BYTE       rgbKeyData[0];
} STRUCT_PLAINTEXTKEYBLOB, *PSTRUCT_PLAINTEXTKEYBLOB;