home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / mapi / manager.sh / smhwb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-11  |  10.3 KB  |  381 lines

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