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 / getobj.cpp < prev    next >
C/C++ Source or Header  |  1997-07-29  |  21KB  |  931 lines

  1. /*++
  2.  
  3. Copyright (c) 1996 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     GetObj.cpp
  8.  
  9. Abstract:
  10.  
  11.     Sample Provider GetObject 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. //  Function:   RelativeGetObject
  27. //
  28. //  Synopsis:   Gets object relative to given OLE DS path.
  29. //
  30. //  Arguments:  [BSTR ADsPath]
  31. //              [BSTR ClassName]
  32. //              [BSTR RelativeName]
  33. //              [IUnknown** ppObject]
  34. //              [BOOT bNamespaceRelative]
  35. //
  36. //  Returns:    HRESULT
  37. //
  38. //  Modifies:   *ppObject
  39. //
  40. //----------------------------------------------------------------------------
  41. HRESULT
  42. RelativeGetObject(
  43.     BSTR ADsPath,
  44.     BSTR ClassName,
  45.     BSTR RelativeName,
  46.     IDispatch* FAR* ppObject,
  47.     BOOL bNamespaceRelative
  48.     )
  49. {
  50.     WCHAR szBuffer[MAX_PATH];
  51.     HRESULT hr = S_OK;
  52.  
  53.     *ppObject = NULL;
  54.  
  55.     if (!RelativeName || !*RelativeName) {
  56.         RRETURN(E_ADS_UNKNOWN_OBJECT);
  57.     }
  58.  
  59.     wcscpy(szBuffer, ADsPath);
  60.  
  61.     if (bNamespaceRelative)
  62.         wcscat(szBuffer, L"//");
  63.     else
  64.         wcscat(szBuffer, L"/");
  65.     wcscat(szBuffer, RelativeName);
  66.  
  67.     if (ClassName && *ClassName) {
  68.         wcscat(szBuffer,L",");
  69.         wcscat(szBuffer, ClassName);
  70.     }
  71.  
  72.     hr = ::GetObject(
  73.                 szBuffer,
  74.                 (LPVOID *)ppObject
  75.                 );
  76.     BAIL_ON_FAILURE(hr);
  77.  
  78. error:
  79.     RRETURN(hr);
  80. }
  81.  
  82. //+---------------------------------------------------------------------------
  83. //  Function:  GetObject
  84. //
  85. //  Synopsis:  Called by ResolvePathName to return an object
  86. //
  87. //  Arguments:  [LPWSTR szBuffer]
  88. //              [LPVOID *ppObject]
  89. //
  90. //  Returns:    HRESULT
  91. //
  92.  
  93. //----------------------------------------------------------------------------
  94. HRESULT
  95. GetObject(
  96.     LPWSTR szBuffer,
  97.     LPVOID * ppObject
  98.     )
  99. {
  100.     HRESULT hr;
  101.     DWORD dwStatus = NO_ERROR;
  102.     DWORD dwNumberEntries = 0;
  103.     DWORD dwModificationTime = 0;
  104.     WCHAR szObjectClassName[MAX_PATH];
  105.     WCHAR szDSPath[MAX_PATH];
  106.     WCHAR szParent[MAX_PATH];
  107.     WCHAR szCommonName[MAX_PATH];
  108.     HANDLE hObject = NULL;
  109.  
  110.     OBJECTINFO ObjectInfo;
  111.     POBJECTINFO pObjectInfo = &ObjectInfo;
  112.     CLexer Lexer(szBuffer);
  113.  
  114.     IADs * pADs = NULL;
  115.     szObjectClassName[0]=L'\0';
  116.  
  117.     memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  118.     hr = ADsObject(&Lexer, pObjectInfo);
  119.     BAIL_ON_FAILURE(hr);
  120.  
  121.     //
  122.     // Validate that this ADs pathname is to be processed by
  123.     // us - as in the provider name is @Sample!
  124.     //
  125.  
  126.     hr = ValidateProvider(pObjectInfo);
  127.     BAIL_ON_FAILURE(hr);
  128.  
  129.  
  130.  
  131.     hr = ValidateObjectType(pObjectInfo);
  132.  
  133.     switch (pObjectInfo->ObjectType) {
  134.  
  135.     case TOKEN_NAMESPACE:
  136.         //
  137.         // This means that this is a namespace object;
  138.         // instantiate the namespace object
  139.         //
  140.  
  141.         hr = GetNamespaceObject(
  142.                 pObjectInfo,
  143.                 ppObject
  144.                 );
  145.         BAIL_ON_FAILURE(hr);
  146.  
  147.         break;
  148.  
  149.     case TOKEN_SCHEMA:
  150.  
  151.         hr = GetSchemaObject(
  152.                 pObjectInfo,
  153.                 ppObject
  154.                 );
  155.         BAIL_ON_FAILURE(hr);
  156.  
  157.         break;
  158.     
  159.     default:
  160.         hr = BuildDSPathFromADsPath(
  161.                     szBuffer,
  162.                     szDSPath
  163.                     );
  164.         BAIL_ON_FAILURE(hr);
  165.  
  166.         hr  = SampleDSOpenObject(
  167.                         szDSPath,
  168.                         &hObject,
  169.                         szObjectClassName,
  170.                         REG_DS);
  171.         BAIL_ON_FAILURE(hr);
  172.  
  173.         hr = BuildADsParentPath(
  174.                     szBuffer,
  175.                     szParent,
  176.                     szCommonName
  177.                     );
  178.         BAIL_ON_FAILURE(hr);
  179.  
  180.         hr = CSampleDSGenObject::CreateGenericObject(
  181.                         szParent,
  182.                         szCommonName,
  183.                         szObjectClassName,
  184.                         ADS_OBJECT_BOUND,
  185.                         IID_IUnknown,
  186.                         (void**)ppObject
  187.                         );
  188.         BAIL_ON_FAILURE(hr);
  189.         break;
  190.  
  191.     }
  192.  
  193. error:
  194.  
  195.     if (pADs) {
  196.         pADs->Release();
  197.     }
  198.     if (hObject) {
  199.         SampleDSCloseObject(hObject);
  200.     }
  201.  
  202.     RRETURN(hr);
  203. }
  204.  
  205.  
  206.  
  207. HRESULT
  208. BuildADsPathFromDSPath(
  209.     LPWSTR szDSRootRDN,
  210.     LPWSTR szDSDNName,
  211.     LPWSTR szADsPathName
  212.     )
  213. {
  214.     PKEYDATA pKeyData = NULL;
  215.     DWORD dwCount = 0;
  216.     DWORD i = 0;
  217.  
  218.     if (!szDSRootRDN || !szDSDNName) {
  219.         RRETURN(E_FAIL);
  220.     }
  221.  
  222.     wsprintf(szADsPathName,L"%s:%s", g_szProviderName, szDSRootRDN);
  223.  
  224.     pKeyData = CreateTokenList(
  225.                     szDSDNName,
  226.                     L'.'
  227.                     );
  228.  
  229.     if (pKeyData) {
  230.  
  231.         dwCount = pKeyData->cTokens;
  232.         for (i = 0; i < dwCount; i++) {
  233.             wcscat(szADsPathName, L"/");
  234.             wcscat(szADsPathName, pKeyData->pTokens[dwCount - 1 - i]);
  235.         }
  236.     }
  237.  
  238.     if (pKeyData) {
  239.         FreeProvMem(pKeyData);
  240.     }
  241.     RRETURN(S_OK);
  242. }
  243.  
  244. HRESULT
  245. BuildDSTreeNameFromADsPath(
  246.     LPWSTR szBuffer,
  247.     LPWSTR szSampleDSTreeName
  248.     )
  249. {
  250.     OBJECTINFO ObjectInfo;
  251.     POBJECTINFO pObjectInfo = &ObjectInfo;
  252.     CLexer Lexer(szBuffer);
  253.     DWORD dwNumComponents = 0;
  254.     HRESULT hr;
  255.  
  256.     memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  257.     hr = ADsObject(&Lexer, pObjectInfo);
  258.     BAIL_ON_FAILURE(hr);
  259.  
  260.     dwNumComponents = pObjectInfo->NumComponents;
  261.  
  262.  
  263.     if (!dwNumComponents && !pObjectInfo->RootRDN) {
  264.         //
  265.         // There are no CNs in this pathname and
  266.         // no tree name specified. This is the
  267.         // namespace object - its parent is the
  268.         // @ADs! object
  269.         //
  270.  
  271.         hr = E_FAIL;
  272.  
  273.     } else if (!dwNumComponents && pObjectInfo->RootRDN) {
  274.         //
  275.         // There are no CNs in this pathname and a tree
  276.         // name has been specified. This is the root
  277.         // object - its parent is the  @SampleDS! object
  278.  
  279.         wsprintf(szSampleDSTreeName,L"\\\\%s", pObjectInfo->RootRDN);
  280.  
  281.  
  282.         hr = S_OK;
  283.  
  284.     }else {
  285.         //
  286.         // There are one or more CNs, a tree name has been
  287.         // specified. In the worst case the parent is the
  288.         // root object. In the best case a long CN.
  289.         //
  290.  
  291.         wsprintf(szSampleDSTreeName,L"\\\\%s", pObjectInfo->RootRDN);
  292.  
  293.         hr = S_OK;
  294.     }
  295.  
  296. error:
  297.     RRETURN(hr);
  298.  
  299. }
  300.  
  301. HRESULT
  302. BuildDSPathFromADsPath(
  303.     LPWSTR szADsPathName,
  304.     LPWSTR szDSPathName
  305.     )
  306. {
  307.     OBJECTINFO ObjectInfo;
  308.     POBJECTINFO pObjectInfo = &ObjectInfo;
  309.     CLexer Lexer(szADsPathName);
  310.     DWORD i = 0;
  311.     DWORD dwNumComponents = 0;
  312.     HRESULT hr;
  313.  
  314.     memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  315.     hr = ADsObject(&Lexer, pObjectInfo);
  316.     BAIL_ON_FAILURE(hr);
  317.  
  318.     dwNumComponents = pObjectInfo->NumComponents;
  319.  
  320.     wcscpy(szDSPathName, L"\\");
  321.     wcscat(szDSPathName, pObjectInfo->RootRDN);
  322.     
  323.     for (i = 0; i < dwNumComponents; i++) {
  324.         wcscat(szDSPathName, L"\\");
  325.                 wcscat(szDSPathName, pObjectInfo->ComponentArray[i].szComponent);
  326.     }
  327.  
  328. error:
  329.  
  330.     RRETURN(hr);
  331.  
  332. }
  333.  
  334. HRESULT
  335. AppendComponent(
  336.    LPWSTR szDSPathName,
  337.    PCOMPONENT pComponent
  338. ){
  339.         DebugBreak();
  340.     RRETURN(S_OK);
  341. }
  342.  
  343.  
  344.  
  345. HRESULT
  346. BuildADsParentPath(
  347.     LPWSTR szBuffer,
  348.     LPWSTR szParent,
  349.     LPWSTR szCommonName
  350.     )
  351. {
  352.     OBJECTINFO ObjectInfo;
  353.     POBJECTINFO pObjectInfo = &ObjectInfo;
  354.     CLexer Lexer(szBuffer);
  355.     DWORD i = 0;
  356.     DWORD dwNumComponents = 0;
  357.     HRESULT hr;
  358.     LPWSTR pszComponent = NULL, pszValue = NULL;
  359.  
  360.     memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  361.     hr = ADsObject(&Lexer, pObjectInfo);
  362.     BAIL_ON_FAILURE(hr);
  363.  
  364.     dwNumComponents = pObjectInfo->NumComponents;
  365.  
  366.  
  367.     if (!dwNumComponents && !pObjectInfo->RootRDN) {
  368.         //
  369.         // There are no CNs in this pathname and
  370.         // no Root name specified. This is the
  371.         // namespace object - its parent is the
  372.         // @ADs! object
  373.         //
  374.  
  375.         wsprintf(szParent,L"ADs:");
  376.  
  377.         RRETURN(S_OK);
  378.  
  379.     } else if (!dwNumComponents && pObjectInfo->RootRDN) {
  380.         //
  381.         // There are no CNs in this pathname and a Root
  382.         // name has been specified. This is the root
  383.         // object - its parent is the  @Sample! object
  384.  
  385.         wsprintf(szParent, L"%s:", pObjectInfo->ProviderName);
  386.  
  387.         //
  388.         // And the common name is the RootRDN
  389.         //
  390.  
  391.         wsprintf(szCommonName,L"%s", pObjectInfo->RootRDN);
  392.  
  393.  
  394.         RRETURN(S_OK);
  395.  
  396.  
  397.     }else {
  398.         //
  399.         // There are one or more CNs, a Root name has been
  400.         // specified. In the worst case the parent is the
  401.         // root object. In the best case a long CN.
  402.         //
  403.  
  404.         wsprintf(
  405.             szParent, L"%s://%s",
  406.             pObjectInfo->ProviderName,
  407.             pObjectInfo->RootRDN
  408.             );
  409.  
  410.         for (i = 0; i < dwNumComponents - 1; i++) {
  411.  
  412.             wcscat(szParent, L"/");
  413.  
  414.  
  415.             pszComponent =  pObjectInfo->ComponentArray[i].szComponent;
  416.             pszValue = pObjectInfo->ComponentArray[i].szValue;
  417.  
  418.  
  419.             if (pszComponent && pszValue) {
  420.  
  421.                 wcscat(
  422.                     szParent,
  423.                     pObjectInfo->ComponentArray[i].szComponent
  424.                     );
  425.                 wcscat(szParent,L"=");
  426.                 wcscat(
  427.                     szParent,
  428.                     pObjectInfo->ComponentArray[i].szValue
  429.                     );
  430.             }else if (pszComponent){
  431.  
  432.                 wcscat(
  433.                     szParent,
  434.                     pObjectInfo->ComponentArray[i].szComponent
  435.                     );
  436.  
  437.             }else {
  438.                 //
  439.                 // Error - we should never hit this case!!
  440.                 //
  441.  
  442.             }
  443.         }
  444.  
  445.         //
  446.         // And the common name is the last component
  447.         //
  448.  
  449.         pszComponent =  pObjectInfo->ComponentArray[dwNumComponents - 1].szComponent;
  450.         pszValue = pObjectInfo->ComponentArray[dwNumComponents - 1].szValue;
  451.  
  452.  
  453.         if (pszComponent && pszValue) {
  454.  
  455.             wsprintf(szCommonName, L"%s=%s",pszComponent, pszValue);
  456.  
  457.         }else if (pszComponent){
  458.  
  459.             wsprintf(szCommonName, L"%s", pszComponent);
  460.  
  461.         }else {
  462.             //
  463.             // Error - we should never hit this case!!
  464.             //
  465.  
  466.         }
  467.  
  468.     }
  469.  
  470. error:
  471.  
  472.     RRETURN(hr);
  473.  
  474. }
  475.  
  476. HRESULT
  477. InstantiateDerivedObject(
  478.     IADs FAR * pADs,
  479.     REFIID riid,
  480.     void  ** ppObject
  481.     )
  482. {
  483.         *ppObject = 0;
  484.  
  485.     RRETURN(S_OK);
  486. }
  487.  
  488.  
  489. //+---------------------------------------------------------------------------
  490. // Function:    GetNamespaceObject
  491. //
  492. // Synopsis:    called by GetObject
  493. //
  494. // Arguments:   [POBJECTINFO pObjectInfo]
  495. //              [LPVOID * ppObject]
  496. //
  497. // Returns:     HRESULT
  498. //
  499. //----------------------------------------------------------------------------
  500. HRESULT
  501. GetNamespaceObject(
  502.     POBJECTINFO pObjectInfo,
  503.     LPVOID * ppObject
  504.     )
  505. {
  506.     HRESULT hr;
  507.  
  508.     hr = ValidateNamespaceObject(
  509.                 pObjectInfo
  510.                 );
  511.     BAIL_ON_FAILURE(hr);
  512.  
  513.     hr = CoCreateInstance(CLSID_SampleDSNamespace,
  514.                           NULL,
  515.                           CLSCTX_INPROC_SERVER,
  516.                           IID_IUnknown,
  517.                           (void **)ppObject
  518.                           );
  519.  
  520. error:
  521.  
  522.     RRETURN(hr);
  523. }
  524.  
  525. HRESULT
  526. ValidateNamespaceObject(
  527.     POBJECTINFO pObjectInfo
  528.     )
  529. {
  530.  
  531.     if (!_wcsicmp(pObjectInfo->ProviderName, g_szProviderName)) {
  532.     }
  533.     RRETURN(S_OK);
  534. }
  535.  
  536.  
  537. HRESULT
  538. ValidateProvider(
  539.     POBJECTINFO pObjectInfo
  540.     )
  541. {
  542.  
  543.     //
  544.     // The provider name is case-sensitive.  This is a restriction that OLE
  545.     // has put on us.
  546.     //
  547.     if (!(wcscmp(pObjectInfo->ProviderName, g_szProviderName))) {
  548.         RRETURN(S_OK);
  549.     }
  550.     RRETURN(E_FAIL);
  551. }
  552.  
  553.  
  554.  
  555. //+---------------------------------------------------------------------------
  556. // Function:    GetSchemaObject
  557. //
  558. // Synopsis:    called by GetObject
  559. //
  560. // Arguments:   [POBJECTINFO pObjectInfo]
  561. //              [LPVOID * ppObject]
  562. //
  563. // Returns:     HRESULT
  564. //
  565. // Modifies:      -
  566. //
  567. //----------------------------------------------------------------------------
  568. HRESULT
  569. GetSchemaObject(
  570.     POBJECTINFO pObjectInfo,
  571.     LPVOID * ppObject
  572.     )
  573. {
  574.     HRESULT hr = S_OK;
  575.     WCHAR szParent[MAX_PATH];
  576.     WCHAR szCommonName[MAX_PATH];
  577.     WCHAR szSampleDSPathName[MAX_PATH];
  578.     DWORD dwObjectType = 0;
  579.     HANDLE hObject= NULL;
  580.  
  581.     hr = ValidateSchemaObject(
  582.                 pObjectInfo,
  583.                 &dwObjectType
  584.                 );
  585.     BAIL_ON_FAILURE(hr);
  586.  
  587.     hr = BuildADsParentPath(
  588.              pObjectInfo,
  589.              szParent,
  590.              szCommonName
  591.              );
  592.     BAIL_ON_FAILURE(hr);
  593.  
  594.     switch(dwObjectType) {
  595.     case SampleDS_CLASS_ID:
  596.     case SampleDS_PROPERTY_ID:
  597.     case SampleDS_CLASSPROP_ID:
  598.  
  599.         wcscpy(szSampleDSPathName, L"\\");
  600.         wcscat(szSampleDSPathName, szCommonName);
  601.         hr = SampleDSOpenObject(
  602.                         szSampleDSPathName,
  603.                         &hObject,
  604.                         NULL,
  605.                         REG_SCHEMA
  606.                         );
  607.         BAIL_ON_FAILURE(hr);
  608.         
  609.         break;
  610.  
  611.     default:
  612.         break;
  613.     }
  614.  
  615.     //
  616.     // Note: The "error:" tag is at the end of the switch statement,
  617.     //       so we can simply break out.
  618.     //
  619.  
  620.     switch (dwObjectType) {
  621.     case SampleDS_SCHEMA_ID:
  622.         hr = CSampleDSSchema::CreateSchema(
  623.                     szParent,
  624.                     szCommonName,
  625.                     ADS_OBJECT_BOUND,
  626.                     IID_IUnknown,
  627.                     ppObject
  628.                     );
  629.         break;
  630.     case SampleDS_CLASSPROP_ID:
  631.         hr = CSampleDSClass::CreateClass(
  632.                     szParent,
  633.                     szCommonName,
  634.                     hObject,
  635.                     ADS_OBJECT_BOUND,
  636.                     IID_IUnknown,
  637.                     ppObject
  638.                     );
  639.         if (FAILED(hr)) {
  640.             hr = CSampleDSProperty::CreateProperty(
  641.                                     szParent,
  642.                                     szCommonName,
  643.                                     hObject,
  644.                                     ADS_OBJECT_BOUND,
  645.                                     IID_IUnknown,
  646.                                     ppObject
  647.                                     );
  648.         }
  649.         break;
  650.  
  651.    default:
  652.         hr = E_ADS_UNKNOWN_OBJECT;
  653.         break;
  654.     }
  655.  
  656. error:
  657.     if (hObject) {
  658.         SampleDSCloseObject(hObject);
  659.     }
  660.     RRETURN(hr);
  661. }
  662.  
  663. HRESULT
  664. ValidateSchemaObject(
  665.     POBJECTINFO pObjectInfo,
  666.     PDWORD pdwObjectType
  667.     )
  668. {
  669.     DWORD dwNumComponents = 0;
  670.  
  671.     dwNumComponents = pObjectInfo->NumComponents;
  672.  
  673.     switch (dwNumComponents) {
  674.  
  675.     case 1:
  676.         if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent, L"schema")) {
  677.             *pdwObjectType = SampleDS_SCHEMA_ID;
  678.             RRETURN(S_OK);
  679.         }
  680.         break;
  681.  
  682.     case 2:
  683.         *pdwObjectType = SampleDS_CLASSPROP_ID;
  684.         RRETURN(S_OK);
  685.     
  686.     default:
  687.         break;
  688.  
  689.  
  690.     }
  691.  
  692.     RRETURN(E_FAIL);
  693. }
  694.  
  695. HRESULT
  696. BuildADsParentPath(
  697.     POBJECTINFO pObjectInfo,
  698.     LPWSTR szParent,
  699.     LPWSTR szCommonName
  700.     )
  701. {
  702.     DWORD i = 0;
  703.     DWORD dwNumComponents = 0;
  704.     LPWSTR pszComponent = NULL, pszValue = NULL;
  705.  
  706.     dwNumComponents = pObjectInfo->NumComponents;
  707.  
  708.     if (!dwNumComponents && !pObjectInfo->RootRDN) {
  709.         //
  710.         // There are no CNs in this pathname and
  711.         // no root name specified. This is the
  712.         // namespace object - its parent is the
  713.         // @ADs! object
  714.         //
  715.  
  716.         wsprintf(szParent,L"ADs:");
  717.  
  718.         RRETURN(S_OK);
  719.  
  720.     } else if (!dwNumComponents && pObjectInfo->RootRDN) {
  721.         //
  722.         // There are no CNs in this pathname and a root
  723.         // name has been specified. This is the root
  724.         // object - its parent is the  @Sample! object
  725.  
  726.         wsprintf(szParent, L"%s:", pObjectInfo->ProviderName);
  727.  
  728.         //
  729.         // And the common name is the RootRDN. Remember the
  730.         // "//" will be added on  when we reconstruct the full
  731.         // pathname
  732.         //
  733.  
  734.         wsprintf(szCommonName,L"%s", pObjectInfo->RootRDN);
  735.  
  736.  
  737.         RRETURN(S_OK);
  738.  
  739.  
  740.     }else {
  741.         //
  742.         // There are one or more CNs, a root name has been
  743.         // specified. In the worst case the parent is the
  744.         // root object. In the best case a long CN.
  745.         //
  746.  
  747.         wsprintf(
  748.             szParent, L"%s://%s",
  749.             pObjectInfo->ProviderName,
  750.             pObjectInfo->RootRDN
  751.             );
  752.  
  753.         for (i = 0; i < dwNumComponents - 1; i++) {
  754.  
  755.             wcscat(szParent, L"/");
  756.  
  757.  
  758.             pszComponent =  pObjectInfo->ComponentArray[i].szComponent;
  759.             pszValue = pObjectInfo->ComponentArray[i].szValue;
  760.  
  761.  
  762.             if (pszComponent && pszValue) {
  763.  
  764.                 wcscat(
  765.                     szParent,
  766.                     pObjectInfo->ComponentArray[i].szComponent
  767.                     );
  768.                 wcscat(szParent,L"=");
  769.                 wcscat(
  770.                     szParent,
  771.                     pObjectInfo->ComponentArray[i].szValue
  772.                     );
  773.             }else if (pszComponent){
  774.  
  775.                 wcscat(
  776.                     szParent,
  777.                     pObjectInfo->ComponentArray[i].szComponent
  778.                     );
  779.  
  780.             }else {
  781.                 //
  782.                 // Error - we should never hit this case!!
  783.                 //
  784.  
  785.             }
  786.         }
  787.  
  788.         //
  789.         // And the common name is the last component
  790.         //
  791.  
  792.         pszComponent =  pObjectInfo->ComponentArray[dwNumComponents - 1].szComponent;
  793.         pszValue = pObjectInfo->ComponentArray[dwNumComponents - 1].szValue;
  794.  
  795.  
  796.         if (pszComponent && pszValue) {
  797.  
  798.             wsprintf(szCommonName, L"%s=%s",pszComponent, pszValue);
  799.  
  800.         }else if (pszComponent){
  801.  
  802.             wsprintf(szCommonName, L"%s", pszComponent);
  803.  
  804.         }else {
  805.             //
  806.             // Error - we should never hit this case!!
  807.             //
  808.  
  809.         }
  810.  
  811.     }
  812.  
  813.     RRETURN(S_OK);
  814. }
  815.  
  816. HRESULT
  817. ValidateObjectType(
  818.     POBJECTINFO pObjectInfo
  819.     )
  820. {
  821.  
  822.     pObjectInfo->ObjectType = TOKEN_DSOBJECT;
  823.  
  824.     if (pObjectInfo->ProviderName && !pObjectInfo->RootRDN
  825.             && !pObjectInfo->NumComponents) {
  826.         pObjectInfo->ObjectType = TOKEN_NAMESPACE;
  827.     }else if (pObjectInfo->ProviderName && pObjectInfo->RootRDN
  828.                 && pObjectInfo->NumComponents) {
  829.  
  830.         if (!_wcsicmp(pObjectInfo->ComponentArray[0].szComponent,L"schema")) {
  831.             pObjectInfo->ObjectType = TOKEN_SCHEMA;
  832.         }
  833.  
  834.     }
  835.  
  836.     RRETURN(S_OK);
  837. }
  838.  
  839. HRESULT
  840. BuildSampleDSRootRDNFromADsPath(
  841.     LPWSTR szBuffer,
  842.     LPWSTR szDSRootRDN
  843.     )
  844. {
  845.     OBJECTINFO ObjectInfo;
  846.     POBJECTINFO pObjectInfo = &ObjectInfo;
  847.     CLexer Lexer(szBuffer);
  848.     DWORD dwNumComponents = 0;
  849.     HRESULT hr;
  850.  
  851.     memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  852.     hr = ADsObject(&Lexer, pObjectInfo);
  853.     BAIL_ON_FAILURE(hr);
  854.  
  855.     dwNumComponents = pObjectInfo->NumComponents;
  856.  
  857.  
  858.     if (!dwNumComponents && !pObjectInfo->RootRDN) {
  859.         //
  860.         // There are no CNs in this pathname and
  861.         // no root name specified. This is the
  862.         // namespace object - its parent is the
  863.         // @ADs! object
  864.         //
  865.  
  866.         hr = E_FAIL;
  867.  
  868.     } else if (!dwNumComponents && pObjectInfo->RootRDN) {
  869.         //
  870.         // There are no CNs in this pathname and a root 
  871.         // name has been specified. This is the root
  872.         // object - its parent is the  @Sample! object
  873.  
  874.         wsprintf(szDSRootRDN,L"\\\\%s", pObjectInfo->RootRDN);
  875.  
  876.  
  877.         hr = S_OK;
  878.  
  879.     }else {
  880.         //
  881.         // There are one or more CNs, a root name has been
  882.         // specified. In the worst case the parent is the
  883.         // root object. In the best case a long CN.
  884.         //
  885.  
  886.         wsprintf(szDSRootRDN,L"\\\\%s", pObjectInfo->RootRDN);
  887.  
  888.         hr = S_OK;
  889.     }
  890.  
  891. error:
  892.     RRETURN(hr);
  893.  
  894. }
  895.  
  896.  
  897. HRESULT
  898. BuildDSPathFromADsPath(
  899.     LPWSTR szADsPathName,
  900.     LPWSTR szDSRootRDN,
  901.     LPWSTR szDSPathName
  902.     )
  903. {
  904.     OBJECTINFO ObjectInfo;
  905.     POBJECTINFO pObjectInfo = &ObjectInfo;
  906.     CLexer Lexer(szADsPathName);
  907.     DWORD i = 0;
  908.     DWORD dwNumComponents = 0;
  909.     HRESULT hr;
  910.  
  911.     memset(pObjectInfo, 0, sizeof(OBJECTINFO));
  912.     hr = ADsObject(&Lexer, pObjectInfo);
  913.     BAIL_ON_FAILURE(hr);
  914.  
  915.     dwNumComponents = pObjectInfo->NumComponents;
  916.  
  917.     wcscpy(szDSRootRDN, L"\\");
  918.     wcscat(szDSRootRDN, pObjectInfo->RootRDN);
  919.  
  920.     *szDSPathName = L'\0';
  921.  
  922.     for (i = dwNumComponents; i >  0; i--) {
  923.                 wcscat(szDSPathName, pObjectInfo->ComponentArray[i-1].szComponent);
  924.         if (i>1) wcscat(szDSPathName, L"\\");
  925.     }
  926.  
  927. error:
  928.  
  929.     RRETURN(hr);
  930. }
  931.