用MAPI来读取SMS的内容

         在做sms备份的时候,我们首先考虑的是采用mapi的形式将sms的具体内容读出来在还原的时候写回去,事实证明,这种方法是可行但是不可取的!
      这里先看看mapi是怎么读取的,这个过程中参考了无聊客写的东西,并得到我们老员工的指点。
定义以下两个宏,方便使用:
#define EXIT_ON_FAILED(_hr)/
 if (FAILED(_hr))/
{   /
 goto FuncExit; /
}

#define RELEASE_OBJ(s)  /
 if (s != NULL)      /
 {                   /
 s->Release();   /
 s = NULL;       /
 }
初始化mapi :

HRESULT InitMAPI( )
{
 CoInitializeEx(NULL, COINIT_MULTITHREADED); 
 MAPIInitialize(NULL);
 // First logon to the store.
 MAPILogonEx(NULL, NULL, NULL, NULL, &m_pSession);

 if( !m_pSession )
  return E_FAIL ;

 return S_OK ;
}

 // Get the message stores table
 hr = m_pSession->GetMsgStoresTable(MAPI_UNICODE, &pStoresTable);

 // 定义ULONG           ProgColumns[]  =   { 2, PR_ENTRYID, PR_DISPLAY_NAME };来得到属性
 hr = pStoresTable->SetColumns((LPSPropTagArray)&ProgColumns, 0);
 EXIT_ON_FAILED(hr);

 

以上初始化mapi并获取store以及table!
下面使用QueryRows方法来获取我们需要的特定的store
while(SUCCEEDED(pStoresTable->QueryRows(1, 0, &pStoresRows)))
 {
  if (pStoresRows->cRows != 1)
   break;
  else if ((pStoresRows->aRow[0].cValues < 1)
         || (pStoresRows->aRow[0].lpProps[0].ulPropTag != PR_ENTRYID))
   break ;
  else
  {
   if (_tcsicmp(pStoresRows->aRow[0].lpProps[1].Value.lpszW, _T("SMS")) == 0)
//这里是获取SMS信息的,而其他的还有ActiveSyne、MMS(等等,如果有相应帐户的话...)
   {
    ULONG ulMesageType;
    hr = m_pSession->OpenEntry(pStoresRows->aRow[0].lpProps[0].Value.bin.cb,
     (LPENTRYID)pStoresRows->aRow[0].lpProps[0].Value.bin.lpb,
     NULL,
     NULL,
     &ulMesageType,
     (LPUNKNOWN*)&pSMSStore);
//得到该store后,后面要用该store来获取IMessage对象
    EXIT_ON_FAILED(hr);
    break;
   }

   FreeProws(pStoresRows);
   pStoresRows = NULL;
  }
 }
 if( pStoresRows )
 {
  FreeProws(pStoresRows);
  pStoresRows = NULL;
 }
 RELEASE_OBJ( pStoresTable );


释放对象尽早做吧,下面就用得到的SMS store来获取SMS的属性以及其他的SMS的Folder.
ULONG   ProgColumns_SubTree[]  =   { 1, PR_IPM_SUBTREE_ENTRYID };
 SPropValue * pProgValue_SubFolders = NULL;
 // Get Root Folder
 hr = pSMSStore->GetProps((LPSPropTagArray) ProgColumns_SubTree, MAPI_UNICODE, &ulValues, &pProgValue_SubTree);
 EXIT_ON_FAILED(hr);

 hr = pSMSStore->OpenEntry(pProgValue_SubTree[0].Value.bin.cb, (LPENTRYID)pProgValue_SubTree[0].Value.bin.lpb,
  NULL,
  NULL,
  NULL,
  (LPUNKNOWN*)&pSMSFolder);

 MAPIFreeBuffer(pProgValue_SubTree);

 //has sub folder or not
 hr = pSMSFolder->GetProps((LPSPropTagArray) ProgColumns_SubFolders, MAPI_UNICODE, &ulValues, &pProgValue_SubFolders);

if( pProgValue_SubFolders[0].Value.b > 0 )
//判断该foler 下是否有sub folder,有则进一步获取message
hr = pFolder->GetContentsTable(0, &pContentsTable);
  hr = pContentsTable->SetColumns((LPSPropTagArray)&ProgColumns_Contents, 0);
//基本同上面,获取Table的方式有变,查错的步骤省略
 hr = pFolder->OpenEntry( pRows->aRow[0].lpProps[0].Value.bin.cb,
      (LPENTRYID)pRows->aRow[0].lpProps[0].Value.bin.lpb,
      NULL,
      MAPI_BEST_ACCESS,
      &ulMesageType,
      (LPUNKNOWN*)&pMessage);
//得到message,下面便可以对message操作了。
//SMS中,利用MAPI读出来的分两部分处理,一是联系人部分,另外是内容部分。SMS的内容存放在SUBJECT属性下,而到了OutLook信息中,SUBJECT部分则存放了信息的主题,而内容要采取Istream的方式读取。由于outlook的稍微复杂点,所以下面是写出了outlook的读取方式,存储在自己定义的BackupTemp结构体中
hr = pMessage->GetProps((LPSPropTagArray) ProgColomns, MAPI_UNICODE, &ulCount, &pProgValue);
  if (SUCCEEDED(hr))
  {       
   if (pProgValue[0].ulPropTag == PR_SENDER_EMAIL_ADDRESS)
    wcscpy( pBackupTemp->bkupHeader.szAddress , pProgValue[0].Value.lpszW);

   if (pProgValue[1].ulPropTag == PR_SUBJECT)
    wcscpy( pBackupTemp->bkupHeader.szSubject , pProgValue[1].Value.lpszW);
   if (pProgValue[2].ulPropTag == PR_MESSAGE_DELIVERY_TIME)
    pBackupTemp->bkupHeader.ftEmailTime =  pProgValue[2].Value.ft;
   MAPIFreeBuffer(pProgValue);
  }


  hr = pMessage->OpenProperty( PR_BODY, &IID_IStream, MAPI_BEST_ACCESS, NULL,
   (LPUNKNOWN*) &pStream);
  if(hr  == S_OK)
  {
   pStream->Read(pBackupTemp->bkupHeader.szBody, 1024*sizeof(WCHAR), &ulNumChars);
  }

 本方法下面读去mail的附件以及mms内容都比较的复杂,而且在还原的时候没办法兼顾所以对象的属性(一个pim联系人的属性就有四十多项),不适合备份!
接下来我要做的事情又与mapi有关,我会来完善这篇文章并不断地修正
另外读取pim.vol的办法我也会讲明,不过对于备份来讲,pim文件可以直接拷贝还原,所以就不需要那么麻烦了

 

 


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值