5.4 Conversation ID

The following is the algorithm used to calculate the Conversation ID (PidTagConversationId) for a given Message object based on the values of the PidTagConversationIndex (PtypBinary), PidTagConversationTopic (PtypString), and PidTagConversationTracking (PtypBoolean) properties in the Message object. This algorithm is referenced in sections 2.5.3.1 and 2.5.3.1.1), and the main entry point is HrComputeConvID.

The arguments for HrComputeConvID are as follows: pbConvIndex and cbConvIndex represents the binary value of the PidTagConversationIndex property (NULL if the property is not present); pwzConvTopic is the Unicode string value of the PidTagConversationTopic property (NULL if property not present); and fConvTracking is the Boolean value of the PidTagConversationTracking property (default is FALSE if property not present). On success, guidConvID receives the GUID value for the computed Conversation ID. On failure, the function returns E_INVALIDARG.

The helper function ComputeMD5Guid is provided here as a placeholder. It computes an MD5 hash of the contents of the buffer passed to the function, as described in [RFC1321].

  
 #define c_ulConvIndexIDOffset 6
 #define c_ulConvIndexIDLength 16
 #define cchMax 256
  
 typedef struct {
   ULONG         i[2];
   ULONG         buf[4];
   unsigned char in[64];
   unsigned char digest[16];
 } MD5_CTX;
  
 void ComputeMD5Guid(byte *pbBuffer, ULONG cbBuffer, GUID *pguid)
 {
    // Compute the MD5 hash of the contents of pbBuffer and return
    // in the pguid parameter.
 }
  
 HRESULT HrComputeConvID(
    byte *pbConvIndex,
    ULONG cbConvIndex,
    LPCWSTR pwzConvTopic,
    BOOL fConvTracking,
    GUID *pguidConvID
    )
 {
    HRESULT   hr = S_OK;
    BOOL   fUseTopic = TRUE;
  
    if (fConvTracking
          && NULL != pbConvIndex
          && cbConvIndex >= c_ulConvIndexIDOffset + c_ulConvIndexIDLength
          && 0x01 == pbConvIndex[0])
    {
       memcpy(pguidConvID, pbConvIndex + c_ulConvIndexIDOffset, c_ulConvIndexIDLength);
       fUseTopic = FALSE;
    }
  
    if (fUseTopic)
    {
       if (NULL != pwzConvTopic)
       {
          size_t   cchHash;
          WCHAR   wzBuffer[cchMax];
          size_t   cbHash = 0;
  
          cchHash = wcslen(pwzConvTopic);
          if (cchHash < cchMax)
          {
             size_t ich;
             for (ich = 0; ich <= cchHash; ich++)
                wzBuffer[ich] = towupper(pwzConvTopic[ich]);
             cbHash = cchHash * sizeof(WCHAR);
             ComputeMD5Guid((byte *)wzBuffer, cbHash, pguidConvID);
          }
          else
             hr = E_INVALIDARG;
       }
       else
          hr = E_INVALIDARG;
    }
  
    return (hr);
 }