home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / sdk / mapi / win16 / dev / sample.ab / abctbl3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-11  |  32.8 KB  |  1,530 lines

  1. /***********************************************************************
  2.  *
  3.  *  ABCTBL3.C
  4.  *
  5.  *  Contents Table - Part 3.
  6.  *
  7.  *
  8.  *  The following routines are implemented in this file.
  9.  *
  10.  *
  11.  *      IVTABC_QueryInterface
  12.  *      IVTABC_Release
  13.  *      IVTABC_SortTable
  14.  *      IVTABC_QuerySortOrder
  15.  *      IVTABC_CreateBookmark
  16.  *      IVTABC_FreeBookmark
  17.  *      IVTABC_ExpandRow
  18.  *      IVTABC_ColapseRow
  19.  *      IVTABC_WaitForCompletion
  20.  *      IVTABC_Abort
  21.  *      IVTABC_Advise
  22.  *      IVTABC_Unadvise
  23.  *      IVTABC_GetStatus
  24.  *      IVTABC_SetColumns
  25.  *      IVTABC_QueryColumns
  26.  *      IVTABC_GetCollapseState,
  27.  *      IVTABC_SetCollapseState,
  28.  *
  29.  *  Copyright 1992-1995 Microsoft Corporation.  All Rights Reserved.
  30.  *
  31.  ***********************************************************************/
  32.  
  33.  
  34.  
  35.  
  36.  
  37. #include "abp.h"
  38. #include "abctbl.h"
  39. #include "sampabp.rh"
  40.  
  41.  
  42. /*
  43.  *  Default sort order set
  44.  */
  45. static const SizedSSortOrderSet(1, sosIVTABC) =
  46. {
  47.     1,
  48.     0,
  49.     0,
  50.     {
  51.         {
  52.             PR_DISPLAY_NAME_A, TABLE_SORT_ASCEND
  53.         }
  54.     }
  55. };
  56.  
  57.  
  58.  
  59.  
  60. /*************************************************************************
  61.  *
  62.  *
  63.  -  AVTABC_QueryInterface
  64.  -
  65.  *
  66.  *
  67.  *
  68.  */
  69. STDMETHODIMP 
  70. IVTABC_QueryInterface(LPIVTABC lpIVTAbc,
  71.     REFIID lpiid,
  72.     LPVOID FAR * lppNewObj)
  73. {
  74.  
  75.     HRESULT hResult = hrSuccess;
  76.  
  77.     /*  Minimally validate the lpIVTAbc parameter */
  78.  
  79.     /*
  80.      *  Check to see if it's big enough to be this object
  81.      */
  82.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  83.     {
  84.         /*
  85.          *  Not big enough
  86.          */
  87.         hResult = ResultFromScode(E_INVALIDARG);
  88.  
  89.         goto out;
  90.     }
  91.  
  92.     /*
  93.      *  Check to see that it's the correct vtbl
  94.      */
  95.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  96.     {
  97.         /*
  98.          *  Not my vtbl
  99.          */
  100.         hResult = ResultFromScode(E_INVALIDARG);
  101.  
  102.         goto out;
  103.     }
  104.  
  105.     /*  Check other parameters */
  106.  
  107.     if (IsBadReadPtr(lpiid, (UINT) sizeof(IID))
  108.         || IsBadWritePtr(lppNewObj, (UINT) sizeof(LPVOID)))
  109.     {
  110.         DebugTraceSc(IVTABC_QueryInterface, E_INVALIDARG);
  111.         return ResultFromScode(E_INVALIDARG);
  112.     }
  113.  
  114.     /*  See if the requested interface is one of ours */
  115.  
  116.     if (memcmp(lpiid, &IID_IUnknown, sizeof(IID)) &&
  117.         memcmp(lpiid, &IID_IMAPITable, sizeof(IID)))
  118.     {
  119.         *lppNewObj = NULL;      /* OLE requires zeroing the [out] parameter */
  120.         DebugTraceSc(IVTABC_QueryInterface, E_NOINTERFACE);
  121.         return ResultFromScode(E_NOINTERFACE);
  122.     }
  123.  
  124.     /*  We'll do this one. Bump the usage count and return a new pointer. */
  125.  
  126.     EnterCriticalSection(&lpIVTAbc->cs);
  127.     ++lpIVTAbc->lcInit;
  128.     LeaveCriticalSection(&lpIVTAbc->cs);
  129.     
  130.     *lppNewObj = lpIVTAbc;
  131.  
  132. out:
  133.     DebugTraceResult(IVTABC_QueryInterface,hResult);
  134.     return hResult;
  135. }
  136.  
  137. /*************************************************************************
  138.  *
  139.  -  IVTABC_Release
  140.  -
  141.  *
  142.  *      Decrement the reference count on this object and free it if
  143.  *      the reference count is zero.
  144.  *      Returns the reference count.
  145.  */
  146.  
  147. STDMETHODIMP_(ULONG)
  148. IVTABC_Release(LPIVTABC lpIVTAbc)
  149. {
  150.     ULONG ulBK;
  151.     long lcInit;
  152.     
  153.     /*
  154.      *  Check to see if it's big enough to hold this object
  155.      */
  156.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  157.     {
  158.         /*
  159.          *  Not large enough
  160.          */
  161.         return 1;
  162.     }
  163.  
  164.     /*
  165.      *  Check to see that it's the correct vtbl
  166.      */
  167.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  168.     {
  169.         /*
  170.          *  Not my vtbl
  171.          */
  172.         return 1;
  173.     }
  174.  
  175.     EnterCriticalSection(&lpIVTAbc->cs);
  176.     lcInit = --lpIVTAbc->lcInit;
  177.     LeaveCriticalSection(&lpIVTAbc->cs);
  178.  
  179.     if (lcInit == 0)
  180.     {
  181.         /*
  182.          *  Free up the current column set
  183.          */
  184.         if (lpIVTAbc->lpPTAColSet != ptagaivtabcColSet)
  185.         {
  186.             lpIVTAbc->lpFreeBuff (lpIVTAbc->lpPTAColSet);
  187.         }
  188.  
  189.         /*
  190.          *  Close up the file
  191.          */
  192.         if (lpIVTAbc->hFile != INVALID_HANDLE_VALUE)
  193.         {
  194.             CloseHandle(lpIVTAbc->hFile);
  195.             lpIVTAbc->hFile = INVALID_HANDLE_VALUE;
  196.         }
  197.  
  198.         /*
  199.          *  Free up the file name
  200.          */
  201.         lpIVTAbc->lpFreeBuff(lpIVTAbc->lpszFileName);
  202.  
  203.         /*
  204.          *  Rip through the bookmarks and free up any that are there
  205.          */
  206.         for (ulBK = 0; ulBK < MAX_BOOKMARKS; ulBK++)
  207.             if (lpIVTAbc->rglpABCBK[ulBK])
  208.             {
  209.                 (*(lpIVTAbc->lpFreeBuff)) (lpIVTAbc->rglpABCBK[ulBK]);
  210.                 lpIVTAbc->rglpABCBK[ulBK] = NULL;
  211.             }
  212.  
  213.         /*
  214.          *  Free up the ANR stuff, if used
  215.          */
  216.         lpIVTAbc->lpFreeBuff (lpIVTAbc->lpszPartialName);
  217.  
  218.         FreeANRBitmaps(lpIVTAbc);
  219.  
  220.         /*
  221.          *  Free up the advise list, if used
  222.          */
  223.         if (lpIVTAbc->parglpAdvise)
  224.             lpIVTAbc->lpMalloc->lpVtbl->Free(lpIVTAbc->lpMalloc, lpIVTAbc->parglpAdvise);
  225.  
  226.         /*  
  227.          *  Release our reference to the ABLogon object.
  228.          */
  229.         if (lpIVTAbc->lpABLogon)
  230.         {
  231.             lpIVTAbc->lpABLogon->lpVtbl->Release(lpIVTAbc->lpABLogon);
  232.             lpIVTAbc->lpABLogon = NULL;
  233.         }
  234.  
  235.         /* Delete critical section for this object */
  236.         DeleteCriticalSection(&lpIVTAbc->cs);
  237.  
  238.         /* Deregister the idle routine */
  239.  
  240.         DeregisterIdleRoutine(lpIVTAbc->ftg);
  241.  
  242.         /*
  243.          *  Set the vtbl to NULL.  This way the client will find out
  244.          *  real fast if it's calling a method on a released object.  That is,
  245.          *  the client will crash.  Hopefully, this will happen during the
  246.          *  development stage of the client.
  247.          */
  248.         lpIVTAbc->lpVtbl = NULL;
  249.  
  250.         /*
  251.          *  Need to free the object
  252.          */
  253.  
  254.         lpIVTAbc->lpFreeBuff(lpIVTAbc);
  255.         return 0;
  256.     }
  257.  
  258.     return lcInit;
  259. }
  260.  
  261.  
  262.  
  263. /*
  264.  -  IVTABC_SortTable
  265.  -
  266.  *  The Sample Address Book does not resort it's views.
  267.  *
  268.  */
  269. STDMETHODIMP 
  270. IVTABC_SortTable(LPIVTABC lpIVTAbc,
  271.     LPSSortOrderSet lpSortCriteria,
  272.     ULONG ulFlags)
  273. {
  274.     HRESULT hResult;
  275.  
  276.     /*
  277.      *  Validate parameters
  278.      */
  279.  
  280.     /*
  281.      *  Check to see if it's big enough to hold this object
  282.      */
  283.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  284.     {
  285.         /*
  286.          *  Not large enough
  287.          */
  288.         hResult = ResultFromScode(MAPI_E_INVALID_PARAMETER);
  289.  
  290.         goto out;
  291.     }
  292.  
  293.     /*
  294.      *  Check to see that it's the correct vtbl
  295.      */
  296.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  297.     {
  298.         /*
  299.          *  Not my vtbl
  300.          */
  301.         hResult = ResultFromScode(MAPI_E_INVALID_PARAMETER);
  302.  
  303.         goto out;
  304.     }
  305.  
  306.     /*
  307.      *  Check for bad sort order set.  This is from the mapi utilities DLL.
  308.      */
  309.     if (FBadSortOrderSet(lpSortCriteria))
  310.     {
  311.         hResult = ResultFromScode(MAPI_E_INVALID_PARAMETER);
  312.         goto out;
  313.     }
  314.  
  315.     /*
  316.      *  Check flags
  317.      */
  318.     if (ulFlags & ~(TBL_ASYNC|TBL_BATCH))
  319.     {
  320.         hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  321.         goto out;
  322.     }
  323.  
  324.  
  325.     /*
  326.      *  We don't support sorting this table
  327.      */
  328.     hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
  329.  
  330. out:
  331.     DebugTraceResult(IVTABC_SortTable, hResult);
  332.     return hResult;
  333.  
  334. }
  335.  
  336. /*
  337.  -  IVTABC_QuerySortOrder
  338.  -
  339.  *
  340.  *  For this implementation there is only one sort order
  341.  */
  342.  
  343. STDMETHODIMP 
  344. IVTABC_QuerySortOrder(LPIVTABC lpIVTAbc,
  345.     LPSSortOrderSet * lppSortCriteria)
  346. {
  347.     SCODE scode;
  348.     HRESULT hResult = hrSuccess;
  349.     int cbSize;
  350.  
  351.     /*
  352.      *  Validate parameters
  353.      */
  354.  
  355.     /*
  356.      *  Check to see if it's large enough to hold this object
  357.      */
  358.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  359.     {
  360.         /*
  361.          *  Not large enough
  362.          */
  363.         hResult = ResultFromScode(E_INVALIDARG);
  364.  
  365.         goto out;
  366.     }
  367.  
  368.     /*
  369.      *  Check to see that it's the correct vtbl
  370.      */
  371.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  372.     {
  373.         /*
  374.          *  Not my vtbl
  375.          */
  376.         hResult = ResultFromScode(E_INVALIDARG);
  377.  
  378.         goto out;
  379.     }
  380.  
  381.     /*
  382.      *  Check the out parameter for writability
  383.      */
  384.     if (IsBadWritePtr(lppSortCriteria, sizeof(LPSSortOrderSet)))
  385.     {
  386.         hResult = ResultFromScode(E_INVALIDARG);
  387.  
  388.         goto out;
  389.     }
  390.  
  391.     /*  Calculate size of the structure we're gonna copy */
  392.     cbSize = CbNewSSortOrderSet((int)sosIVTABC.cSorts);
  393.  
  394.     scode = lpIVTAbc->lpAllocBuff(cbSize, (LPVOID *) lppSortCriteria);
  395.     if (FAILED(scode))
  396.     {
  397.         hResult = ResultFromScode(scode);
  398.  
  399.         goto out;
  400.     }
  401.  
  402.     /*
  403.      *  Copy the column set in
  404.      */
  405.     if (cbSize)
  406.         memcpy(*lppSortCriteria, &sosIVTABC, cbSize);
  407.  
  408. out:
  409.  
  410.     DebugTraceResult(IVTABC_QuerySortOrder, hResult);
  411.     return hResult;
  412.  
  413. }
  414.  
  415.  
  416.  
  417.  
  418. /*
  419.  -  IVTABC_CreateBookmark
  420.  -
  421.  *  Creates a bookmark associated with a row in a table
  422.  *
  423.  */
  424. STDMETHODIMP 
  425. IVTABC_CreateBookmark(LPIVTABC lpIVTAbc,
  426.     BOOKMARK * lpbkPosition)
  427. {
  428.     SCODE scode;
  429.     HRESULT hResult = hrSuccess;
  430.     ULONG ulBK;
  431.     LPABCBK lpABCBK = NULL;
  432.     ULONG cbRead = 0;
  433.  
  434.     /*
  435.      *  Validate parameters
  436.      */
  437.  
  438.     /*
  439.      *  Check to see if it's large enough to hold this object
  440.      */
  441.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  442.     {
  443.         /*
  444.          *  Not large enough
  445.          */
  446.         hResult = ResultFromScode(E_INVALIDARG);
  447.  
  448.         DebugTraceResult(IVTABC_CreateBookmark, hResult);
  449.         return hResult;
  450.     }
  451.  
  452.     /*
  453.      *  Check to see that it's the correct vtbl
  454.      */
  455.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  456.     {
  457.         /*
  458.          *  Not my vtbl
  459.          */
  460.         hResult = ResultFromScode(E_INVALIDARG);
  461.  
  462.         DebugTraceResult(IVTABC_CreateBookmark, hResult);
  463.         return hResult;
  464.     }
  465.  
  466.     /*
  467.      *  Check the out parameter for writability
  468.      */
  469.     if (IsBadWritePtr(lpbkPosition, sizeof(BOOKMARK)))
  470.     {
  471.         hResult = ResultFromScode(E_INVALIDARG);
  472.  
  473.         DebugTraceResult(IVTABC_CreateBookmark, hResult);
  474.         return hResult;
  475.     }
  476.  
  477.  
  478.     EnterCriticalSection(&lpIVTAbc->cs);
  479.  
  480.  
  481.     /*
  482.      *  Open the file
  483.      */
  484.     hResult = HrOpenFile(lpIVTAbc);
  485.     if (HR_FAILED(hResult))
  486.     {
  487.         goto out;
  488.     }
  489.  
  490.     /*
  491.      *  Shortcuts first
  492.      */
  493.     if (lpIVTAbc->ulPosition == lpIVTAbc->ulMaxPos)
  494.     {
  495.         *lpbkPosition = BOOKMARK_END;
  496.         return hrSuccess;
  497.     }
  498.  
  499.     /*
  500.      *  search for a blank bookmark
  501.      */
  502.     for (ulBK = 0; lpIVTAbc->rglpABCBK[ulBK] && ulBK < MAX_BOOKMARKS; ulBK++);
  503.  
  504.     /*  did we find any??  */
  505.     if (ulBK == MAX_BOOKMARKS)
  506.     {
  507.         hResult = ResultFromScode(MAPI_E_UNABLE_TO_COMPLETE);
  508.  
  509.         goto out;
  510.     }
  511.  
  512.  
  513.     scode = lpIVTAbc->lpAllocBuff (sizeof(ABCBK),(LPVOID *) &lpABCBK);
  514.     if (FAILED(scode))
  515.     {
  516.         hResult = ResultFromScode(scode);
  517.         goto out;
  518.     }
  519.  
  520.     /*
  521.      *  Fill in new bookmark
  522.      */
  523.     lpABCBK->filetime = lpIVTAbc->filetime;
  524.     lpABCBK->ulPosition = lpIVTAbc->ulPosition;
  525.  
  526.     /*  Seek to position in file  */
  527.     (void) SetFilePointer(lpIVTAbc->hFile, lpABCBK->ulPosition, NULL, FILE_BEGIN);
  528.  
  529.     /*  Read in the record at that location  */
  530.     if (!ReadFile(lpIVTAbc->hFile,
  531.             (LPVOID) &(lpABCBK->abcrec), sizeof(ABCREC), &cbRead, NULL))
  532.     {
  533.         goto readerror;
  534.     }
  535.     /*  Second check  */
  536.     if (cbRead != sizeof(ABCREC))
  537.     {
  538.         goto readerror;
  539.     }
  540.  
  541.     /*
  542.      *  Put this in the bookmark structure
  543.      */
  544.     lpIVTAbc->rglpABCBK[ulBK] = lpABCBK;
  545.  
  546.     /*  Return the bookmark  */
  547.     *lpbkPosition = ulBK + 3;
  548.  
  549. out:
  550.     LeaveCriticalSection(&lpIVTAbc->cs);
  551.  
  552.     DebugTraceResult(IVTABC_CreateBookmark, hResult);
  553.     return hResult;
  554.  
  555. readerror:
  556.     /*
  557.      *  Didn't get the record.
  558.      */
  559.  
  560.     /*  Restore back to original position  */
  561.     (void) SetFilePointer(lpIVTAbc->hFile, lpIVTAbc->ulPosition, NULL, FILE_BEGIN);
  562.  
  563.     /*  Free up the new bookmark  */
  564.     lpIVTAbc->lpFreeBuff(lpABCBK);
  565.  
  566.     hResult = ResultFromScode(MAPI_E_UNABLE_TO_COMPLETE);
  567.     SetErrorIDS(lpIVTAbc, hResult, IDS_SAB_NO_READ);
  568.  
  569.     goto out;
  570. }
  571.  
  572. /*************************************************************************
  573.  *
  574.  -  IVTABC_FreeBookmark
  575.  -
  576.  *  Frees up the given bookmark
  577.  *
  578.  *
  579.  *
  580.  */
  581. STDMETHODIMP 
  582. IVTABC_FreeBookmark(LPIVTABC lpIVTAbc,
  583.     BOOKMARK bkPosition)
  584. {
  585.     HRESULT hResult = hrSuccess;
  586.  
  587.     /*
  588.      *  Validate parameters
  589.      */
  590.  
  591.     /*
  592.      *  Check to see if it's large enough to hold this object
  593.      */
  594.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  595.     {
  596.         /*
  597.          *  Not large enough
  598.          */
  599.         hResult = ResultFromScode(E_INVALIDARG);
  600.  
  601.         DebugTraceResult(IVTABC_FreeBookmark, hResult);
  602.         return hResult;
  603.     }
  604.  
  605.     /*
  606.      *  Check to see that it's the correct vtbl
  607.      */
  608.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  609.     {
  610.         /*
  611.          *  Not my vtbl
  612.          */
  613.         hResult = ResultFromScode(E_INVALIDARG);
  614.  
  615.         DebugTraceResult(IVTABC_FreeBookmark, hResult);
  616.         return hResult;
  617.     }
  618.  
  619.  
  620.     EnterCriticalSection(&lpIVTAbc->cs);
  621.  
  622.  
  623.     /*
  624.      *  Don't try and free up any of the standard bookmarks
  625.      */
  626.     if ((bkPosition != BOOKMARK_BEGINNING) &&
  627.         (bkPosition != BOOKMARK_CURRENT) &&
  628.         (bkPosition != BOOKMARK_END))
  629.     {
  630.         ULONG ulBK = (ULONG) bkPosition - 3;
  631.  
  632.         /*
  633.          *  See if it's in range
  634.          */
  635.         if (ulBK >= 0 && ulBK < MAX_BOOKMARKS)
  636.         {
  637.             LPABCBK lpABCBK = NULL;
  638.  
  639.             /*  If it's valid...  */
  640.             if (lpABCBK = lpIVTAbc->rglpABCBK[ulBK])    /* '=' on purpose */
  641.             {
  642.                 /*  ...free it up.  */
  643.  
  644.                 lpIVTAbc->lpFreeBuff(lpABCBK);
  645.                 lpIVTAbc->rglpABCBK[ulBK] = NULL;
  646.             }
  647.  
  648.         }
  649.         else
  650.         {
  651.             /*
  652.              * It's an error
  653.              */
  654.             hResult = ResultFromScode(E_INVALIDARG);
  655.  
  656.         }
  657.     }
  658.  
  659.     LeaveCriticalSection(&lpIVTAbc->cs);
  660.  
  661.     DebugTraceResult(IVTABC_FreeBookmark, hResult);
  662.     return hResult;
  663.  
  664. }
  665.  
  666.  
  667. /*************************************************************************
  668.  *
  669.  -  IVTABC_ExpandRow
  670.  -
  671.  *  Stubbed out.  This table doesn't implement catagorization.
  672.  *
  673.  *
  674.  *
  675.  */
  676. STDMETHODIMP 
  677. IVTABC_ExpandRow(LPIVTABC lpIVTAbc, ULONG cbIKey, LPBYTE pbIKey,
  678.     ULONG ulRowCount, ULONG ulFlags, LPSRowSet FAR * lppRows,
  679.     ULONG FAR * lpulMoreRows)
  680.  
  681. {
  682.     HRESULT hResult;
  683.  
  684.     /*
  685.      *  Validate parameters
  686.      */
  687.  
  688.     /*
  689.      *  Check to see if it's large enough to hold this object
  690.      */
  691.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  692.     {
  693.         /*
  694.          *  Not large enough
  695.          */
  696.         hResult = ResultFromScode(E_INVALIDARG);
  697.  
  698.         DebugTraceResult(IVTABC_ExpandRow, hResult);
  699.         return hResult;
  700.     }
  701.  
  702.     /*
  703.      *  Check to see that it's the correct vtbl
  704.      */
  705.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  706.     {
  707.         /*
  708.          *  Not my vtbl
  709.          */
  710.         hResult = ResultFromScode(E_INVALIDARG);
  711.  
  712.         DebugTraceResult(IVTABC_ExpandRow, hResult);
  713.         return hResult;
  714.     }
  715.  
  716.     hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
  717.  
  718.     DebugTraceResult(IVTABC_ExpandRow, hResult);
  719.     return hResult;
  720.  
  721. }
  722.  
  723. /*************************************************************************
  724.  *
  725.  -  IVTABC_CollapseRow
  726.  -
  727.  *  Stubbed out.  This table doesn't implement catagorization.
  728.  *
  729.  *
  730.  *
  731.  */
  732. STDMETHODIMP 
  733. IVTABC_CollapseRow(LPIVTABC lpIVTAbc, ULONG cbIKey, LPBYTE pbIKey,
  734.     ULONG ulFlags, ULONG FAR * lpulRowCount)
  735.  
  736. {
  737.     HRESULT hResult;
  738.  
  739.     /*
  740.      *  Validate parameters
  741.      */
  742.  
  743.     /*
  744.      *  Check to see if it's large enough to hold this object
  745.      */
  746.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  747.     {
  748.         /*
  749.          *  Not large enough
  750.          */
  751.         hResult = ResultFromScode(E_INVALIDARG);
  752.  
  753.         DebugTraceResult(IVTABC_CollapseRow, hResult);
  754.         return hResult;
  755.     }
  756.  
  757.     /*
  758.      *  Check to see that it's the correct vtbl
  759.      */
  760.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  761.     {
  762.         /*
  763.          *  Not my vtbl
  764.          */
  765.         hResult = ResultFromScode(E_INVALIDARG);
  766.  
  767.         DebugTraceResult(IVTABC_CollapseRow, hResult);
  768.         return hResult;
  769.     }
  770.  
  771.     hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
  772.  
  773.     DebugTraceResult(IVTABC_CollapseRow, hResult);
  774.     return hResult;
  775.  
  776. }
  777.  
  778. /*************************************************************************
  779.  *
  780.  -  IVTABC_WaitForCompletion
  781.  -
  782.  *  Stubbed out.
  783.  *
  784.  *
  785.  *
  786.  */
  787. STDMETHODIMP 
  788. IVTABC_WaitForCompletion(LPIVTABC lpIVTAbc, ULONG ulFlags,
  789.     ULONG ulTimeout, ULONG FAR * lpulTableStatus)
  790. {
  791.     HRESULT hResult;
  792.  
  793.     /*
  794.      *  Validate parameters
  795.      */
  796.  
  797.     /*
  798.      *  Check to see if it's large enough to hold this object
  799.      */
  800.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  801.     {
  802.         /*
  803.          *  Not large enough
  804.          */
  805.         hResult = ResultFromScode(E_INVALIDARG);
  806.  
  807.         DebugTraceResult(IVTABC_WaitForCompletion, hResult);
  808.         return hResult;
  809.     }
  810.  
  811.     /*
  812.      *  Check to see that it's the correct vtbl
  813.      */
  814.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  815.     {
  816.         /*
  817.          *  Not my vtbl
  818.          */
  819.         hResult = ResultFromScode(E_INVALIDARG);
  820.  
  821.         DebugTraceResult(IVTABC_WaitForCompletion, hResult);
  822.         return hResult;
  823.     }
  824.  
  825.     hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
  826.  
  827.     DebugTraceResult(IVTABC_WaitForCompletion, hResult);
  828.     return hResult;
  829.  
  830. }
  831. /*************************************************************************
  832.  *
  833.  -  IVTABC_Abort
  834.  -
  835.  *  Nothing ever to abort...
  836.  *
  837.  *
  838.  *
  839.  */
  840. STDMETHODIMP 
  841. IVTABC_Abort(LPIVTABC lpIVTAbc)
  842.  
  843. {
  844.     HRESULT hResult;
  845.  
  846.     /*
  847.      *  Validate parameters
  848.      */
  849.  
  850.     /*
  851.      *  Check to see if it's large enough to hold this object
  852.      */
  853.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  854.     {
  855.         /*
  856.          *  Not large enough
  857.          */
  858.         hResult = ResultFromScode(E_INVALIDARG);
  859.  
  860.         DebugTraceResult(IVTABC_Abort, hResult);
  861.         return hResult;
  862.     }
  863.  
  864.     /*
  865.      *  Check to see that it's the correct vtbl
  866.      */
  867.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  868.     {
  869.         /*
  870.          *  Not my vtbl
  871.          */
  872.         hResult = ResultFromScode(E_INVALIDARG);
  873.  
  874.         DebugTraceResult(IVTABC_Abort, hResult);
  875.         return hResult;
  876.     }
  877.  
  878.     return hrSuccess;
  879.  
  880. }
  881.  
  882. /*************************************************************************
  883.  *
  884.  *
  885.  -  IVTABC_Advise
  886.  -
  887.  *
  888.  *
  889.  *
  890.  */
  891. STDMETHODIMP 
  892. IVTABC_Advise(LPIVTABC lpIVTAbc,
  893.     ULONG ulEventmask,
  894.     LPMAPIADVISESINK lpAdviseSink,
  895.     ULONG FAR * lpulConnection)
  896. {
  897.     HRESULT hResult = hrSuccess;
  898.     UINT iAdvise;
  899.  
  900.     /*
  901.      *  Check to see if it's large enough to hold this object
  902.      */
  903.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  904.     {
  905.         /*
  906.          *  Not large enough
  907.          */
  908.         DebugTraceSc(IVTABC_Advise, E_INVALIDARG);
  909.         return ResultFromScode(E_INVALIDARG);
  910.     }
  911.  
  912.     /*
  913.      *  Check to see that it's the correct vtbl
  914.      */
  915.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  916.     {
  917.         /*
  918.          *  Not my vtbl
  919.          */
  920.         hResult = ResultFromScode(E_INVALIDARG);
  921.  
  922.         DebugTraceResult(IVTABC_Advise, hResult);
  923.         return hResult;
  924.     }
  925.  
  926.     /*
  927.      *  Validate the parameters
  928.      */
  929.  
  930.     if ((ulEventmask & ~(ULONG) fnevTableModified) ||
  931.         IsBadReadPtr(lpAdviseSink, sizeof(LPVOID)) ||
  932.         IsBadReadPtr(lpAdviseSink->lpVtbl, 3 * sizeof(LPVOID)) ||
  933.         IsBadWritePtr(lpulConnection, sizeof(ULONG)))
  934.     {
  935.         DebugTraceSc(IVTABC_Advise, E_INVALIDARG);
  936.         return ResultFromScode(E_INVALIDARG);
  937.     }
  938.  
  939.     /* Get the Critical Section */
  940.     EnterCriticalSection(&lpIVTAbc->cs);
  941.  
  942.     for (iAdvise = 0;
  943.         lpIVTAbc->parglpAdvise && iAdvise < lpIVTAbc->cAdvise;
  944.         ++iAdvise)
  945.     {
  946.         if (lpIVTAbc->parglpAdvise[iAdvise] == NULL)
  947.             break;
  948.     }
  949.  
  950.     if (iAdvise >= lpIVTAbc->cAdvise)
  951.     {
  952.         /*
  953.          *   Realloc the array if it exists
  954.          */
  955.         if (lpIVTAbc->parglpAdvise)
  956.         {
  957.             lpIVTAbc->parglpAdvise = lpIVTAbc->lpMalloc->lpVtbl->Realloc(
  958.                 lpIVTAbc->lpMalloc,
  959.                 lpIVTAbc->parglpAdvise,
  960.                 (lpIVTAbc->cAdvise + 1) * sizeof(LPMAPIADVISESINK));
  961.         }
  962.         else
  963.         {
  964.             lpIVTAbc->parglpAdvise = lpIVTAbc->lpMalloc->lpVtbl->Alloc(
  965.                 lpIVTAbc->lpMalloc,
  966.                 (lpIVTAbc->cAdvise + 1) * sizeof(LPMAPIADVISESINK));
  967.         }
  968.  
  969.         /*
  970.          *  Could we get the desired memory?
  971.          */
  972.         if (lpIVTAbc->parglpAdvise == NULL)
  973.         {
  974.             hResult = MakeResult(E_OUTOFMEMORY);
  975.             goto ret;
  976.         }
  977.     }
  978.  
  979.     lpIVTAbc->cAdvise++;
  980.  
  981.     *lpulConnection = lpIVTAbc->ulConnectMic + iAdvise;
  982.  
  983.     lpIVTAbc->parglpAdvise[iAdvise] = lpAdviseSink;
  984.  
  985.     lpAdviseSink->lpVtbl->AddRef(lpAdviseSink);
  986.  
  987. ret:
  988.     /* leave critical section */
  989.     LeaveCriticalSection(&lpIVTAbc->cs);
  990.  
  991.     DebugTraceResult(IVTABC_Advise, hResult);
  992.     return hResult;
  993. }
  994.  
  995. /*************************************************************************
  996.  *
  997.  *
  998.  -  IVTABC_Unadvise
  999.  -
  1000.  *
  1001.  *
  1002.  *
  1003.  */
  1004. STDMETHODIMP 
  1005. IVTABC_Unadvise(LPIVTABC lpIVTAbc, ULONG ulConnection)
  1006. {
  1007.     LPMAPIADVISESINK padvise;
  1008.     UINT iAdvise;
  1009.     HRESULT hResult = hrSuccess;
  1010.  
  1011.     /*
  1012.      *  Check to see if it's large enough to hold this object
  1013.      */
  1014.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  1015.     {
  1016.         /*
  1017.          *  Not large enough
  1018.          */
  1019.         DebugTraceSc(IVTABC_Unadvise, E_INVALIDARG);
  1020.         return ResultFromScode(E_INVALIDARG);
  1021.     }
  1022.  
  1023.     /*
  1024.      *  Check to see that it's the correct vtbl
  1025.      */
  1026.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  1027.     {
  1028.         /*
  1029.          *  Not my vtbl
  1030.          */
  1031.         hResult = ResultFromScode(E_INVALIDARG);
  1032.  
  1033.         DebugTraceResult(IVTABC_Unadvise, hResult);
  1034.         return hResult;
  1035.     }
  1036.  
  1037.     if (ulConnection - lpIVTAbc->ulConnectMic > (ULONG) lpIVTAbc->cAdvise)
  1038.     {
  1039.         DebugTraceSc(IVTABC_Unadvise, E_INVALIDARG);
  1040.         return ResultFromScode(E_INVALIDARG);
  1041.     }
  1042.  
  1043.     /* Get the Critical Section */
  1044.     EnterCriticalSection(&lpIVTAbc->cs);
  1045.  
  1046.     iAdvise = (UINT) (ulConnection - lpIVTAbc->ulConnectMic);
  1047.     padvise = lpIVTAbc->parglpAdvise[iAdvise];
  1048.     padvise->lpVtbl->Release(padvise);
  1049.     lpIVTAbc->parglpAdvise[iAdvise] = NULL;
  1050.     lpIVTAbc->cAdvise--;
  1051.  
  1052.     /* leave critical section */
  1053.     LeaveCriticalSection(&lpIVTAbc->cs);
  1054.  
  1055.     DebugTraceResult(IVTABC_Unadvise, hResult);
  1056.     return hResult;
  1057. }
  1058.  
  1059. /*************************************************************************
  1060.  *
  1061.  -  IVTABC_GetStatus
  1062.  -
  1063.  *  Returns the status of this table.  This table really isn't
  1064.  *  dynamic yet, but it could be...
  1065.  *
  1066.  *
  1067.  */
  1068. STDMETHODIMP 
  1069. IVTABC_GetStatus(LPIVTABC lpIVTAbc,
  1070.     ULONG * lpulTableStatus,
  1071.     ULONG * lpulTableType)
  1072. {
  1073.     HRESULT hResult;
  1074.  
  1075.     /*
  1076.      *  Parameter checking
  1077.      */
  1078.  
  1079.     /*
  1080.      *  Check to see if it's large enough to hold this object
  1081.      */
  1082.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  1083.     {
  1084.         /*
  1085.          *  Not large enough
  1086.          */
  1087.         hResult = ResultFromScode(E_INVALIDARG);
  1088.  
  1089.         DebugTraceResult(IVTABC_GetStatus, hResult);
  1090.         return hResult;
  1091.     }
  1092.  
  1093.     /*
  1094.      *  Check to see that it's the correct vtbl
  1095.      */
  1096.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  1097.     {
  1098.         /*
  1099.          *  Not my vtbl
  1100.          */
  1101.         hResult = ResultFromScode(E_INVALIDARG);
  1102.  
  1103.         DebugTraceResult(IVTABC_GetStatus, hResult);
  1104.         return hResult;
  1105.     }
  1106.  
  1107.     /*
  1108.      *  Check the out parameters for writability
  1109.      */
  1110.     if (IsBadWritePtr(lpulTableStatus, sizeof(ULONG))
  1111.         || IsBadWritePtr(lpulTableType, sizeof(ULONG)))
  1112.     {
  1113.         /*
  1114.          *  Bad out parameters
  1115.          */
  1116.         hResult = ResultFromScode(E_INVALIDARG);
  1117.  
  1118.         DebugTraceResult(IVTABC_GetStatus, hResult);
  1119.         return hResult;
  1120.     }
  1121.  
  1122.     *lpulTableStatus = TBLSTAT_COMPLETE;
  1123.     *lpulTableType = TBLTYPE_DYNAMIC;
  1124.  
  1125.     return hrSuccess;
  1126. }
  1127.  
  1128. /*************************************************************************
  1129.  *
  1130.  -  IVTABC_SetColumns
  1131.  -
  1132.  *
  1133.  *  SetColumns for contents table.
  1134.  *
  1135.  */
  1136. STDMETHODIMP 
  1137. IVTABC_SetColumns(LPIVTABC lpIVTAbc,
  1138.     LPSPropTagArray lpPTAColSet,
  1139.     ULONG ulFlags)
  1140. {
  1141.     SCODE scode;
  1142.     HRESULT hResult = hrSuccess;
  1143.     int cbSizeOfColSet;
  1144.     LPSPropTagArray lpPTAColSetT;
  1145.     ULONG uliCol;
  1146.  
  1147.     /*
  1148.      *  Check parameters
  1149.      */
  1150.  
  1151.     /*
  1152.      *  Check to see if it's large enough to hold this object
  1153.      */
  1154.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  1155.     {
  1156.         /*
  1157.          *  Not large enough
  1158.          */
  1159.         hResult = ResultFromScode(E_INVALIDARG);
  1160.  
  1161.         DebugTraceResult(IVTABC_SetColumns, hResult);
  1162.         return hResult;
  1163.     }
  1164.  
  1165.     /*
  1166.      *  Check to see that it's the correct vtbl
  1167.      */
  1168.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  1169.     {
  1170.         /*
  1171.          *  Not my vtbl
  1172.          */
  1173.         hResult = ResultFromScode(E_INVALIDARG);
  1174.  
  1175.         DebugTraceResult(IVTABC_GetStatus, hResult);
  1176.         return hResult;
  1177.     }
  1178.  
  1179.     /*
  1180.      *  Check flags
  1181.      */
  1182.     if (ulFlags & ~TBL_NOWAIT)
  1183.     {
  1184.         hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  1185.  
  1186.         DebugTraceResult(IVTABC_GetStatus, hResult);
  1187.         return hResult;
  1188.     }
  1189.  
  1190.     /*
  1191.      *  The first element of the structure
  1192.      */
  1193.     if (IsBadReadPtr(lpPTAColSet, offsetof(SPropTagArray, aulPropTag)))
  1194.     {
  1195.         hResult = ResultFromScode(E_INVALIDARG);
  1196.  
  1197.         DebugTraceResult(IVTABC_GetStatus, hResult);
  1198.         return hResult;
  1199.     }
  1200.  
  1201.     cbSizeOfColSet = CbSPropTagArray(lpPTAColSet);
  1202.  
  1203.     /*
  1204.      *  The rest of the structure
  1205.      */
  1206.     if (IsBadReadPtr(lpPTAColSet, cbSizeOfColSet))
  1207.     {
  1208.         hResult = ResultFromScode(E_INVALIDARG);
  1209.  
  1210.         DebugTraceResult(IVTABC_GetStatus, hResult);
  1211.         return hResult;
  1212.     }
  1213.  
  1214.     /*
  1215.      *  Verify that there are no PT_ERRORs here...
  1216.      */
  1217.     for (uliCol = 0; uliCol < lpPTAColSet->cValues; uliCol++)
  1218.     {
  1219.         if (PROP_TYPE(lpPTAColSet->aulPropTag[uliCol]) == PT_ERROR)
  1220.         {
  1221.             hResult = ResultFromScode(E_INVALIDARG);
  1222.  
  1223.             DebugTraceResult(IVTABC_GetStatus, hResult);
  1224.             return hResult;
  1225.         }
  1226.     }
  1227.  
  1228.     /*
  1229.      *  Allocate a new column set.
  1230.      */
  1231.  
  1232.     scode = lpIVTAbc->lpAllocBuff(cbSizeOfColSet,(LPVOID *) &lpPTAColSetT);
  1233.  
  1234.     if (FAILED(scode))
  1235.     {
  1236.         hResult = ResultFromScode(scode);
  1237.  
  1238.         DebugTraceResult(IVTABC_GetStatus, hResult);
  1239.         return hResult;
  1240.     }
  1241.  
  1242.     /*
  1243.      *  Copy the column set in
  1244.      */
  1245.     if (cbSizeOfColSet)
  1246.         memcpy(lpPTAColSetT, lpPTAColSet, cbSizeOfColSet);
  1247.  
  1248.  
  1249.     EnterCriticalSection(&lpIVTAbc->cs);
  1250.  
  1251.  
  1252.     if (lpIVTAbc->lpPTAColSet != ptagaivtabcColSet)
  1253.     {
  1254.         /*
  1255.          *  Free up the old column set
  1256.          */
  1257.         lpIVTAbc->lpFreeBuff(lpIVTAbc->lpPTAColSet);
  1258.     }
  1259.  
  1260.     lpIVTAbc->lpPTAColSet = lpPTAColSetT;
  1261.  
  1262.  
  1263.     LeaveCriticalSection(&lpIVTAbc->cs);
  1264.     
  1265.  
  1266.     return hrSuccess;
  1267.  
  1268. }
  1269.  
  1270. /*************************************************************************
  1271.  *
  1272.  -  IVTABC_QueryColumns
  1273.  -
  1274.  *
  1275.  *
  1276.  *  I always have all my columns available...  and active.
  1277.  */
  1278. STDMETHODIMP 
  1279. IVTABC_QueryColumns(LPIVTABC lpIVTAbc,
  1280.     ULONG ulFlags,
  1281.     LPSPropTagArray FAR * lppColumns)
  1282. {
  1283.     SCODE scode;
  1284.     HRESULT hResult = hrSuccess;
  1285.     int cbSizeOfColSet;
  1286.  
  1287.     /*
  1288.      *  Check parameters
  1289.      */
  1290.  
  1291.     /*
  1292.      *  Check to see if it's large enough to hold this object
  1293.      */
  1294.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  1295.     {
  1296.         /*
  1297.          *  Not large enough
  1298.          */
  1299.         hResult = ResultFromScode(E_INVALIDARG);
  1300.  
  1301.         DebugTraceResult(IVTABC_QueryColumns, hResult);
  1302.         return hResult;
  1303.     }
  1304.  
  1305.     /*
  1306.      *  Check to see that it's the correct vtbl
  1307.      */
  1308.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  1309.     {
  1310.         /*
  1311.          *  Not my vtbl
  1312.          */
  1313.         hResult = ResultFromScode(E_INVALIDARG);
  1314.  
  1315.         DebugTraceResult(IVTABC_QueryColumns, hResult);
  1316.         return hResult;
  1317.     }
  1318.  
  1319.     /*
  1320.      *  Check the out parameters for writability
  1321.      */
  1322.     if (IsBadWritePtr(lppColumns, sizeof(LPSPropTagArray)))
  1323.     {
  1324.         hResult = ResultFromScode(E_INVALIDARG);
  1325.  
  1326.         DebugTraceResult(IVTABC_QueryColumns, hResult);
  1327.         return hResult;
  1328.     }
  1329.  
  1330.     /*
  1331.      *  Check flags
  1332.      */
  1333.     if (ulFlags & ~TBL_ALL_COLUMNS)
  1334.     {
  1335.         hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  1336.  
  1337.         DebugTraceResult(IVTABC_QueryColumns, hResult);
  1338.         return hResult;
  1339.     }
  1340.  
  1341.  
  1342.     EnterCriticalSection(&lpIVTAbc->cs);
  1343.  
  1344.     /*
  1345.      *  Allocate enough memory for the column set
  1346.      */
  1347.     if (ulFlags & TBL_ALL_COLUMNS)
  1348.  
  1349.         cbSizeOfColSet = sizeof(ULONG) +
  1350.             (int)(ptagaivtabcColSet->cValues) * sizeof(ULONG);
  1351.     else
  1352.         cbSizeOfColSet = sizeof(ULONG) +
  1353.             (int)lpIVTAbc->lpPTAColSet->cValues * sizeof(ULONG);
  1354.  
  1355.  
  1356.     scode = lpIVTAbc->lpAllocBuff (cbSizeOfColSet,(LPVOID *) lppColumns);
  1357.  
  1358.     if (FAILED(scode))
  1359.     {
  1360.         hResult = ResultFromScode(scode);
  1361.         goto out;
  1362.     }
  1363.  
  1364.     /*
  1365.      *  Copy the column set in
  1366.      */
  1367.     if (ulFlags & TBL_ALL_COLUMNS)
  1368.         memcpy(*lppColumns, ptagaivtabcColSet, cbSizeOfColSet);
  1369.     else
  1370.         memcpy(*lppColumns, lpIVTAbc->lpPTAColSet, cbSizeOfColSet);
  1371.  
  1372.  
  1373. out:
  1374.     LeaveCriticalSection(&lpIVTAbc->cs);
  1375.  
  1376.     DebugTraceResult(IVTABC_QueryColumns, hResult);
  1377.     return hResult;
  1378.  
  1379. }
  1380.  
  1381. /*************************************************************************
  1382.  *
  1383.  -  IVTABC_GetCollapseState
  1384.  -
  1385.  *  Stubbed out.  Only necessary if this table were to support categorization.
  1386.  *
  1387.  *
  1388.  *
  1389.  */
  1390. STDMETHODIMP
  1391. IVTABC_GetCollapseState(LPIVTABC lpIVTAbc,
  1392.                         ULONG ulFlags,
  1393.                         ULONG cbInstanceKey,
  1394.                         LPBYTE pbInstanceKey,
  1395.                         ULONG FAR * lpcbCollapseState,
  1396.                         LPBYTE FAR * lppbCollapseState)
  1397. {
  1398.     SCODE sc = MAPI_E_NO_SUPPORT;
  1399.     HRESULT hResult;
  1400.  
  1401.     /*
  1402.      *  Check parameters
  1403.      */
  1404.  
  1405.     /*
  1406.      *  Check to see if it's large enough to hold this object
  1407.      */
  1408.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  1409.     {
  1410.         /*
  1411.          *  Not large enough
  1412.          */
  1413.         sc = E_INVALIDARG;
  1414.         goto out;
  1415.     }
  1416.  
  1417.     /*
  1418.      *  Check to see that it's the correct vtbl
  1419.      */
  1420.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  1421.     {
  1422.         /*
  1423.          *  Not my vtbl
  1424.          */
  1425.         sc = E_INVALIDARG;
  1426.         goto out;
  1427.     }
  1428.  
  1429.     if ( IsBadReadPtr(pbInstanceKey, (UINT) cbInstanceKey))
  1430.     {
  1431.         sc = MAPI_E_INVALID_PARAMETER;
  1432.         goto out;
  1433.     }
  1434.  
  1435.     if ( IsBadWritePtr(lpcbCollapseState, sizeof(ULONG)))
  1436.     {
  1437.         sc = MAPI_E_INVALID_PARAMETER;
  1438.         goto out;
  1439.     }
  1440.  
  1441.     if ( IsBadWritePtr(lppbCollapseState, sizeof(LPBYTE)))
  1442.     {
  1443.         sc = MAPI_E_INVALID_PARAMETER;
  1444.         goto out;
  1445.     }
  1446.  
  1447.     if ( ulFlags )
  1448.     {
  1449.         sc = MAPI_E_UNKNOWN_FLAGS;
  1450.     }
  1451.  
  1452. out:
  1453.  
  1454.     hResult = ResultFromScode(sc);
  1455.     DebugTraceResult(IVTABC_GetCollapseState, hResult);
  1456.     return hResult;
  1457. }
  1458.  
  1459. /*************************************************************************
  1460.  *
  1461.  -  IVTABC_SetCollapseState
  1462.  -
  1463.  *  Stubbed out.  Only necessary if this table were to support categorization.
  1464.  *
  1465.  *
  1466.  *
  1467.  */
  1468. STDMETHODIMP
  1469. IVTABC_SetCollapseState(LPIVTABC lpIVTAbc,
  1470.                         ULONG ulFlags,
  1471.                         ULONG cbCollapseState,
  1472.                         LPBYTE pbCollapseState,
  1473.                         BOOKMARK FAR * lpbkLocation)
  1474. {
  1475.  
  1476.     SCODE sc = MAPI_E_NO_SUPPORT;
  1477.     HRESULT hResult;
  1478.  
  1479.     /*
  1480.      *  Check parameters
  1481.      */
  1482.  
  1483.     /*
  1484.      *  Check to see if it's large enough to hold this object
  1485.      */
  1486.     if (IsBadReadPtr(lpIVTAbc, sizeof(IVTABC)))
  1487.     {
  1488.         /*
  1489.          *  Not large enough
  1490.          */
  1491.         sc = E_INVALIDARG;
  1492.         goto out;
  1493.     }
  1494.  
  1495.     /*
  1496.      *  Check to see that it's the correct vtbl
  1497.      */
  1498.     if (lpIVTAbc->lpVtbl != &vtblIVTABC)
  1499.     {
  1500.         /*
  1501.          *  Not my vtbl
  1502.          */
  1503.         sc = E_INVALIDARG;
  1504.         goto out;
  1505.     }
  1506.  
  1507.     if ( IsBadReadPtr(pbCollapseState, (UINT) cbCollapseState))
  1508.     {
  1509.         sc = MAPI_E_INVALID_PARAMETER;
  1510.         goto out;
  1511.     }
  1512.  
  1513.     if (IsBadWritePtr(lpbkLocation, sizeof(BOOKMARK)))
  1514.     {
  1515.         sc = MAPI_E_INVALID_PARAMETER;
  1516.         goto out;
  1517.     }
  1518.  
  1519.     if ( ulFlags )
  1520.     {
  1521.         sc = MAPI_E_UNKNOWN_FLAGS;
  1522.     }
  1523.  
  1524. out:
  1525.  
  1526.     hResult = ResultFromScode(sc);
  1527.     DebugTraceResult(IVTABC_SetCollapseState, hResult);
  1528.     return hResult;
  1529. }
  1530.