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

Windows编程

开发平台:

Visual C++

  1. /*++ 
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4.     CGenObj.cpp
  5. Abstract:
  6.     Microsoft ADs DS Provider Generic Object
  7. Author:
  8. Environment:
  9.     User mode
  10. Revision History :
  11. --*/
  12. #include "adssmp.h"
  13. #pragma hdrstop
  14. DEFINE_IDispatch_Implementation(CSampleDSGenObject)
  15. DEFINE_IADs_Implementation(CSampleDSGenObject)
  16. CSampleDSGenObject::CSampleDSGenObject():_pPropertyCache(NULL)
  17. {
  18.     VariantInit(&_vFilter);
  19. }
  20. HRESULT
  21. CSampleDSGenObject::CreateGenericObject(
  22.     BSTR Parent,
  23.     BSTR CommonName,
  24.     BSTR ClassName,
  25.     DWORD dwObjectState,
  26.     REFIID riid,
  27.     void **ppvObj
  28.     )
  29. {
  30.     CSampleDSGenObject FAR * pGenObject = NULL;
  31.     HRESULT hr = S_OK;
  32.     hr = AllocateGenObject(&pGenObject);
  33.     BAIL_ON_FAILURE(hr);
  34.     hr = pGenObject->InitializeCoreObject(
  35.                 Parent,
  36.                 CommonName,
  37.                 ClassName,
  38.                 L"",
  39.                 CLSID_SampleDSGenObject,
  40.                 dwObjectState
  41.                 );
  42.     BAIL_ON_FAILURE(hr);
  43.     hr = pGenObject->QueryInterface(riid, ppvObj);
  44.     BAIL_ON_FAILURE(hr);
  45.     pGenObject->Release();
  46.     RRETURN(hr);
  47. error:
  48.     delete pGenObject;
  49.     RRETURN(hr);
  50. }
  51. CSampleDSGenObject::~CSampleDSGenObject( )
  52. {
  53.     delete _pDispMgr;
  54.     delete _pPropertyCache;
  55. }
  56. STDMETHODIMP
  57. CSampleDSGenObject::QueryInterface(REFIID iid, LPVOID FAR* ppv)
  58. {
  59.     if (IsEqualIID(iid, IID_IUnknown))
  60.     {
  61.         *ppv = (IADs FAR *) this;
  62.     }
  63.     else if (IsEqualIID(iid, IID_IADsContainer))
  64.     {
  65.         *ppv = (IADsContainer FAR *) this;
  66.     }
  67.     else if (IsEqualIID(iid, IID_IADs))
  68.     {
  69.         *ppv = (IADs FAR *) this;
  70.     }
  71.     else if (IsEqualIID(iid, IID_IDispatch))
  72.     {
  73.         *ppv = (IADs FAR *) this;
  74.     }
  75.     else
  76.     {
  77.         *ppv = NULL;
  78.         return E_NOINTERFACE;
  79.     }
  80.     AddRef();
  81.     return NOERROR;
  82. }
  83. HRESULT
  84. CSampleDSGenObject::SetInfo()
  85. {
  86.     HRESULT hr = S_OK;
  87.     if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  88.         hr = SampleDSCreateObject();
  89.         BAIL_ON_FAILURE(hr);
  90.         //
  91.         // If the create succeded, set the object type to bound
  92.         //
  93.         SetObjectState(ADS_OBJECT_BOUND);
  94.     }else {
  95.         hr = SampleDSSetObject();
  96.         BAIL_ON_FAILURE(hr);
  97.     }
  98. error:
  99.     RRETURN(hr);
  100. }
  101. HRESULT
  102. CSampleDSGenObject::SampleDSSetObject()
  103. {
  104.     WCHAR szSampleDSPathName[MAX_PATH];
  105.     HANDLE hObject = NULL;
  106.     HRESULT hr = S_OK;
  107.     HANDLE hOperationData = NULL;
  108.     hr = BuildDSPathFromADsPath(
  109.                 _ADsPath,
  110.                 szSampleDSPathName
  111.                 );
  112.     BAIL_ON_FAILURE(hr);
  113.     
  114.     hr = SampleDSOpenObject(
  115.                     szSampleDSPathName,
  116.                     &hObject,
  117.                     NULL,
  118.                     REG_DS
  119.                     );
  120.     BAIL_ON_FAILURE(hr);
  121.     hr = SampleDSCreateBuffer(&hOperationData);
  122.     BAIL_ON_FAILURE(hr);
  123.     
  124.     hr = _pPropertyCache->SampleDSMarshallProperties(
  125.                             hOperationData
  126.                             );
  127.     
  128.     BAIL_ON_FAILURE(hr);
  129.     hr = SampleDSModifyObject(hObject,
  130.                               hOperationData
  131.                              );
  132. error:
  133.     if (hObject) {
  134.         hr = SampleDSCloseObject(hObject);
  135.     }
  136.     if (hOperationData) {
  137.         SampleDSFreeBuffer(hOperationData);
  138.     }
  139.     RRETURN(hr);
  140. }
  141. HRESULT
  142. CSampleDSGenObject::SampleDSCreateObject()
  143. {
  144.     WCHAR szSampleDSParentName[MAX_PATH];
  145.     HANDLE hOperationData = NULL;
  146.     HANDLE hObject = NULL;
  147.     HRESULT hr = S_OK;
  148.     hr = BuildDSPathFromADsPath(
  149.                 _Parent,
  150.                 szSampleDSParentName
  151.                 );
  152.     BAIL_ON_FAILURE(hr);
  153.     hr = SampleDSOpenObject(
  154.                     szSampleDSParentName,
  155.                     &hObject,
  156.                     NULL,
  157.                     REG_DS
  158.                     );
  159.     BAIL_ON_FAILURE(hr);
  160.     hr = SampleDSCreateBuffer(&hOperationData);
  161.     BAIL_ON_FAILURE(hr);
  162.     
  163.     hr = _pPropertyCache->SampleDSMarshallProperties(
  164.                             hOperationData
  165.                             );
  166.     BAIL_ON_FAILURE(hr);
  167.     
  168.     hr = SampleDSAddObject(
  169.                 hObject,
  170.                 _Name,
  171.                 _ADsClass,
  172.                 hOperationData
  173.                 );
  174.     
  175. error:
  176.     if (hObject) {
  177.         hr = SampleDSCloseObject(hObject);
  178.     }
  179.     if (hOperationData) {
  180.         SampleDSFreeBuffer(hOperationData);
  181.     }
  182.     RRETURN(hr);
  183. }
  184. HRESULT
  185. CSampleDSGenObject::GetInfo()
  186. {
  187.     RRETURN(GetInfo(TRUE));
  188. }
  189. HRESULT
  190. CSampleDSGenObject::GetInfo(
  191.     BOOL fExplicit
  192. ){
  193.     HANDLE hObject = NULL;
  194.     HRESULT hr = S_OK;
  195.     WCHAR szDSPathName[MAX_PATH];
  196.     HANDLE hOperationData = NULL;
  197.     if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  198.         hr = E_ADS_OBJECT_UNBOUND;
  199.         BAIL_ON_FAILURE(hr);
  200.     }
  201.     hr = BuildDSPathFromADsPath(
  202.                 _ADsPath,
  203.                 szDSPathName
  204.                 );
  205.     BAIL_ON_FAILURE(hr);
  206.     hr = SampleDSOpenObject(
  207.                     szDSPathName,
  208.                     &hObject,
  209.                     NULL,
  210.                     REG_DS
  211.                     );
  212.     BAIL_ON_FAILURE(hr);
  213.     hr = SampleDSReadObject(
  214.         hObject,
  215.         &hOperationData
  216.     );
  217.     BAIL_ON_FAILURE(hr);
  218.             
  219.     hr = _pPropertyCache->SampleDSUnMarshallProperties(hOperationData,
  220.                                                        fExplicit
  221.                                                        );
  222.     BAIL_ON_FAILURE(hr);
  223. error:
  224.     if (hObject) {
  225.         hr = SampleDSCloseObject(hObject);
  226.     }
  227.     if (hOperationData) {
  228.         SampleDSFreeBuffer(hOperationData);
  229.     }
  230.     RRETURN(hr);
  231. }
  232. /* IADsContainer methods */
  233. STDMETHODIMP
  234. CSampleDSGenObject::get_Count(long FAR* retval)
  235. {
  236.     RRETURN(E_NOTIMPL);
  237. }
  238. STDMETHODIMP
  239. CSampleDSGenObject::get_Filter(THIS_ VARIANT FAR* pVar)
  240. {
  241.     VariantInit(pVar);
  242.     RRETURN(VariantCopy(pVar, &_vFilter));
  243. }
  244. STDMETHODIMP
  245. CSampleDSGenObject::put_Filter(THIS_ VARIANT Var)
  246. {
  247.     RRETURN(VariantCopy(&_vFilter, &Var));
  248. }
  249. STDMETHODIMP
  250. CSampleDSGenObject::put_Hints(THIS_ VARIANT Var)
  251. {
  252.     RRETURN( E_NOTIMPL);
  253. }
  254. STDMETHODIMP
  255. CSampleDSGenObject::get_Hints(THIS_ VARIANT FAR* pVar)
  256. {
  257.     RRETURN(E_NOTIMPL);
  258. }
  259. STDMETHODIMP
  260. CSampleDSGenObject::GetObject(
  261.     BSTR ClassName,
  262.     BSTR RelativeName,
  263.     IDispatch * FAR* ppObject
  264.     )
  265. {
  266.     RRETURN(::RelativeGetObject(_ADsPath,
  267.                                 ClassName,
  268.                                 RelativeName,
  269.                                 ppObject,
  270.                                 FALSE));
  271. }
  272. STDMETHODIMP
  273. CSampleDSGenObject::get__NewEnum(
  274.     THIS_ IUnknown * FAR* retval
  275.     )
  276. {
  277.     HRESULT hr;
  278.     IUnknown FAR* punkEnum=NULL;
  279.     IEnumVARIANT * penum = NULL;
  280.     *retval = NULL;
  281.     hr = CSampleDSGenObjectEnum::Create(
  282.                 (CSampleDSGenObjectEnum **)&penum,
  283.                 _ADsPath,
  284.                 _vFilter
  285.                 );
  286.     BAIL_ON_FAILURE(hr);
  287.     hr = penum->QueryInterface(
  288.                 IID_IUnknown,
  289.                 (VOID FAR* FAR*)retval
  290.                 );
  291.     BAIL_ON_FAILURE(hr);
  292.     if (penum) {
  293.         penum->Release();
  294.     }
  295.     RRETURN(NOERROR);
  296. error:
  297.     if (penum) {
  298.         delete penum;
  299.     }
  300.     RRETURN(hr);
  301. }
  302. STDMETHODIMP
  303. CSampleDSGenObject::Create(
  304.     THIS_ BSTR ClassName,
  305.     BSTR RelativeName,
  306.     IDispatch * FAR* ppObject
  307.     )
  308. {
  309.     HRESULT hr = S_OK;
  310.     IADs * pADs  = NULL;
  311.     WCHAR szDSTreeName[MAX_PATH];
  312.     DWORD dwSyntaxId = 0;
  313.     //
  314.     // Get the TreeName for this object
  315.     //
  316.     hr = BuildDSTreeNameFromADsPath(
  317.                 _ADsPath,
  318.                 szDSTreeName
  319.                 );
  320.     BAIL_ON_FAILURE(hr);
  321.     //
  322.     // Validate if this class really exists in the schema
  323.     // and validate that this object can be created in this
  324.     // container
  325.     //
  326.     hr = CSampleDSGenObject::CreateGenericObject(
  327.                     _ADsPath,
  328.                     RelativeName,
  329.                     ClassName,
  330.                     ADS_OBJECT_UNBOUND,
  331.                     IID_IDispatch,
  332.                     (void **)ppObject
  333.                     );
  334.     BAIL_ON_FAILURE(hr);
  335. error:
  336.     RRETURN(hr);
  337. }
  338. STDMETHODIMP
  339. CSampleDSGenObject::Delete(
  340.     THIS_ BSTR bstrClassName,
  341.     BSTR bstrRelativeName
  342.     )
  343. {
  344.     WCHAR szDSPathName[MAX_PATH];
  345.     HRESULT hr = S_OK;
  346.     DWORD dwStatus = 0;
  347.     HANDLE hParentObject = NULL;
  348.     hr = BuildDSPathFromADsPath(
  349.                 _ADsPath,
  350.                 szDSPathName
  351.                 );
  352.     BAIL_ON_FAILURE(hr);
  353.     
  354.     hr = SampleDSOpenObject(
  355.                     szDSPathName,
  356.                     &hParentObject,
  357.                     NULL,
  358.                     REG_DS
  359.                     );
  360.     BAIL_ON_FAILURE(hr);
  361.     hr= SampleDSRemoveObject(
  362.                 hParentObject,
  363.                 bstrRelativeName);
  364.     BAIL_ON_FAILURE(hr);
  365. error:
  366.     if (hParentObject) {
  367.         dwStatus = SampleDSCloseObject(hParentObject);
  368.     }
  369.     RRETURN(hr);
  370. }
  371. STDMETHODIMP
  372. CSampleDSGenObject::CopyHere(
  373.     THIS_ BSTR SourceName,
  374.     BSTR NewName,
  375.     IDispatch * FAR* ppObject
  376.     )
  377. {
  378.     RRETURN(E_NOTIMPL);
  379. }
  380. STDMETHODIMP
  381. CSampleDSGenObject::MoveHere(
  382.     THIS_ BSTR SourceName,
  383.     BSTR NewName,
  384.     IDispatch * FAR* ppObject
  385.     )
  386. {
  387.     RRETURN(E_NOTIMPL);
  388. }
  389. HRESULT
  390. CSampleDSGenObject::AllocateGenObject(CSampleDSGenObject ** ppGenObject)
  391. {
  392.     CSampleDSGenObject FAR * pGenObject = NULL;
  393.     CDispatchMgr FAR * pDispMgr = NULL;
  394.     CPropertyCache FAR * pPropertyCache = NULL;
  395.     HRESULT hr = S_OK;
  396.     pGenObject = new CSampleDSGenObject();
  397.     if (pGenObject == NULL) {
  398.         hr = E_OUTOFMEMORY;
  399.     }
  400.     BAIL_ON_FAILURE(hr);
  401.     pDispMgr = new CDispatchMgr;
  402.     if (pDispMgr == NULL) {
  403.         hr = E_OUTOFMEMORY;
  404.     }
  405.     BAIL_ON_FAILURE(hr);
  406.     hr = LoadTypeInfoEntry(pDispMgr,
  407.                            LIBID_ADs,
  408.                            IID_IADs,
  409.                            (IADs *)pGenObject,
  410.                            DISPID_REGULAR
  411.                            );
  412.     BAIL_ON_FAILURE(hr);
  413.     hr = LoadTypeInfoEntry(pDispMgr,
  414.                            LIBID_ADs,
  415.                            IID_IADsContainer,
  416.                            (IADsContainer *)pGenObject,
  417.                            DISPID_NEWENUM
  418.                            );
  419.     BAIL_ON_FAILURE(hr);
  420.     hr = CPropertyCache::createpropertycache(
  421.                         (CCoreADsObject FAR *)pGenObject,
  422.                         &pPropertyCache
  423.                         );
  424.     BAIL_ON_FAILURE(hr);
  425.     pGenObject->_pPropertyCache = pPropertyCache;
  426.     pGenObject->_pDispMgr = pDispMgr;
  427.     *ppGenObject = pGenObject;
  428.     
  429.     RRETURN(hr);
  430. error:
  431.     delete  pDispMgr;
  432.     RRETURN(hr);
  433. }
  434. STDMETHODIMP
  435. CSampleDSGenObject::Get(
  436.     THIS_ BSTR bstrName,
  437.     VARIANT FAR* pvProp
  438.     )
  439. {
  440.     HRESULT hr = S_OK;
  441.     DWORD dwSyntaxId;
  442.     DWORD dwNumValues;
  443.     LPSampleDSOBJECT pNdsSrcObjects = NULL;
  444.     //
  445.     // retrieve data object from cache; if one exists
  446.     //
  447.     if (GetObjectState() == ADS_OBJECT_UNBOUND) {
  448.         hr = _pPropertyCache->unboundgetproperty(
  449.                     bstrName,
  450.                     &dwSyntaxId,
  451.                     &dwNumValues,
  452.                     &pNdsSrcObjects
  453.                     );
  454.         BAIL_ON_FAILURE(hr);
  455.     }else {
  456.         hr = _pPropertyCache->getproperty(
  457.                     bstrName,
  458.                     &dwSyntaxId,
  459.                     &dwNumValues,
  460.                     &pNdsSrcObjects
  461.                     );
  462.         BAIL_ON_FAILURE(hr);
  463.     }
  464.     //
  465.     // translate the Nds objects to variants
  466.     //
  467.     hr = SampleDSTypeToVarTypeCopyConstruct(
  468.                 pNdsSrcObjects,
  469.                 dwNumValues,
  470.                 pvProp
  471.                 );
  472.     BAIL_ON_FAILURE(hr);
  473. error:
  474.     if (pNdsSrcObjects) {
  475.         SampleDSTypeFreeSampleDSObjects(
  476.             pNdsSrcObjects,
  477.             dwNumValues
  478.             );
  479.     }
  480.     RRETURN(hr);
  481. }
  482. STDMETHODIMP
  483. CSampleDSGenObject::Put(
  484.     THIS_ BSTR bstrName,
  485.     VARIANT vProp
  486.     )
  487. {
  488.     HRESULT hr = S_OK;
  489.     DWORD dwSyntaxId  = 0;
  490.     DWORD dwIndex = 0;
  491.     LPSampleDSOBJECT pNdsDestObjects = NULL;
  492.     WCHAR szSampleDSTreeName[MAX_PATH];
  493.     DWORD dwNumValues = 0;
  494.     VARIANT * pVarArray = NULL;
  495.     VARIANT * pvProp = NULL;
  496.     //
  497.     // Issue: How do we handle multi-valued support
  498.     //
  499.     if ((V_VT(&vProp) &  VT_VARIANT) &&  V_ISARRAY(&vProp)) {
  500.         hr  = ConvertSafeArrayToVariantArray(
  501.                     vProp,
  502.                     &pVarArray,
  503.                     &dwNumValues
  504.                     );
  505.         BAIL_ON_FAILURE(hr);
  506.         pvProp = pVarArray;
  507.     }else {
  508.         dwNumValues = 1;
  509.         pvProp = &vProp;
  510.     }
  511.     //
  512.     // Get the TreeName for this object
  513.     //
  514.     hr = BuildDSPathFromADsPath(
  515.                 _ADsPath,
  516.                 szSampleDSTreeName
  517.                 );
  518.     BAIL_ON_FAILURE(hr);
  519.     
  520.     //
  521.     // check if the variant maps to the syntax of this property
  522.     //
  523.     switch (vProp.vt) {
  524.         case VT_BSTR:
  525.                 dwSyntaxId = SampleDS_DATATYPE_1;
  526.                 break;
  527.         case VT_I4:
  528.                 dwSyntaxId = SampleDS_DATATYPE_2;
  529.                 break;
  530.         default:
  531.                 hr = E_FAIL;
  532.                 goto error;
  533.         }
  534.                 hr = VarTypeToSampleDSTypeCopyConstruct(
  535.                     dwSyntaxId,
  536.                     pvProp,
  537.                     dwNumValues,
  538.                     &pNdsDestObjects
  539.                     );
  540.     BAIL_ON_FAILURE(hr);
  541.     //
  542.     // Find this property in the cache
  543.     //
  544.     hr = _pPropertyCache->findproperty(
  545.                         bstrName,
  546.                         &dwIndex
  547.                         );
  548.     //
  549.     // If this property does not exist in the
  550.     // cache, add this property into the cache.
  551.     //
  552.     if (FAILED(hr)) {
  553.         hr = _pPropertyCache->addproperty(
  554.                     bstrName,
  555.                     dwSyntaxId,
  556.                     dwNumValues,
  557.                     pNdsDestObjects
  558.                     );
  559.         //
  560.         // If the operation fails for some reason
  561.         // move on to the next property
  562.         //
  563.         BAIL_ON_FAILURE(hr);
  564.     }
  565.     //
  566.     // Now update the property in the cache
  567.     //
  568.     hr = _pPropertyCache->putproperty(
  569.                     bstrName,
  570.                     dwSyntaxId,
  571.                     dwNumValues,
  572.                     pNdsDestObjects
  573.                     );
  574.     BAIL_ON_FAILURE(hr);
  575. error:
  576.     if (pNdsDestObjects) {
  577.         SampleDSTypeFreeSampleDSObjects(
  578.                 pNdsDestObjects,
  579.                 dwNumValues
  580.                 );
  581.     }
  582.     if (pVarArray) {
  583.         DWORD i = 0;
  584.         for (i = 0; i < dwNumValues; i++) {
  585.             VariantClear(pVarArray + i);
  586.         }
  587.         FreeProvMem(pVarArray);
  588.     }
  589.     RRETURN(hr);
  590. }
  591. HRESULT
  592. ConvertSafeArrayToVariantArray(
  593.     VARIANT varSafeArray,
  594.     VARIANT ** ppVarArray,
  595.     PDWORD pdwNumVariants
  596.     )
  597. {
  598.     HRESULT hr = S_OK;
  599.     DWORD dwSLBound = 0;
  600.     DWORD dwSUBound = 0;
  601.     DWORD i = 0;
  602.     DWORD dwNumVariants = 0;
  603.     VARIANT * pVarArray = NULL;
  604.     *pdwNumVariants = 0;
  605.     *ppVarArray  = 0;
  606.     if(!((V_VT(&varSafeArray) &  VT_VARIANT) &&  V_ISARRAY(&varSafeArray))) {
  607.         return(E_FAIL);
  608.     }
  609.     //
  610.     // Check that there is only one dimension in this array
  611.     //
  612.     if ((V_ARRAY(&varSafeArray))->cDims != 1) {
  613.         hr = E_FAIL;
  614.         BAIL_ON_FAILURE(hr);
  615.     }
  616.     //
  617.     // Check that there is atleast one element in this array
  618.     //
  619.     if ((V_ARRAY(&varSafeArray))->rgsabound[0].cElements == 0){
  620.         hr = E_FAIL;
  621.         BAIL_ON_FAILURE(hr);
  622.     }
  623.     hr = SafeArrayGetLBound(V_ARRAY(&varSafeArray),
  624.                             1,
  625.                             (long FAR *)&dwSLBound
  626.                             );
  627.     BAIL_ON_FAILURE(hr);
  628.     hr = SafeArrayGetUBound(V_ARRAY(&varSafeArray),
  629.                             1,
  630.                             (long FAR *)&dwSUBound
  631.                             );
  632.     BAIL_ON_FAILURE(hr);
  633.     dwNumVariants = dwSUBound - dwSLBound + 1;
  634.     pVarArray = (VARIANT*)AllocProvMem(
  635.                                 sizeof(VARIANT)*dwNumVariants
  636.                                 );
  637.     if (!pVarArray) {
  638.         hr = E_OUTOFMEMORY;
  639.         BAIL_ON_FAILURE(hr);
  640.     }
  641.     for (i = dwSLBound; i <= dwSUBound; i++) {
  642.         VariantInit(pVarArray + i);
  643.         hr = SafeArrayGetElement(V_ARRAY(&varSafeArray),
  644.                                 (long FAR *)&i,
  645.                                 (pVarArray + i)
  646.                                 );
  647.         CONTINUE_ON_FAILURE(hr);
  648.     }
  649.     *ppVarArray = pVarArray;
  650.     *pdwNumVariants = dwNumVariants;
  651. error:
  652.     RRETURN(hr);
  653. }