SMHWB.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:10k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*
  2.  *  S M H W B . C
  3.  *
  4.  *  Sample mail handling wastbasket message archiving
  5.  *  Copyright 1992-95 Microsoft Corporation.  All Rights Reserved.
  6.  */
  7. #include "_pch.h"
  8. /*
  9.  *  sptFilterWb
  10.  *
  11.  *  These are the columns used in wastebasket filteringarchiving
  12.  */
  13. enum { iwbEid, iwbDlv, iwbSbmt };
  14. const static SizedSPropTagArray (3, sptFilterWb) =
  15. {
  16.     3,
  17.     {
  18.         PR_ENTRYID,
  19.         PR_MESSAGE_DELIVERY_TIME,
  20.         PR_CLIENT_SUBMIT_TIME
  21.     }
  22. };
  23. /*
  24.  *  HrFilterDeleted()
  25.  *
  26.  *  Purpose:
  27.  *
  28.  *      Filters all the current message from the 'Wastebasket'/'Deleted Items'
  29.  *      folder based on the archiving model used in sent mail processing.
  30.  *
  31.  *  Arguments:
  32.  *
  33.  *      lpwb            wastbucket struct for the current store
  34.  *      lpbin           sbinary holding the entryid of the message
  35.  *
  36.  *  Returns:
  37.  *
  38.  *      (HRESULT)
  39.  */
  40. HRESULT
  41. HrFilterDeleted (LPWB lpwb, LPSRowSet lprws)
  42. {
  43.     HRESULT hr = ResultFromScode (MAPI_E_NOT_ENOUGH_MEMORY);
  44.     FILETIME ft;
  45.     LPBYTE lpeid = NULL;
  46.     LPMAPIFOLDER lpfldr = lpwb->lpfldr;
  47.     LPMDB lpmdb = lpwb->lpmdb;
  48.     LPSBinary lpbin = NULL;
  49.     LPSMH lpsmh = lpwb->lpsmh;
  50.     SBinaryArray sba;
  51.     UINT ib;
  52.     UINT irw;
  53.     ULONG cb = lpwb->lpvalEid->Value.bin.cb;
  54.     ULONG ulFlags = 0;
  55.     if (!FAILED ((*lpsmh->lpfnAlloc) (lprws->cRows * sizeof(SBinary), &lpbin)))
  56.     {
  57.         for (irw = 0; irw < lprws->cRows; )
  58.         {
  59.             ib = 0;
  60.             if (!FAILED ((*lpsmh->lpfnAlloc) (cb, &lpeid)))
  61.             {
  62.                 memcpy (lpeid, lpwb->lpvalEid->Value.bin.lpb, (UINT)cb);
  63.                 if (lprws->aRow[irw].lpProps[iwbDlv].ulPropTag == PR_MESSAGE_DELIVERY_TIME)
  64.                     ft = lprws->aRow[irw].lpProps[iwbDlv].Value.ft;
  65.                 else if (lprws->aRow[irw].lpProps[iwbSbmt].ulPropTag == PR_CLIENT_SUBMIT_TIME)
  66.                     ft = lprws->aRow[irw].lpProps[iwbSbmt].Value.ft;
  67.                 else
  68.                 {
  69.                     ++irw;
  70.                     continue;
  71.                 }
  72.                 
  73.                 hr = HrArchiveByDate (lpsmh,
  74.                                 &ft,
  75.                                 lpfldr,
  76.                                 lpmdb,
  77.                                 &lpwb->bkit,
  78.                                 lpsmh->fCatWb,
  79.                                 cb,
  80.                                 lpeid);
  81.                 if (!HR_FAILED (hr))
  82.                 {
  83.                     lpbin[ib++] = lprws->aRow[irw].lpProps[iwbEid].Value.bin;
  84.                     for (irw += 1; irw < lprws->cRows; irw++)
  85.                     {
  86.                         if (lprws->aRow[irw].lpProps[iwbDlv].ulPropTag == PR_MESSAGE_DELIVERY_TIME)
  87.                         {
  88.                             ft = lprws->aRow[irw].lpProps[iwbDlv].Value.ft;
  89.                             if ((CompareFileTime (&lpwb->bkit.dft.ftStart, &ft) == 1) ||
  90.                                 (CompareFileTime (&lpwb->bkit.dft.ftEnd, &ft) == -1))
  91.                                 break;
  92.                             lpbin[ib++] = lprws->aRow[irw].lpProps[iwbEid].Value.bin;
  93.                         }
  94.                         else if (lprws->aRow[irw].lpProps[iwbSbmt].ulPropTag == PR_CLIENT_SUBMIT_TIME)
  95.                         {
  96.                             ft = lprws->aRow[irw].lpProps[iwbSbmt].Value.ft;
  97.                             if ((CompareFileTime (&lpwb->bkit.dft.ftStart, &ft) == 1) ||
  98.                                 (CompareFileTime (&lpwb->bkit.dft.ftEnd, &ft) == -1))
  99.                                 break;
  100.                             lpbin[ib++] = lprws->aRow[irw].lpProps[iwbEid].Value.bin;
  101.                         }
  102.                         else
  103.                             break;
  104.                     }
  105.                     sba.cValues = ib;
  106.                     sba.lpbin = lpbin;
  107.                     hr = lpfldr->lpVtbl->CopyMessages (lpfldr,
  108.                                 &sba,
  109.                                 NULL,
  110.                                 lpwb->bkit.lpfldr,
  111.                                 0,
  112.                                 NULL,
  113.                                 MAPI_MOVE);
  114.                 }
  115.             }
  116.             (*lpsmh->lpfnFree) (lpeid);
  117.             lpeid = NULL;
  118.         }
  119.     }
  120.     (*lpsmh->lpfnFree) (lpbin);
  121.     DebugTraceResult (HrFilterDeleted(), hr);
  122.     return hr;
  123. }
  124. /*
  125.  *  FilterDeletedThread()
  126.  *  
  127.  *  Purpose:
  128.  *  
  129.  *      This function will spin off and do the archiving of the messages
  130.  *      in the deleted folder.  It is important to note that on 32 bit
  131.  *      platforms, this function will belong to its own thread.  Thus
  132.  *      cleanup and logoff must wait for the thread to terminate before
  133.  *      releasing returning.
  134.  *  
  135.  *  Arguments:
  136.  *  
  137.  *      lpwb        pointer to the wastebasket object
  138.  *  
  139.  *  Returns:
  140.  *  
  141.  *      (DOWRD) : Ignored
  142.  */
  143. static DWORD WINAPI
  144. FilterDeletedThread (LPWB lpwb)
  145. {
  146.     HRESULT hr;
  147.     LPMAPITABLE lptbl;
  148.     LPSRowSet lprws = NULL;
  149.     lptbl = lpwb->lptbl;
  150. #ifdef  _WIN32
  151.     SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_IDLE);
  152. #endif
  153.     while (!lpwb->fBail)
  154.     {
  155.         lptbl->lpVtbl->SeekRow (lptbl, BOOKMARK_BEGINNING, 0, NULL);
  156.         hr = lptbl->lpVtbl->QueryRows (lptbl, 64, 0, &lprws);
  157.         if (HR_FAILED (hr))
  158.             break;
  159.         if (lprws->cRows)
  160.         {
  161.             //  Filter the deleted messages
  162.             //
  163.             HrFilterDeleted (lpwb, lprws);
  164.             while (lprws->cRows)
  165.                 (*lpwb->lpsmh->lpfnFree) (lprws->aRow[--lprws->cRows].lpProps);
  166.         }
  167.         else
  168.             break;
  169.         (*lpwb->lpsmh->lpfnFree) (lprws);
  170.         lprws = NULL;
  171.     }
  172.     
  173.     (*lpwb->lpsmh->lpfnFree) (lprws);
  174.     
  175.     /*  Reset the filtering indicator */
  176. #ifdef  _WIN32
  177.     CloseHandle (lpwb->ht);
  178.     lpwb->ht = NULL;
  179. #endif
  180.     return 0;
  181. }
  182. /*
  183.  *  WBNotify()
  184.  *
  185.  *  Purpose:
  186.  *
  187.  *      Notification callback on the WB folders of message stores.  When
  188.  *      rows are added to the WB contents table, we enum the table and
  189.  *      filter each message added.
  190.  *
  191.  *  Arguments:
  192.  *
  193.  *      lpv         void pointer to current WB struct
  194.  *      cntf        count of notifications
  195.  *      lpntf       notifications
  196.  *
  197.  *  Returns:
  198.  *
  199.  *      (SCODE)
  200.  */
  201. STDAPI_(SCODE)
  202. WBNotify (LPVOID lpv, ULONG cntf, LPNOTIFICATION lpntf)
  203. {
  204.     BOOL fFilter = FALSE;
  205.     LPWB lpwb = (LPWB)lpv;
  206.     /* Quick and dirty check on the context */
  207.     if (IsBadReadPtr (lpv, sizeof(WB)) ||
  208.         IsBadReadPtr (((LPWB)lpv)->lpsmh, sizeof(SMH)))
  209.         return S_OK;
  210.     /* Just incase we were turned off */
  211.     if (lpwb->lpsmh->fCatWb)
  212.     {
  213.         while (cntf--)
  214.         {
  215.             Assert (lpntf->ulEventType == fnevTableModified);
  216.             if (lpntf->info.tab.ulTableEvent == TABLE_ROW_ADDED)
  217.             {
  218.                 fFilter |= TRUE;
  219.                 break;
  220.             }
  221.         }
  222.         
  223.         if (fFilter)
  224.         {
  225. #ifdef  _WIN32
  226.             if(!lpwb->ht)
  227.             {
  228.                 DWORD dw;
  229.                 
  230.                 lpwb->ht = CreateThread (NULL,
  231.                             1024,
  232.                             (LPTHREAD_START_ROUTINE)FilterDeletedThread,
  233.                             lpwb,
  234.                             0,
  235.                             &dw);
  236.             }
  237. #else
  238.             FilterDeletedThread (lpwb);
  239. #endif  // _WIN32
  240.         }       
  241.     }
  242.     return S_OK;
  243. }
  244. /*
  245.  *  HrInitDeletedMailFilter()
  246.  *
  247.  *  Purpose:
  248.  *
  249.  *      Inits the deleted mail filters by opening the store, finding the
  250.  *      WB folder, opening the contents table of the WB, and registering
  251.  *      for table modification notifications.
  252.  *
  253.  *  Arguments:
  254.  *
  255.  *      lpsmg           the sample mail handler object
  256.  *
  257.  *  Returns:
  258.  *
  259.  *      (HRESULT)
  260.  */
  261. HRESULT
  262. HrInitDeletedMailFilter (LPSMH lpsmh)
  263. {
  264.     HRESULT hr;
  265.     LPMAPIADVISESINK lpadvz = NULL;
  266.     LPMAPIFOLDER lpfldr = NULL;
  267.     LPMAPITABLE lptbl = NULL;
  268.     LPMDB lpmdb = NULL;
  269.     LPSPropValue lpval = NULL;
  270.     LPWB lpwb = NULL;
  271.     ULONG ulType;
  272.     UINT cerr = 0;
  273.     UINT i;
  274.     for (i = 0; i < lpsmh->lpstotbl->cSto; i++)
  275.     {
  276.         hr = ResultFromScode ((*lpsmh->lpfnAlloc) (sizeof(WB), &lpwb));
  277.         if (HR_FAILED (hr))
  278.             goto nxt;
  279.         memset (lpwb, 0, sizeof(WB));
  280.         hr = HrOpenStoEntry (lpsmh->lpsess, &lpsmh->lpstotbl->aSto[i], &lpmdb);
  281.         if (HR_FAILED (hr))
  282.             goto nxt;
  283.         hr = HrGetOneProp ((LPMAPIPROP)lpmdb, PR_IPM_WASTEBASKET_ENTRYID, &lpval);
  284.         if (HR_FAILED (hr))
  285.             goto nxt;
  286.         hr = lpmdb->lpVtbl->OpenEntry (lpmdb,
  287.                                 lpval->Value.bin.cb,
  288.                                 (LPENTRYID)lpval->Value.bin.lpb,
  289.                                 NULL,
  290.                                 MAPI_MODIFY,
  291.                                 &ulType,
  292.                                 (LPUNKNOWN FAR *)&lpfldr);
  293.         if (HR_FAILED (hr))
  294.             goto nxt;
  295.         hr = lpfldr->lpVtbl->GetContentsTable (lpfldr, 0, &lptbl);
  296.         if (HR_FAILED (hr))
  297.             goto nxt;
  298.         hr = lptbl->lpVtbl->SetColumns (lptbl, (LPSPropTagArray)&sptFilterWb, 0);
  299.         if (HR_FAILED (hr))
  300.             goto nxt;
  301.         hr = HrAllocAdviseSink ((LPNOTIFCALLBACK)&WBNotify, lpwb, &lpadvz);
  302.         if (HR_FAILED (hr))
  303.             goto nxt;
  304.         hr = lptbl->lpVtbl->Advise (lptbl, fnevTableModified, lpadvz, &lpwb->ulAdvz);
  305.         if (HR_FAILED (hr))
  306.             goto nxt;
  307.         UlAddRef (lptbl);
  308.         UlAddRef (lpfldr);
  309.         lpwb->lpmdb = lpmdb;
  310.         lpwb->lptbl = lptbl;
  311.         lpwb->lpfldr = lpfldr;
  312.         lpwb->lpvalEid = lpval;
  313.         lpwb->lpsmh = lpsmh;
  314.         lpval = NULL;
  315.         /* Hook it in */
  316.         lpwb->wbNext = lpsmh->lstWb;
  317.         lpsmh->lstWb = lpwb;
  318.         lpwb = NULL;
  319. nxt:
  320.         if (HR_FAILED (hr))
  321.             cerr++;
  322.         (*lpsmh->lpfnFree) (lpval);
  323.         lpval = NULL;
  324.         (*lpsmh->lpfnFree) (lpwb);
  325.         lpwb = NULL;
  326.         UlRelease (lpadvz);
  327.         lpadvz = NULL;
  328.         UlRelease (lpfldr);
  329.         lpfldr = NULL;
  330.         UlRelease (lptbl);
  331.         lptbl = NULL;
  332.     }
  333.     hr = ResultFromScode (cerr ? MAPI_W_ERRORS_RETURNED : S_OK);
  334.     DebugTraceResult (HrInitDeletedMailFilter(), hr);
  335.     return hr;
  336. }