FIX: ADSI adscmd Sample Dump Option Fails

Last reviewed: October 29, 1997
Article ID: Q169396
The information in this article applies to:
  • Microsoft Win32 Software Development Kit (SDK) on the following platforms: - Alpha - Windows NT - Windows 95 - x86

SYMPTOMS

The dump option in the adscmd sample provided with the ADSI 1.0 SDK does not work.

RESOLUTION

You can enable the dump option by replacing main.hxx and dump.cxx files with the code below.

STATUS

Microsoft has confirmed this to be a bug in the ADSI sample code released with the ADSI 1.0 SDK.

MORE INFORMATION

Sample Code

Replace main.hxx with the following code:

   //----------------------------------------------------------------------
   //
   //  Microsoft Active Directory 1.0 Sample Code
   //
   //  Copyright (C) Microsoft Corporation, 1996
   //
   //  File:       main.hxx
   //
   //  Contents:   Main include file for adscmd
   //
   //
   //----------------------------------------------------------------------

   //
   // ********* System Includes
   //

   #define UNICODE
   #define _UNICODE
   #define INC_OLE2

   #include <windows.h>

   //
   // ********* CRunTime Includes
   //

   #include <stdlib.h>
   #include <limits.h>
   #include <io.h>
   #include <stdio.h>

   //
   // *********  Public ADs includes
   //

   #include <activeds.h>

   //
   // *********  Useful macros
   //

   #define BAIL_ON_NULL(p)       \
        if (!(p)) {           \
                goto error;   \
        }

   #define BAIL_ON_FAILURE(hr)   \
        if (FAILED(hr)) {     \
                goto error;   \
        }

   #define FREE_INTERFACE(pInterface) \
        if (pInterface) {          \
            pInterface->Release(); \
            pInterface=NULL;       \
        }

   #define FREE_BSTR(bstr)            \
        if (bstr) {                \
            SysFreeString(bstr);   \
            bstr = NULL;           \
        }

   //
   // *********  Prototypes
   //

   void
   PrintUsage(
    void
    );

   int
   AnsiToUnicodeString(
    LPSTR pAnsi,
    LPWSTR pUnicode,
    DWORD StringLength
    );

   int
   UnicodeToAnsiString(
    LPWSTR pUnicode,
    LPSTR pAnsi,
    DWORD StringLength
    );

   LPWSTR
   AllocateUnicodeString(
    LPSTR  pAnsiString
    );

   void
   FreeUnicodeString(
    LPWSTR  pUnicodeString
    );

   HRESULT
   PrintVariantArray(
    VARIANT var
    );

   HRESULT
   PrintVariant(
    VARIANT varPropData
    );

   HRESULT
   PrintProperty(
    BSTR bstrPropName,
    HRESULT hRetVal,
    VARIANT varPropData
    );

   HRESULT
   GetPropertyList(
    IADs * pADs,
    VARIANT * pvar
    );

   //
   // Functions to dump contents of an object
   //

   int
   DoDump(
    char *AnsiADsPath
    ) ;

   HRESULT
   DumpObject(
    IADs * pADs
    );

   //
   // Functions to list objects within a container.
   //

   int
   DoList(
    char *AnsiADsPath
    ) ;

   HRESULT
   EnumObject(
    LPWSTR pszADsPath,
    LPWSTR * lppClassNames,
    DWORD dwClassNames
    ) ;


Replace dump.cxx with the following code

   //----------------------------------------------------------------------
   //
   //  Microsoft Active Directory 1.0 Sample Code
   //
   //  Copyright (C) Microsoft Corporation, 1996
   //
   //  File:       dump.cxx
   //
   //  Contents:   Functions for dumping the properties for an object.
   //
   //
   //----------------------------------------------------------------------

   #include "main.hxx"

   //
   // Given an ADsPath, bind to the object and call the DumpObject routine.
   //

   int
   DoDump(char *AnsiADsPath)
   {
    HRESULT hr = E_OUTOFMEMORY ;
    LPWSTR pszADsPath = NULL;
    IADs * pADs = NULL;

    //
    // Convert path to unicode and then bind to the object.
    //

    BAIL_ON_NULL(pszADsPath = AllocateUnicodeString(AnsiADsPath));

    hr = ADsGetObject(
                pszADsPath,
                IID_IADs,
                (void **)&pADs
                );

    if (FAILED(hr)) {

        printf("Failed to bind to object: %S\n", pszADsPath) ;
    }
    else {

        //
        // Dump the object
        //

        hr = DumpObject(pADs);

        if (FAILED(hr)) {

            printf("Unable to read properties of: %S\n", pszADsPath) ;
        }

        pADs->Release();
    }

   error:

    FreeUnicodeString(pszADsPath);

    return (FAILED(hr) ? 1 : 0) ;
   }

   //
   // Given an ADs pointer, dump the contents of the object
   //

   HRESULT
   DumpObject(
    IADs * pADs
    )
   {
    HRESULT hr;
   HRESULT hrSA;
    IADs * pADsProp = NULL;
    VARIANT var;
   ZeroMemory(&var,sizeof(var));
   VARIANT *   pvarPropName = NULL;
    DWORD i = 0;
   VARIANT varProperty;
    IDispatch * pDispatch = NULL;

    //
    // Access the schema for the object
    //

    hr = GetPropertyList(
                pADs,
                &var);
    BAIL_ON_FAILURE(hr);

    //
    // List the Properties
   //
   hr = SafeArrayAccessData(var.parray, (void **) &pvarPropName);
   BAIL_ON_FAILURE(hr);

   for (i = 0; i < var.parray->rgsabound[0].cElements; i++){

      //
        // Get a property and print it out. The HRESULT is passed to
        // PrintProperty.
        //

        hr = pADs->Get(
                pvarPropName[i].bstrVal,
                &varProperty
                );
      PrintProperty(
            pvarPropName[i].bstrVal,
            hr,
            varProperty
            );

   }

   hr = SafeArrayUnaccessData(var.parray);

   error:
   // Don't destroy hr in case we're here from BAIL_ON_FAILURE
   if(var.parray) hrSA = SafeArrayDestroy(var.parray);

   return(hr);
   }


   HRESULT
   GetPropertyList(
    IADs * pADs,
    VARIANT * pvar )
   {
    HRESULT hr= S_OK;
    BSTR bstrSchemaPath = NULL;
   IADsClass * pADsClass = NULL;

    hr = pADs->get_Schema(&bstrSchemaPath);
    BAIL_ON_FAILURE(hr);

    hr = ADsGetObject(
                bstrSchemaPath,
                IID_IADsClass,
                (void **)&pADsClass);
    BAIL_ON_FAILURE(hr);

   //Put SafeArray of bstr's into input variant struct
   hr = pADsClass->get_MandatoryProperties(pvar);
   BAIL_ON_FAILURE(hr);

   error:
    if (bstrSchemaPath) {
        SysFreeString(bstrSchemaPath);
    }

    if (pADsClass) {
        pADsClass->Release();
    }

    return(hr);
   }
Keywords          : kbcode
Platform          : NT WINDOWS
Solution Type     : kbfix


================================================================================


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: October 29, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.