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 / cenumobj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-29  |  12.2 KB  |  527 lines

  1. /*++
  2.  
  3. Copyright (c) 1996 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     CEnumObj.c
  8.  
  9. Abstract:
  10.  
  11.     Generic Object Enumeration CodeStandard IClassFactory implementation
  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. //
  28. //  Function:   CSampleDSEnumVariant::Create
  29. //
  30. //  Synopsis:
  31. //
  32. //  Arguments:  [pCollection]
  33. //              [ppEnumVariant]
  34. //
  35. //  Returns:    HRESULT
  36. //
  37. //  Modifies:
  38. //
  39. //  History:    
  40. //
  41. //----------------------------------------------------------------------------
  42. HRESULT
  43. CSampleDSGenObjectEnum::Create(
  44.     CSampleDSGenObjectEnum FAR* FAR* ppenumvariant,
  45.     BSTR ADsPath,
  46.     VARIANT var
  47.     )
  48. {
  49.     HRESULT hr = NOERROR;
  50.     CSampleDSGenObjectEnum FAR* penumvariant = NULL;
  51.     WCHAR szDSPath[MAX_PATH];
  52.     DWORD dwModificationTime = 0L;
  53.     DWORD dwNumberOfEntries = 0L;
  54.     DWORD dwStatus = 0L;
  55.  
  56.     *ppenumvariant = NULL;
  57.  
  58.     penumvariant = new CSampleDSGenObjectEnum();
  59.     if (!penumvariant) {
  60.         hr = E_OUTOFMEMORY;
  61.         BAIL_ON_FAILURE(hr);
  62.     }
  63.  
  64.     hr = xx_put_BSTR(&penumvariant->_ADsPath, ADsPath);
  65.     BAIL_ON_FAILURE(hr);
  66.  
  67.     hr = BuildDSFilterArray(
  68.                 var,
  69.                 (LPBYTE *)&penumvariant->_pDSFilterList
  70.                 );
  71.     if (FAILED(hr)) {
  72.         penumvariant->_pDSFilterList = NULL;
  73.     }
  74.  
  75.     *ppenumvariant = penumvariant;
  76.  
  77.     hr = BuildDSPathFromADsPath(
  78.                 ADsPath,
  79.                 szDSPath
  80.                 );
  81.     BAIL_ON_FAILURE(hr);
  82.  
  83.     hr = SampleDSOpenObject(
  84.                     szDSPath,
  85.                     &penumvariant->_hObject,
  86.                     NULL,
  87.                     REG_DS
  88.                     );
  89.     BAIL_ON_FAILURE(hr);
  90.  
  91.     hr = SampleDSRDNEnum( 
  92.                  &penumvariant->_hEnum, 
  93.                  penumvariant->_hObject
  94.                  );
  95.     
  96.     RRETURN(hr);
  97.  
  98. error:
  99.     if (penumvariant->_hObject) {
  100.         SampleDSCloseObject(penumvariant->_hObject);
  101.     }
  102.     
  103.     delete penumvariant;
  104.  
  105.     RRETURN(hr);
  106. }
  107.  
  108. CSampleDSGenObjectEnum::CSampleDSGenObjectEnum():
  109.                     _ADsPath(NULL)
  110. {
  111.     _pObjList = NULL;
  112.     _dwObjectReturned = 0;
  113.     _dwObjectCurrentEntry = 0;
  114.     _dwObjectTotal = 0;
  115.     _hObject = NULL;
  116.     _hEnum = NULL;
  117.     _lpObjects = NULL;
  118.     _pDSFilterList = NULL;
  119.  
  120.     _bNoMore = FALSE;
  121. }
  122.  
  123.  
  124. CSampleDSGenObjectEnum::~CSampleDSGenObjectEnum()
  125. {
  126.     if (_pDSFilterList) {
  127.         FreeFilterList((LPBYTE)_pDSFilterList);
  128.     }
  129. }
  130.  
  131. HRESULT
  132. CSampleDSGenObjectEnum::EnumObjects(
  133.     DWORD ObjectType,
  134.     ULONG cElements,
  135.     VARIANT FAR * pvar,
  136.     ULONG FAR * pcElementFetched
  137.     )
  138. {
  139.  
  140.     //
  141.     // Multi-level detection of Objects may not be necessary for DS code
  142.     //
  143.  
  144.     RRETURN(EnumGenericObjects(cElements, pvar, pcElementFetched));
  145.  
  146. }
  147. HRESULT
  148. CSampleDSGenObjectEnum::EnumGenericObjects(
  149.     ULONG cElements,
  150.     VARIANT FAR* pvar,
  151.     ULONG FAR* pcElementFetched
  152.     )
  153. {
  154.     DWORD           i;
  155.     ULONG           cRequested = 0;
  156.     ULONG           cTotalFetched = 0;
  157.     HRESULT         hr;
  158.  
  159.     for (i = 0; i < cElements; i++)  {
  160.         VariantInit(&pvar[i]);
  161.     }
  162.     cRequested = cElements;
  163.  
  164.         hr = FetchObjects(cElements, pvar, &cTotalFetched);
  165.    
  166.     if (pcElementFetched) {
  167.         *pcElementFetched = cTotalFetched;
  168.     }
  169.  
  170.     RRETURN(hr);
  171. }
  172.  
  173. //
  174. // Load IDispatch pointers of Next cElements Filtered Objects into pvar array
  175. //
  176. HRESULT
  177. CSampleDSGenObjectEnum::FetchObjects(
  178.  
  179.     ULONG cElements,
  180.     VARIANT FAR* pvar,
  181.     ULONG FAR* pcElementFetched
  182.     )
  183. {
  184.     HRESULT hr;
  185.     IDispatch *pDispatch = NULL;
  186.     DWORD i = 0;
  187.  
  188.     while (i < cElements) {
  189.  
  190.         hr = FetchNextObject(&pDispatch);
  191.         if (hr == S_FALSE) {
  192.             break;
  193.         }
  194.  
  195.         VariantInit(&pvar[i]);
  196.         pvar[i].vt = VT_DISPATCH;
  197.         pvar[i].pdispVal = pDispatch;
  198.         (*pcElementFetched)++;
  199.         i++;
  200.     }
  201.     return(hr);
  202. }
  203. //+---------------------------------------------------------------------------
  204. //
  205. //  Function:   CSampleDSNamespaceEnum::FetchNextObject
  206. //
  207. //  Synopsis:   Gets IDispatch pointer of next object in namespace subject to
  208. //                              filter.
  209. //
  210. //  Arguments:  [ppDispatch] -- Pointer to where to return IDispatch pointer.
  211. //
  212. //  Returns:    HRESULT -- S_OK if got the next object
  213. //                      -- S_FALSE if not
  214. //
  215. //  Modifies:   [*ppDispatch]
  216. //
  217. //----------------------------------------------------------------------------
  218. HRESULT
  219. CSampleDSGenObjectEnum::FetchNextObject(
  220.     IDispatch ** ppDispatch
  221.     )
  222.  {
  223.     HRESULT hr;
  224.     LPTSTR lpszObjectRDN=NULL ;
  225.     LPTSTR lpszObjectClass = 0;
  226.     DWORD dwClassId = 0;
  227.     IADs * pADs = NULL;
  228.     *ppDispatch = NULL;
  229.  
  230.     hr = S_OK;
  231.     while (hr == S_OK){
  232.         hr=SampleDSNextRDN(_hEnum,
  233.                            &lpszObjectRDN,
  234.                            &lpszObjectClass
  235.                            );    
  236.         if (S_OK==hr && 
  237.             S_OK==IsValidDSFilter(lpszObjectClass)) {
  238.             break;
  239.         }
  240.     }
  241.  
  242.     //
  243.     // Now create and send back the current object
  244.     //
  245.     if (hr == S_OK) {
  246.         hr = CSampleDSGenObject::CreateGenericObject(_ADsPath,
  247.                                                      lpszObjectRDN,
  248.                                                      lpszObjectClass,
  249.                                                      ADS_OBJECT_BOUND,
  250.                                                      IID_IDispatch,
  251.                                                      (void **)ppDispatch
  252.                                                      );
  253.         BAIL_ON_FAILURE(hr);
  254.     }
  255.     else {
  256.         if (_hEnum) {
  257.             SampleDSFreeEnum(_hEnum);
  258.             _hEnum = NULL;
  259.         }
  260.     }
  261.  
  262. error:
  263.  
  264.     //
  265.     // Free the intermediate pADs pointer.
  266.     //
  267.     if (pADs) {
  268.         pADs->Release();
  269.     }
  270.     if (lpszObjectRDN)
  271.         FreeProvMem(lpszObjectRDN);
  272.     if (lpszObjectClass)
  273.         FreeProvMem(lpszObjectClass);
  274.     RRETURN_ENUM_STATUS(hr); 
  275. }
  276.  
  277.  
  278. //+---------------------------------------------------------------------------
  279. //
  280. //  Function:   CSampleDSGenObjectEnum::Next
  281. //
  282. //  Synopsis:   Returns cElements number of requested NetOle objects in the
  283. //              array supplied in pvar.
  284. //
  285. //  Arguments:  [cElements] -- The number of elements requested by client
  286. //              [pvar] -- ptr to array of VARIANTs to for return objects
  287. //              [pcElementFetched] -- if non-NULL, then number of elements
  288. //                                 -- actually returned is placed here
  289. //
  290. //  Returns:    HRESULT -- S_OK if number of elements requested are returned
  291. //                      -- S_FALSE if number of elements is < requested
  292. //
  293. //
  294. //----------------------------------------------------------------------------
  295. STDMETHODIMP
  296. CSampleDSGenObjectEnum::Next(
  297.     ULONG cElements,
  298.     VARIANT FAR* pvar,
  299.     ULONG FAR* pcElementFetched
  300.     )
  301. {
  302.     ULONG cElementFetched = 0;
  303.     HRESULT hr = S_OK;
  304.  
  305.     hr = EnumGenericObjects(
  306.             cElements,
  307.             pvar,
  308.             &cElementFetched
  309.             );
  310.  
  311.  
  312.     if (pcElementFetched) {
  313.         *pcElementFetched = cElementFetched;
  314.     }
  315.     RRETURN(hr);
  316. }
  317.  
  318. HRESULT
  319. CSampleDSGenObjectEnum::IsValidDSFilter(LPWSTR ObjectName){
  320.  
  321.     if (_pDSFilterList){
  322.                 for (DWORD i = 0; i < _pDSFilterList->dwNumberOfFilters; i++) {
  323.  
  324.                         if ( !_wcsicmp(ObjectName,_pDSFilterList->Filters[i].lpObjectClass) ) {
  325.                                 RRETURN(S_OK);
  326.                         }
  327.                 }
  328.                 RRETURN(E_FAIL);
  329.     }
  330.     RRETURN(S_OK);
  331. }
  332.  
  333. HRESULT
  334. BuildDSFilterArray(
  335.     VARIANT var,
  336.     LPBYTE * ppContigFilter
  337.     )
  338. {
  339.     LONG uDestCount = 0;
  340.     LONG dwSLBound = 0;
  341.     LONG dwSUBound = 0;
  342.     VARIANT v;
  343.     LONG i;
  344.     HRESULT hr = S_OK;
  345.  
  346.     LPDS_FILTER_LIST pDsFilterList = NULL;
  347.     LPBYTE pContigFilter = NULL;
  348.  
  349.     if(!((V_VT(&var) &  VT_VARIANT) &&  V_ISARRAY(&var))) {
  350.         RRETURN(E_FAIL);
  351.     }
  352.  
  353.     //
  354.     // Check that there is only one dimension in this array
  355.     //
  356.  
  357.     if ((V_ARRAY(&var))->cDims != 1) {
  358.         hr = E_FAIL;
  359.         BAIL_ON_FAILURE(hr);
  360.     }
  361.     //
  362.     // Check that there is atleast one element in this array
  363.     //
  364.  
  365.     if ((V_ARRAY(&var))->rgsabound[0].cElements == 0){
  366.         hr = E_FAIL;
  367.         BAIL_ON_FAILURE(hr);
  368.     }
  369.  
  370.     //
  371.     // We know that this is a valid single dimension array
  372.     //
  373.  
  374.     hr = SafeArrayGetLBound(V_ARRAY(&var),
  375.                             1,
  376.                             (long FAR *)&dwSLBound
  377.                             );
  378.     BAIL_ON_FAILURE(hr);
  379.  
  380.     hr = SafeArrayGetUBound(V_ARRAY(&var),
  381.                             1,
  382.                             (long FAR *)&dwSUBound
  383.                             );
  384.     BAIL_ON_FAILURE(hr);
  385.  
  386.  
  387.     pContigFilter = (LPBYTE)AllocProvMem(
  388.                             sizeof(DS_FILTER_LIST)
  389.                             - sizeof(DS_FILTER)
  390.                             );
  391.     if (!pContigFilter) {
  392.  
  393.         hr = E_FAIL;
  394.         BAIL_ON_FAILURE(hr);
  395.     }
  396.  
  397.  
  398.     for (i = dwSLBound; i <= dwSUBound; i++) {
  399.         VariantInit(&v);
  400.         hr = SafeArrayGetElement(V_ARRAY(&var),
  401.                                 (long FAR *)&i,
  402.                                 &v
  403.                                 );
  404.         if (FAILED(hr)) {
  405.             continue;
  406.         }
  407.  
  408.         //
  409.         //  Create an entry in the filter block
  410.         //  Append it to the existing block
  411.         //
  412.  
  413.         pContigFilter = CreateAndAppendFilterEntry(
  414.                             pContigFilter,
  415.                             V_BSTR(&v)
  416.                             );
  417.         if (!pContigFilter) {
  418.  
  419.             hr = E_FAIL;
  420.             BAIL_ON_FAILURE(hr);
  421.         }
  422.  
  423.     }
  424.  
  425.     pDsFilterList = (LPDS_FILTER_LIST)pContigFilter;
  426.  
  427.     if (!pDsFilterList->dwNumberOfFilters){
  428.  
  429.         hr = E_FAIL;
  430.         BAIL_ON_FAILURE(hr);
  431.     }
  432.  
  433.     *ppContigFilter = pContigFilter;
  434.  
  435.     RRETURN(S_OK);
  436.  
  437. error:
  438.  
  439.     if (pContigFilter){
  440.  
  441.         FreeFilterList(
  442.                pContigFilter
  443.                );
  444.  
  445.     }
  446.  
  447.     *ppContigFilter = NULL;
  448.  
  449.     RRETURN(hr);
  450. }
  451.  
  452. LPBYTE
  453. CreateAndAppendFilterEntry(
  454.     LPBYTE pContigFilter,
  455.     LPWSTR lpObjectClass
  456.     )
  457. {
  458.     LPWSTR pszFilter = NULL;
  459.     LPDS_FILTER_LIST pDsFilterList = NULL;
  460.     DWORD dwFilterCount = 0;
  461.     LPBYTE pNewContigFilter = NULL;
  462.     LPDS_FILTER pNewEntry = NULL;
  463.  
  464.  
  465.     pszFilter = (LPWSTR)AllocProvStr(lpObjectClass);
  466.     if (!pszFilter) {
  467.         return(pContigFilter);
  468.     }
  469.  
  470.     pDsFilterList = (LPDS_FILTER_LIST)pContigFilter;
  471.  
  472.     dwFilterCount = pDsFilterList->dwNumberOfFilters;
  473.  
  474.     pNewContigFilter = (LPBYTE)ReallocProvMem(
  475.                                     pContigFilter,
  476.  
  477.                                     sizeof(DS_FILTER_LIST) +
  478.                                     (dwFilterCount - 1)* sizeof(DS_FILTER),
  479.  
  480.                                     sizeof(DS_FILTER_LIST)
  481.                                     + dwFilterCount * sizeof(DS_FILTER)
  482.                                     );
  483.     if (!pNewContigFilter) {
  484.         return(pContigFilter);
  485.     }
  486.  
  487.     pNewEntry = (LPDS_FILTER)(pNewContigFilter + sizeof(DS_FILTER_LIST)
  488.                         + (dwFilterCount - 1)* sizeof(DS_FILTER));
  489.  
  490.     pNewEntry->lpObjectClass = pszFilter;
  491.  
  492.     pDsFilterList = (LPDS_FILTER_LIST)pNewContigFilter;
  493.  
  494.     pDsFilterList->dwNumberOfFilters = dwFilterCount + 1;
  495.  
  496.     return(pNewContigFilter);
  497. }
  498.  
  499. void
  500. FreeFilterList(
  501.     LPBYTE lpContigFilter
  502.     )
  503. {
  504.     LPDS_FILTER_LIST lpDsFilterList = (LPDS_FILTER_LIST)lpContigFilter;
  505.     DWORD dwNumFilters = 0;
  506.     LPDS_FILTER lpDsFilter = NULL;
  507.     DWORD i = 0;
  508.  
  509.     dwNumFilters = lpDsFilterList->dwNumberOfFilters;
  510.  
  511.     if (dwNumFilters){
  512.  
  513.         lpDsFilter = (LPDS_FILTER)(lpContigFilter  + sizeof(DS_FILTER_LIST)
  514.                                       - sizeof(DS_FILTER));
  515.  
  516.         for (i = 0; i < dwNumFilters; i++) {
  517.  
  518.             FreeProvStr((lpDsFilter + i)->lpObjectClass);
  519.         }
  520.  
  521.     }
  522.  
  523.     FreeProvMem(lpContigFilter);
  524. }
  525.  
  526.  
  527.