Call CryptMsgUpdate once, passing in the handle retrieved in step 2 and a pointer to the data that is to be decoded. This causes the appropriate actions to be taken on the message, depending on the message type.
Call CryptMsgGetParam, passing in the handle retrieved in step 2 and CMSG_TYPE_PARAM to verify that the message is of the enveloped data type.
If the inner content data type is data, proceed to decrypt and decode the content. Otherwise, run a decoding procedure appropriate for the content data type.
Assuming the inner content type is "data", initialize the CMSG_CTRL_DECRYPT_PARA data structure, and call CryptMsgControl, passing in CMSG_CTRL_DECRYPT and the address of the structure. The content will be decrypted.
Call CryptMsgGetParam, passing in CMSG_CONTENT_PARAM to get a pointer to the decoded content data BLOB (BYTE string).