|
|
//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: cenumvar.cxx
//
// Contents: Windows NT 3.5 Enumerator Code
//
// CNDSNamespaceEnum::Create
// CNDSNamespaceEnum::CNDSNamespaceEnum
// CNDSNamespaceEnum::~CNDSNamespaceEnum
// CNDSNamespaceEnum::Next
// CNDSNamespaceEnum::FetchObjects
// CNDSNamespaceEnum::FetchNextObject
// CNDSNamespaceEnum::PrepBuffer
//
// History:
//----------------------------------------------------------------------------
#include "NDS.hxx"
#pragma hdrstop
#define ENUM_BUFFER_SIZE (1024 * 16)
//+---------------------------------------------------------------------------
//
// Function: CNDSNamespaceEnum::Create
//
// Synopsis:
//
// Arguments: [pCollection]
// [ppEnumVariant]
//
// Returns: HRESULT
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT CNDSNamespaceEnum::Create( CNDSNamespaceEnum FAR* FAR* ppenumvariant, VARIANT var, CCredentials& Credentials ) { HRESULT hr = S_OK; CNDSNamespaceEnum FAR* penumvariant = NULL; DWORD dwStatus;
penumvariant = new CNDSNamespaceEnum();
if (penumvariant == NULL){ hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
penumvariant->_Credentials = Credentials;
*ppenumvariant = penumvariant;
RRETURN(hr);
error: if (penumvariant) { delete penumvariant; } RRETURN(hr); }
//+---------------------------------------------------------------------------
//
// Function: CNDSNamespaceEnum::CNDSNamespaceEnum
//
// Synopsis:
//
//
// Arguments:
//
//
// Returns:
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//
//----------------------------------------------------------------------------
CNDSNamespaceEnum::CNDSNamespaceEnum() { _dwEntriesRead = 0; _dwCurrentEntry = 0; _pBuffer = NULL; }
//+---------------------------------------------------------------------------
//
// Function: CNDSNamespaceEnum::~CNDSNamespaceEnum
//
// Synopsis:
//
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//
//----------------------------------------------------------------------------
CNDSNamespaceEnum::~CNDSNamespaceEnum() {
if (_pBuffer) FreeADsMem(_pBuffer);
}
//+---------------------------------------------------------------------------
//
// Function: CNDSNamespaceEnum::Next
//
// Synopsis: Returns cElements number of requested ADs objects in the
// array supplied in pvar.
//
// Arguments: [cElements] -- The number of elements requested by client
// [pvar] -- ptr to array of VARIANTs to for return objects
// [pcElementFetched] -- if non-NULL, then number of elements
// -- actually returned is placed here
//
// Returns: HRESULT -- S_OK if number of elements requested are returned
// -- S_FALSE if number of elements is < requested
//
// Modifies:
//
// History:
//
//----------------------------------------------------------------------------
STDMETHODIMP CNDSNamespaceEnum::Next( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched ) { ULONG cElementFetched = 0; HRESULT hr = S_OK;
hr = FetchObjects( cElements, pvar, &cElementFetched );
if (pcElementFetched) { *pcElementFetched = cElementFetched; } RRETURN(hr); }
HRESULT CNDSNamespaceEnum::FetchObjects( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched ) { HRESULT hr = S_OK; IDispatch *pDispatch = NULL; DWORD i = 0;
while (i < cElements) {
hr = FetchNextObject(&pDispatch); if (hr == S_FALSE) { break; }
VariantInit(&pvar[i]); pvar[i].vt = VT_DISPATCH; pvar[i].pdispVal = pDispatch; (*pcElementFetched)++; i++; } return(hr); }
//+---------------------------------------------------------------------------
//
// Function: CNDSNamespaceEnum::FetchNextObject
//
// Synopsis: Gets IDispatch pointer of next object in namespace.
//
// Arguments: [ppDispatch] -- Pointer to where to return IDispatch pointer.
//
// Returns: HRESULT -- S_OK if got the next object
// -- S_FALSE if not
//
// Modifies: [*ppDispatch]
//
// History: 31-Jul-96 t-danal Use Multiple Network Provider for enum
//
//----------------------------------------------------------------------------
HRESULT CNDSNamespaceEnum::FetchNextObject( IDispatch ** ppDispatch ) { HRESULT hr; DWORD dwStatus; LPTSTR lpTreeName ;
*ppDispatch = NULL;
//
// Ensure that the buffer is valid
//
hr = PrepBuffer(); BAIL_ON_FAILURE(hr);
//
// Grab next (tree) name out of the buffer
//
lpTreeName = (LPWSTR)_pBuffer + (_dwCurrentEntry++ * OBJ_NAME_SIZE) ;
//
// Now create and send back the current object
//
hr = CNDSTree::CreateTreeObject( L"NDS:", lpTreeName, L"Top", _Credentials, ADS_OBJECT_BOUND, IID_IDispatch, (void **)ppDispatch ); BAIL_ON_FAILURE(hr);
error:
RRETURN_ENUM_STATUS(hr); }
//+---------------------------------------------------------------------------
//
// Function: CNDSNamespaceEnum::PrepBuffer
//
// Synopsis: Ensures that the enumeration buffer has something
//
// Arguments: none
//
// Returns: HRESULT -- S_OK if the buffer is ready to be used
// -- an error if not
//
// Modifies: _pBuffer, _dwCurrentEntry, _dwEntriesRead
//
// History: 31-Jul-96 t-danal Created
//
//----------------------------------------------------------------------------
HRESULT CNDSNamespaceEnum::PrepBuffer() {
HRESULT hr = S_OK; DWORD cb = ENUM_BUFFER_SIZE; DWORD dwIter = 0, i; BOOL fFound ; LPWSTR lpString = NULL; WCHAR pszObjectName[OBJ_NAME_SIZE];
NWDSCCODE ccode; nuint32 connRef = 0; nstr8 aObjectName[OBJ_NAME_SIZE]; nuint32 objectID = 0xFFFFFFFF; /* -1 */ nuint16 objectType; nuint8 objectHasProperties; nuint8 objectFlag; nuint8 objectSecurity; NWCCConnInfo connInfo; NWCONN_HANDLE connHandle; nstr8 searchObjectName[48] = "*"; nuint16 searchObjectType = OT_TREE_NAME;
//
// Fill buffer as need. In theory we can get called to refill.
// But since we need get everything to remove dups in
// th case of TREEs, we dont allow this case. Ie. we get all
// and there should be no more. So if _dwCurrentEntry is not
// 0 and we need read more - then its time to bail.
//
if ( (_dwCurrentEntry < _dwEntriesRead) ) { //
// Buffer still good
//
ADsAssert(_pBuffer) ; return(S_OK) ; }
if (_dwCurrentEntry != 0) { return (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)); }
//
// Allocate buffer, if needed
//
if (!_pBuffer) { _pBuffer = AllocADsMem(cb); if (!_pBuffer) { hr = E_OUTOFMEMORY; RRETURN(hr); } lpString = (LPWSTR) _pBuffer ; _pBufferEnd = (LPBYTE)_pBuffer + cb ; }
//
// Get handle
//
ccode = NWCCGetPrimConnRef( &connRef ); ccode = NWCCOpenConnByRef( connRef, NWCC_OPEN_UNLICENSED, NWCC_RESERVED, &connHandle );
CHECK_AND_SET_EXTENDED_ERROR(ccode, hr);
ccode = NWCCGetAllConnInfo( connHandle, NWCC_INFO_VERSION_1, &connInfo ); CHECK_AND_SET_EXTENDED_ERROR(ccode, hr);
_dwEntriesRead = 0 ;
do {
//
// Scan bindery for NDS tree objects
//
ccode = NWScanObject(connHandle, searchObjectName, searchObjectType, &objectID, aObjectName, &objectType, &objectHasProperties, &objectFlag, &objectSecurity); if ( ccode ) { if (_dwEntriesRead > 0) hr = S_OK ; break ; }
AnsiToUnicodeString( aObjectName, pszObjectName, NULL_TERMINATED );
//
// Remove any trailing '_' upto 32 chars. This is standard NDS tree
// naming stuff.
//
dwIter = 31; while (pszObjectName[dwIter] == L'_' && dwIter > 0 ) { dwIter--; } pszObjectName[dwIter + 1] = L'\0';
//
// Scan for duplicates. We are doing linear everytime, but then again,
// there shouldnt be many trees.
//
fFound = FALSE ; for (i = 0; i < _dwEntriesRead; i++) {
if (_wcsicmp( pszObjectName, (LPWSTR)_pBuffer + (i * OBJ_NAME_SIZE)) == 0) {
fFound = TRUE ; break ; } }
//
// Copy this unique tree name into the buffer
//
if (!fFound) {
//
// Check that we have enough space.
//
if ((lpString + OBJ_NAME_SIZE) >= _pBufferEnd) {
cb = (LPBYTE)_pBufferEnd - (LPBYTE)_pBuffer ; _pBuffer = ReallocADsMem( _pBuffer, cb, 2 * cb );
if (!_pBuffer) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
lpString = (LPWSTR)_pBuffer + (_dwEntriesRead * OBJ_NAME_SIZE) ; _pBufferEnd = (LPBYTE) _pBuffer + (2 * cb) ; }
//
// Assume fixed size (max NW name). Yes, its more than
// we really need but keeps things simpler.
//
wcscpy(lpString, pszObjectName); lpString += OBJ_NAME_SIZE ;
_dwEntriesRead++ ; }
} while (TRUE) ;
error: if (connHandle) { NWCCCloseConn( connHandle ); }
RRETURN(hr);
}
|