home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / adsi / sampprov / cenumsch.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-29  |  8.6 KB  |  379 lines

  1. /*++
  2.  
  3. Copyright (c) 1996 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     CEnumSch.cpp
  8.  
  9. Abstract:
  10.  
  11.     Sample Provider Enum Schema functionality
  12.  
  13. Author:
  14.  
  15. Environment:
  16.  
  17.     User mode
  18.  
  19. Revision History :
  20.  
  21. --*/
  22. #include "adssmp.h"
  23. #pragma hdrstop
  24.  
  25. //+---------------------------------------------------------------------------
  26. //
  27. //  Function:   CSampleDSSchemaEnum::Create
  28. //
  29. //  Synopsis:
  30. //
  31. //  Arguments:  [pCollection]
  32. //              [ppEnumVariant]
  33. //
  34. //  Returns:    HRESULT
  35. //
  36. //  Modifies:
  37. //
  38. //  History:    01-30-95   yihsins     Created.
  39. //
  40. //----------------------------------------------------------------------------
  41. HRESULT
  42. CSampleDSSchemaEnum::Create(
  43.     CSampleDSSchemaEnum FAR* FAR* ppenumvariant,
  44.     BSTR bstrSampleDSTreeName,
  45.     BSTR bstrADsPath,
  46.     BSTR bstrName,
  47.     VARIANT var
  48.     )
  49. {
  50.     HRESULT hr = S_OK;
  51.     CSampleDSSchemaEnum FAR* penumvariant = NULL;
  52.  
  53.     *ppenumvariant = NULL;
  54.  
  55.     penumvariant = new CSampleDSSchemaEnum();
  56.     if (!penumvariant)
  57.     {
  58.         hr = E_OUTOFMEMORY;
  59.         BAIL_ON_FAILURE(hr);
  60.     }
  61.  
  62.     hr = ProvAllocString( bstrSampleDSTreeName, &penumvariant->_bstrSampleDSTreeName);
  63.     BAIL_ON_FAILURE(hr);
  64.     hr = ProvAllocString( bstrADsPath, &penumvariant->_bstrADsPath);
  65.     BAIL_ON_FAILURE(hr);
  66.         
  67.     hr = ProvAllocString( bstrName, &penumvariant->_bstrName);
  68.     BAIL_ON_FAILURE(hr);
  69.  
  70.     hr = ObjectTypeList::CreateObjectTypeList(
  71.             var,
  72.             &penumvariant->_pObjList
  73.             );
  74.     BAIL_ON_FAILURE(hr);
  75.  
  76.     *ppenumvariant = penumvariant;
  77.  
  78.     RRETURN(hr);
  79.  
  80. error:
  81.  
  82.     delete penumvariant;
  83.  
  84.     RRETURN(hr);
  85. }
  86.  
  87. CSampleDSSchemaEnum::CSampleDSSchemaEnum()
  88.     : _bstrADsPath( NULL ),
  89.       _bstrName( NULL ),
  90.       _bstrSampleDSTreeName( NULL ),
  91.       _pObjList( NULL )
  92. {
  93.     _lpClassDefs = NULL;
  94.     _dwClassCurrent = 0;
  95.     _dwClassReturned = 0;
  96.  
  97.     _lpAttrDefs = NULL;
  98.     _dwAttrCurrent = 0;
  99.     _dwAttrReturned = 0;
  100.  
  101. }
  102.  
  103. CSampleDSSchemaEnum::~CSampleDSSchemaEnum()
  104. {
  105.    ProvFreeString( _bstrName );
  106.    ProvFreeString( _bstrADsPath );
  107.    ProvFreeString( _bstrSampleDSTreeName );
  108.  
  109.  
  110.    if ( _pObjList != NULL )
  111.    {
  112.        delete _pObjList;
  113.        _pObjList = NULL;
  114.    }
  115. }
  116.  
  117. //+---------------------------------------------------------------------------
  118. //
  119. //  Function:   CSampleDSSchemaEnum::Next
  120. //
  121. //  Synopsis:   Returns cElements number of requested NetOle objects in the
  122. //              array supplied in pvar.
  123. //
  124. //  Arguments:  [cElements] -- The number of elements requested by client
  125. //              [pvar] -- ptr to array of VARIANTs to for return objects
  126. //              [pcElementFetched] -- if non-NULL, then number of elements
  127. //                                 -- actually returned is placed here
  128. //
  129. //  Returns:    HRESULT -- S_OK if number of elements requested are returned
  130. //                      -- S_FALSE if number of elements is < requested
  131. //
  132. //  Modifies:
  133. //
  134. //  History:    11-3-95   yihsins     Created.
  135. //
  136. //----------------------------------------------------------------------------
  137. STDMETHODIMP
  138. CSampleDSSchemaEnum::Next(
  139.     ULONG cElements,
  140.     VARIANT FAR* pvar,
  141.     ULONG FAR* pcElementFetched
  142.     )
  143. {
  144.     ULONG cElementFetched = 0;
  145.     HRESULT hr = S_OK;
  146.  
  147.     hr = EnumObjects(
  148.                 cElements,
  149.                 pvar,
  150.                 &cElementFetched
  151.                 );
  152.  
  153.     if ( pcElementFetched )
  154.         *pcElementFetched = cElementFetched;
  155.  
  156.     RRETURN(hr);
  157. }
  158.  
  159. HRESULT
  160. CSampleDSSchemaEnum::EnumObjects(
  161.     DWORD ObjectType,
  162.     ULONG cElements,
  163.     VARIANT FAR * pvar,
  164.     ULONG FAR * pcElementFetched
  165.     )
  166. {
  167.     switch (ObjectType)
  168.     {
  169.         case SampleDS_CLASS_ID:
  170.             RRETURN (EnumClasses(cElements, pvar, pcElementFetched));
  171.         
  172.         case SampleDS_PROPERTY_ID:
  173.             RRETURN (EnumProperties(cElements, pvar, pcElementFetched));
  174.  
  175.         default:
  176.             RRETURN(S_FALSE);
  177.     }
  178. }
  179.  
  180. HRESULT
  181. CSampleDSSchemaEnum::EnumObjects(
  182.     ULONG cElements,
  183.     VARIANT FAR* pvar,
  184.     ULONG FAR* pcElementFetched
  185.     )
  186. {
  187.     DWORD           i;
  188.     ULONG           cRequested = 0;
  189.     ULONG           cFetchedByPath = 0;
  190.     ULONG           cTotalFetched = 0;
  191.     VARIANT FAR*    pPathvar = pvar;
  192.     HRESULT         hr;
  193.     DWORD           ObjectType;
  194.  
  195.     for (i = 0; i < cElements; i++)
  196.         VariantInit(&pvar[i]);
  197.  
  198.     cRequested = cElements;
  199.  
  200.     while (  SUCCEEDED( _pObjList->GetCurrentObject(&ObjectType))
  201.           && ((hr = EnumObjects( ObjectType,
  202.                                  cRequested,
  203.                                  pPathvar,
  204.                                  &cFetchedByPath)) == S_FALSE )
  205.           )
  206.     {
  207.         pPathvar += cFetchedByPath;
  208.         cRequested -= cFetchedByPath;
  209.         cTotalFetched += cFetchedByPath;
  210.  
  211.         cFetchedByPath = 0;
  212.  
  213.         if ( FAILED(_pObjList->Next()) )
  214.         {
  215.             if ( pcElementFetched )
  216.                 *pcElementFetched = cTotalFetched;
  217.             RRETURN(S_FALSE);
  218.         }
  219.     }
  220.  
  221.     if ( pcElementFetched )
  222.         *pcElementFetched = cTotalFetched + cFetchedByPath;
  223.  
  224.     RRETURN(hr);
  225. }
  226.  
  227. HRESULT
  228. CSampleDSSchemaEnum::EnumClasses(
  229.     ULONG cElements,
  230.     VARIANT FAR* pvar,
  231.     ULONG FAR* pcElementFetched
  232.     )
  233. {
  234.     HRESULT hr = S_OK;
  235.     DWORD i = 0;
  236.     IDispatch *pDispatch = NULL;
  237.  
  238.     while ( i < cElements )
  239.     {
  240.         hr = GetClassObject(&pDispatch);
  241.         if ( hr == S_FALSE )
  242.             break;
  243.  
  244.         VariantInit( &pvar[i] );
  245.         pvar[i].vt = VT_DISPATCH;
  246.         pvar[i].pdispVal = pDispatch;
  247.         (*pcElementFetched)++;
  248.         i++;
  249.     }
  250.  
  251.     RRETURN(hr);
  252. }
  253.  
  254. HRESULT
  255. CSampleDSSchemaEnum::GetClassObject(
  256.     IDispatch ** ppDispatch
  257.     )
  258. {
  259.     HRESULT hr = S_OK;
  260.     LPSampleDS_CLASS_DEF lpCurrentObject = NULL;
  261.     
  262.     if (!_lpClassDefs) {
  263.         _dwClassCurrent = 0;
  264.         hr = SampleDSGetClassDefinition(&_lpClassDefs,
  265.                                         &_dwClassReturned);
  266.         BAIL_ON_FAILURE(hr);
  267.     }
  268.  
  269.     if (_dwClassCurrent == _dwClassReturned) {
  270.         goto error;
  271.     }
  272.  
  273.     if (_dwClassCurrent < _dwClassReturned) {
  274.  
  275.         //
  276.         // Now send back the current object
  277.         //
  278.  
  279.         lpCurrentObject = _lpClassDefs + _dwClassCurrent;
  280.  
  281.  
  282.         hr = CSampleDSClass::CreateClass(
  283.                             _bstrADsPath,
  284.                             lpCurrentObject->lpClassName,
  285.                             lpCurrentObject,
  286.                             ADS_OBJECT_BOUND,
  287.                             IID_IDispatch,
  288.                             (void **)ppDispatch
  289.                             );
  290.         BAIL_ON_FAILURE(hr);
  291.         _dwClassCurrent++;
  292.  
  293.         RRETURN(S_OK);
  294.  
  295.     }
  296.  
  297. error:
  298.     if (_lpClassDefs) {
  299.         SampleDSFreeClassDefinition(_lpClassDefs,
  300.                                     _dwClassReturned);
  301.     }
  302.     *ppDispatch = NULL;
  303.     RRETURN(S_FALSE);
  304. }
  305.  
  306. HRESULT
  307. CSampleDSSchemaEnum::EnumProperties(
  308.     ULONG cElements,
  309.     VARIANT FAR* pvar,
  310.     ULONG FAR* pcElementFetched
  311.     )
  312. {
  313.     HRESULT hr = S_OK;
  314.     DWORD i = 0;
  315.     IDispatch *pDispatch = NULL;
  316.  
  317.     while ( i < cElements )
  318.     {
  319.         hr = GetPropertyObject(&pDispatch);
  320.         if ( hr == S_FALSE )
  321.             break;
  322.  
  323.         VariantInit( &pvar[i] );
  324.         pvar[i].vt = VT_DISPATCH;
  325.         pvar[i].pdispVal = pDispatch;
  326.         (*pcElementFetched)++;
  327.         i++;
  328.     }
  329.  
  330.     RRETURN(hr);
  331. }
  332.  
  333. HRESULT
  334. CSampleDSSchemaEnum::GetPropertyObject(
  335.     IDispatch ** ppDispatch
  336.     )
  337. {
  338.     HRESULT hr = S_OK;
  339.     
  340.     LPSampleDS_ATTR_DEF lpCurrentObject = NULL;
  341.     
  342.     if (!_lpAttrDefs) {
  343.         _dwAttrCurrent = 0;
  344.         hr = SampleDSGetPropertyDefinition(&_lpAttrDefs,
  345.                                            &_dwAttrReturned);
  346.         BAIL_ON_FAILURE(hr);
  347.     }
  348.  
  349.     if (_dwAttrCurrent == _dwAttrReturned) {
  350.         goto error;
  351.     }
  352.  
  353.     if (_dwAttrCurrent < _dwAttrReturned) {
  354.  
  355.         lpCurrentObject = _lpAttrDefs + _dwAttrCurrent;
  356.  
  357.         hr = CSampleDSProperty::CreateProperty(
  358.                             _bstrADsPath,
  359.                             lpCurrentObject->lpAttributeName,
  360.                             lpCurrentObject,
  361.                             ADS_OBJECT_BOUND,
  362.                             IID_IDispatch,
  363.                             (void **)ppDispatch
  364.                             );
  365.         BAIL_ON_FAILURE(hr);
  366.         _dwAttrCurrent++;
  367.         RRETURN(S_OK);
  368.     }
  369.  
  370. error:
  371.     if (_lpAttrDefs)
  372.         SampleDSFreePropertyDefinition(_lpAttrDefs,
  373.                                        _dwAttrReturned);
  374.     *ppDispatch = NULL;
  375.     RRETURN(S_FALSE);
  376. }
  377.  
  378.  
  379.