| Posts 1 - 10 of 11
First | Prev. | 1 2 | Next | Last
 | 
  
        |  | 
  
        |                                 Brad Smith                				   
 
 
 Posts: 49
 Joined: 2005-11-22
 
 | 
                | I've been away from the forums for a while, and realized with horror that I'd failed to send in the code fragments I promised earlier covering how to add an SMTP X-Header to an outgoing message. The following is going to be a bit disjointed but hopefully can be "converted" to real code. This is C++ code, with a few bits stripped out. Apologies in advance for formatting problems below:
 
 
 
// Undocumented "magic" GUID that lets us set X-Header values in outgoing SMTP headers
// Supported in OL2000 and above
GUID CLSID_X_Headers = { 0x00020386, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
SCODE CMsgHelper::SetSMTPXHeader(LPMESSAGE pMessage, LPCSTR szHeaderName, LPCSTR szValue)
{
  MAPINAMEID NamedProp;
  NamedProp.ulKind = MNID_STRING;
  MAPINAMEID* pNamedProp = &NamedProp;
  LPSPropTagArray lpTags = 0;
  // The name needs to be a wide character, so do a simple conversion
  wchar_t* pcwPropName = new wchar_t[(strlen(szHeaderName)+1)*2];
  memset(pcwPropName, 0, sizeof(pcwPropName));
  mbstowcs(pcwPropName, szHeaderName, strlen(szHeaderName)+1);
  // Get/Create our named properly, then set the value
  // Since this is going in a mail header, we want to make it a human-readable
  // string value, but something that can easily be parsed on receipt.
  NamedProp.lpguid = (LPGUID)&CLSID_X_Headers;
  NamedProp.Kind.lpwstrName = pcwPropName;
  hr = ((LPMAPIPROP)(IUnknown*)pMessage)->GetIDsFromNames( 1, &pNamedProp, MAPI_CREATE, &lpTags);
  delete [] pcwPropName;
  if(S_OK == hr && NULL != lpTags )
  {
    ULONG ulPropTag = lpTags->aulPropTag[0];
    SPropValue prop;
    prop.ulPropTag = PROP_TAG(PT_STRING8,PROP_ID(ulPropTag));
    prop.Value.LPSZ = (LPSTR)szValue;
    hr = HrSetOneProp((LPMAPIPROP)(IUnknown*)pMessage, &prop );
    MAPIFreeBuffer(lpTags);
  }
  return hr;
}
 
 You'd call this something like:
 red
 
 This sets a "magic" named property which, when Outlook or Exchange formats the message for SMTP transit, adds a line like:
 x-my-header=My String
 Note that the name is lowercased. This is a known bug/limitation. Since SMTP headers are expected to be case-insensitive, this isn't much of an issue.
 Also note that Outlook/Exchange does absolutely *no* syntax checking. So if' you're not careful, you can render the message unreadable.
 
 More to follow...
 
 
 | 
 | 
  
        | 
                
                  
						| Posted 20 Apr, 2006 11:31:53 |  | Top |  | 
    
        |                                 Brad Smith                				   
 
 
 Posts: 49
 Joined: 2005-11-22
 
 | 
                | Within an Exchange environment (ie. not sent via the Internet), you can read back this named property using MAPI again: 
 
 
std::string CMsgHelper::GetSMTPXHeader(LPMESSAGE pMessage, LPCSTR szHeaderName)
{
  std::string strTmp;
  std::string strValue;
  // Attempt to get direct from MAPI first. If that fails, then we'll have
  // to parse the SMTP headers.
  MAPINAMEID NamedProp;
  NamedProp.ulKind = MNID_STRING;
  MAPINAMEID* pNamedProp = &NamedProp;
  LPSPropTagArray lpTags = 0;
  // The name needs to be a wide character, so do a simple conversion
  wchar_t* pcwPropName = new wchar_t[(strlen(szHeaderName)+1)*2];
  memset(pcwPropName, 0, sizeof(pcwPropName));
  mbstowcs(pcwPropName, szHeaderName, strlen(szHeaderName)+1);
  NamedProp.lpguid = (LPGUID)&CLSID_X_Headers;
  NamedProp.Kind.lpwstrName = pcwPropName;
  HRESULT hr = ((LPMAPIPROP)(IUnknown*)pMessage)->GetIDsFromNames( 1, &pNamedProp, 0, &lpTags);
  delete [] pcwPropName;
  if(S_OK == hr && NULL != lpTags )
  {
    // and now the value
    ULONG ulPropTag = lpTags->aulPropTag[0];
    SPropValue* pProp = NULL;
    hr = HrGetOneProp((LPMAPIPROP)(IUnknown*)pMessage, PROP_TAG(PT_STRING8, PROP_ID(ulPropTag)), &pProp );
    if(SUCCEEDED(hr) && PROP_TYPE(pProp->ulPropTag) == PT_STRING8)
    {
      strValue = pProp->Value.LPSZ;
    }
    MAPIFreeBuffer(lpTags);
  }
  return strValue;
}
 
 If the above doesn't return anything, then you reset to grabbing the PR_TRANSPORT_MESSAGE_HEADERS MAPI property, which returns the entire SMTP header blob, and parse out your desired header line (remember, case-insensitive).
 
 I hope this helps, and humble apologies for the delay in getting this out. Now I just get to sit back and wait for somebody to port to C# for me. :-)
 
 Brad.
 | 
 | 
  
        | 
                
                  
						| Posted 20 Apr, 2006 11:42:53 |  | Top |  | 
    
        |                                 Sergey Grischenko                				   
 Add-in Express team
 
 
 Posts: 7233
 Joined: 2004-07-05
 
 | 
                | Hi Brad. 
 Thank you very much for the code. I will try to rewrite it in C#.
 | 
 | 
  
        | 
                
                  
						| Posted 20 Apr, 2006 12:04:32 |  | Top |  | 
    
        |                                 nistech                				   
 
 
 Posts: 30
 Joined: 2005-09-04
 
 | 
                | Thanks!  I look forward to the conversion Sergey. | 
 | 
  
        | 
                
                  
						| Posted 22 Apr, 2006 01:26:01 |  | Top |  | 
    
        |                                 Sergey Grischenko                				   
 Add-in Express team
 
 
 Posts: 7233
 Joined: 2004-07-05
 
 |  | 
  
        | 
                
                  
						| Posted 26 Apr, 2006 11:33:46 |  | Top |  | 
    
        |                                 nistech                				   
 
 
 Posts: 30
 Joined: 2005-09-04
 
 | 
                | Thanks!  I'll take a look. | 
 | 
  
        | 
                
                  
						| Posted 26 Apr, 2006 12:26:13 |  | Top |  | 
    
        |                                 Esteban Astudillo                				   
 Guest
 
 
 
 | 
                | This is great!! 
 Thank you Brad and Sergey!
 
 I will post here later my results using this code.
 
 
 | 
 | 
  
        | 
                
                  
						| Posted 26 Apr, 2006 13:52:49 |  | Top |  | 
    
        |                                 Jim Kimbrough                				   
 
 
 Posts: 17
 Joined: 2006-02-13
 
 | 
                | Regarding the sample code posted above: 
 When this code calls SetHeader()...
 
 Outlook._MailItem mitem = item as Outlook._MailItem;
 mitem.Save();
 SetHeader(mitem.MAPIOBJECT,"x-xyz-header","xyz-xyz");
 
 In the function SetHeader...
 
 private void SetHeader(object itemObj, string headerName, string _value)
 {
 IMAPIProp mail = null
 mail = itemObj as IMAPIProp;
 
 if (mail != null)
 .
 .
 .
 
 ItemObj receives an object argument, but "mail" is always null after itemObj is assigned as IMAPIProp.
 
 What do I need to do to get a successful object assignment to "mail"?
 
 Thank you.
 
 | 
 | 
  
        | 
                
                  
						| Posted 05 May, 2006 11:18:48 |  | Top |  | 
    
        |                                 Sergey Grischenko                				   
 Add-in Express team
 
 
 Posts: 7233
 Joined: 2004-07-05
 
 | 
                | Hi Jim. 
 It is very strange. The fact is that the mitem.MAPIOBJECT always returns IMAPIProp interface if the mitem field is an Outlook item.
 Didn't you change the code of the example?
 
 | 
 | 
  
        | 
                
                  
						| Posted 05 May, 2006 11:53:25 |  | Top |  | 
    
        |                                 Jim Kimbrough                				   
 
 
 Posts: 17
 Joined: 2006-02-13
 
 | 
                | Yes, I moved the relevant portions of your sample code, and your references, with new GUIDs, into another project for x-header testing. 
 It builds.  It runs.  But this argument always goes to null when assigned to the IMAPIProp mail object.  Maybe an interop or duplicate reference problem.  I will experiment with alternate references and see if I can raise some other symptom.
 
 Any thoughts about which reference might be at issue?  Seems odd since the IMAPIProp interface is specified right in the code.
 
 Thank you, Sergey.
 
 Jim
 
 
 
 
 | 
 | 
  
        | 
                
                  
						| Posted 05 May, 2006 13:38:18 |  | Top |  | 
  		
			| Posts 1 - 10 of 11
First | Prev. | 1 2 | Next | Last
 |