Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

649 lines
15 KiB

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
cenmfpse.cxx
Abstract:
Contains methods for implementing the Enumeration of session on a
server. Has methods for the CFPNWSessionsCollection object
as well as the CFPNWSessionsEnumVar object.
Author:
Ram Viswanathan (ramv) 11-28-95
Revision History:
--*/
#include "winnt.hxx"
#pragma hdrstop
#if DBG
DECLARE_INFOLEVEL(FPNWEnumSession);
DECLARE_DEBUG(FPNWEnumSession);
#define FPNWEnumSessionDebugOut(x) FPNWEnumSessionInlineDebugOut x
#endif
CFPNWSessionsCollection::CFPNWSessionsCollection()
{
_pszServerADsPath = NULL;
_pszServerName = NULL;
_pDispMgr = NULL;
_pCSessionsEnumVar = NULL;
ENLIST_TRACKING(CFPNWSessionsCollection);
}
CFPNWSessionsCollection::~CFPNWSessionsCollection()
{
if(_pszServerADsPath){
FreeADsStr(_pszServerADsPath);
}
if(_pszServerName){
FreeADsStr(_pszServerName);
}
delete _pDispMgr;
if(_pCSessionsEnumVar){
_pCSessionsEnumVar->Release();
}
}
HRESULT
CFPNWSessionsCollection::Create(LPTSTR pszServerADsPath,
CWinNTCredentials& Credentials,
CFPNWSessionsCollection
** ppCFPNWSessionsCollection )
{
BOOL fStatus = FALSE;
HRESULT hr;
CFPNWSessionsCollection *pCFPNWSessionsCollection = NULL;
POBJECTINFO pServerObjectInfo = NULL;
//
// create the Sessions collection object
//
pCFPNWSessionsCollection = new CFPNWSessionsCollection();
if(pCFPNWSessionsCollection == NULL){
hr = E_OUTOFMEMORY;
goto cleanup;
}
pCFPNWSessionsCollection->_pszServerADsPath =
AllocADsStr(pszServerADsPath);
if(!(pCFPNWSessionsCollection->_pszServerADsPath )){
hr = E_OUTOFMEMORY;
goto cleanup;
}
hr = BuildObjectInfo(pszServerADsPath,
&pServerObjectInfo
);
BAIL_IF_ERROR(hr);
pCFPNWSessionsCollection->_pszServerName =
AllocADsStr(pServerObjectInfo->ComponentArray[1]);
if(!(pCFPNWSessionsCollection->_pszServerName)){
hr = E_OUTOFMEMORY;
goto cleanup;
}
pCFPNWSessionsCollection->_Credentials = Credentials;
hr = pCFPNWSessionsCollection->_Credentials.RefServer(
pCFPNWSessionsCollection->_pszServerName);
BAIL_IF_ERROR(hr);
pCFPNWSessionsCollection->_pDispMgr = new CAggregatorDispMgr;
if (pCFPNWSessionsCollection->_pDispMgr == NULL){
hr = E_OUTOFMEMORY;
goto cleanup;
}
hr = LoadTypeInfoEntry(pCFPNWSessionsCollection->_pDispMgr,
LIBID_ADs,
IID_IADsCollection,
(IADsCollection *)pCFPNWSessionsCollection,
DISPID_NEWENUM
);
BAIL_IF_ERROR(hr);
hr = CFPNWSessionsEnumVar::Create(pszServerADsPath,
pCFPNWSessionsCollection->_Credentials,
&pCFPNWSessionsCollection->_pCSessionsEnumVar);
BAIL_IF_ERROR(hr);
*ppCFPNWSessionsCollection = pCFPNWSessionsCollection;
cleanup:
if(pServerObjectInfo){
FreeObjectInfo(pServerObjectInfo);
}
if(SUCCEEDED(hr)){
RRETURN(hr);
}
delete pCFPNWSessionsCollection;
RRETURN_EXP_IF_ERR(hr);
}
/* IUnknown methods for Sessions collection object */
STDMETHODIMP
CFPNWSessionsCollection::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
{
if(!ppvObj){
RRETURN(E_POINTER);
}
if (IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = this;
}
else if (IsEqualIID(riid, IID_IDispatch))
{
*ppvObj = (IDispatch *)this;
}
else if (IsEqualIID(riid, IID_ISupportErrorInfo))
{
*ppvObj = (ISupportErrorInfo FAR *) this;
}
else if (IsEqualIID(riid, IID_IADsCollection))
{
*ppvObj = (IADsCollection FAR *)this;
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
((LPUNKNOWN)*ppvObj)->AddRef();
RRETURN(S_OK);
}
DEFINE_IDispatch_Implementation(CFPNWSessionsCollection);
/* ISupportErrorInfo method */
STDMETHODIMP
CFPNWSessionsCollection::InterfaceSupportsErrorInfo(
THIS_ REFIID riid
)
{
if (IsEqualIID(riid, IID_IADsCollection)) {
RRETURN(S_OK);
} else {
RRETURN(S_FALSE);
}
}
/* IADsCollection methods */
STDMETHODIMP
CFPNWSessionsCollection::get__NewEnum(THIS_ IUnknown * FAR* retval)
{
HRESULT hr;
if(!retval){
RRETURN_EXP_IF_ERR(E_POINTER);
}
*retval = NULL;
ADsAssert(_pCSessionsEnumVar);
hr = _pCSessionsEnumVar->QueryInterface(IID_IUnknown, (void **)retval);
RRETURN_EXP_IF_ERR(hr);
}
STDMETHODIMP
CFPNWSessionsCollection::GetObject(THIS_ BSTR bstrSessionName,
VARIANT *pvar
)
{
//
// scan the buffer _pbSessions to find one where the ConnectionId
// matches the one in bstrSessionName and get this object
//
HRESULT hr;
hr = _pCSessionsEnumVar->GetObject(bstrSessionName, pvar);
RRETURN_EXP_IF_ERR(hr);
/*
LPTSTR pszSession = NULL;
IDispatch *pDispatch = NULL;
HRESULT hr;
if(!bstrSessionName || !pvar){
RRETURN_EXP_IF_ERR(E_ADS_BAD_PARAMETER);
}
pszSession = AllocADsStr(bstrSessionName);
if(!pszSession){
RRETURN_EXP_IF_ERR(E_OUTOFMEMORY);
}
hr = CFPNWSession::Create(_pszServerADsPath,
ADS_OBJECT_BOUND,
IID_IDispatch,
_Credentials,
(void **)&pDispatch);
BAIL_IF_ERROR(hr);
//
// stick this IDispatch pointer into caller provided variant
//
VariantInit(pvar);
V_VT(pvar) = VT_DISPATCH;
V_DISPATCH(pvar) = pDispatch;
cleanup:
FreeADsStr(pszSession);
RRETURN_EXP_IF_ERR(hr);
*/
}
STDMETHODIMP
CFPNWSessionsCollection::Add(THIS_ BSTR bstrName, VARIANT varNewItem)
{
RRETURN_EXP_IF_ERR(E_NOTIMPL);
}
STDMETHODIMP
CFPNWSessionsCollection::Remove(THIS_ BSTR bstrSessionName)
{
HRESULT hr = S_OK;
DWORD dwConnectionId;
DWORD dwErrorCode;
dwConnectionId = (DWORD)_wtol(bstrSessionName);
dwErrorCode = ADsNwConnectionDel(_pszServerName,
dwConnectionId);
if(dwErrorCode != NERR_Success){
hr = HRESULT_FROM_WIN32(dwErrorCode);
}
RRETURN_EXP_IF_ERR(hr);
}
//
// CFPNWSessionsEnumVar methods follow
//
//+---------------------------------------------------------------------------
//
// Function: CFPNWSessionsEnumVar::CFPNWSessionsEnumVar
//
// Synopsis:
//
//
// Arguments:
//
//
// Returns:
//
// Modifies:
//
// History: 11-22-95 RamV Created.
//
//----------------------------------------------------------------------------
CFPNWSessionsEnumVar::CFPNWSessionsEnumVar()
{
_pszServerName = NULL;
_pszServerADsPath = NULL;
_pbSessions = NULL;
_cElements = 0;
_lLBound = 0;
_lCurrentPosition = _lLBound;
_dwResumeHandle = 0;
}
//+---------------------------------------------------------------------------
//
// Function: CFPNWSessionsEnumVar::~CFPNWSessionsEnumVar
//
// Synopsis:
//
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-22-95 RamV Created.
//
//----------------------------------------------------------------------------
CFPNWSessionsEnumVar::~CFPNWSessionsEnumVar()
{
if(_pszServerName){
FreeADsStr(_pszServerName);
}
if(_pszServerADsPath){
FreeADsStr(_pszServerADsPath);
}
if(_pbSessions){
NetApiBufferFree(_pbSessions);
}
}
HRESULT CFPNWSessionsEnumVar::Create(LPTSTR pszServerADsPath,
CWinNTCredentials& Credentials,
CFPNWSessionsEnumVar \
**ppCSessionsEnumVar
)
{
HRESULT hr;
BOOL fStatus = FALSE;
POBJECTINFO pServerObjectInfo = NULL;
CFPNWSessionsEnumVar FAR* pCSessionsEnumVar = NULL;
*ppCSessionsEnumVar = NULL;
pCSessionsEnumVar = new CFPNWSessionsEnumVar();
if (pCSessionsEnumVar == NULL){
hr = E_OUTOFMEMORY;
goto cleanup;
}
pCSessionsEnumVar->_pszServerADsPath =
AllocADsStr(pszServerADsPath);
if(!(pCSessionsEnumVar->_pszServerADsPath)){
hr = E_OUTOFMEMORY;
goto cleanup;
}
hr = BuildObjectInfo(pszServerADsPath,
&pServerObjectInfo);
BAIL_IF_ERROR(hr);
pCSessionsEnumVar->_pszServerName =
AllocADsStr(pServerObjectInfo->ComponentArray[1]);
if(!(pCSessionsEnumVar->_pszServerName)){
hr = E_OUTOFMEMORY;
goto cleanup;
}
pCSessionsEnumVar->_Credentials = Credentials;
hr = pCSessionsEnumVar->_Credentials.RefServer(
pCSessionsEnumVar->_pszServerName);
BAIL_IF_ERROR(hr);
*ppCSessionsEnumVar = pCSessionsEnumVar;
cleanup:
if(pServerObjectInfo){
FreeObjectInfo(pServerObjectInfo);
}
if(SUCCEEDED(hr)){
RRETURN(hr);
}
delete pCSessionsEnumVar;
RRETURN_EXP_IF_ERR(hr);
}
//+---------------------------------------------------------------------------
//
// Function: CFPNWSessionsEnumVar::Next
//
// Synopsis: Returns cElements number of requested Session 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: 11-27-95 RamV Created.
//
//----------------------------------------------------------------------------
STDMETHODIMP
CFPNWSessionsEnumVar::Next(ULONG ulNumElementsRequested,
VARIANT FAR* pvar,
ULONG FAR* pulNumFetched)
{
HRESULT hresult;
ULONG ulIndex;
LONG lNewCurrent;
ULONG lNumFetched;
PNWCONNECTIONINFO pConnectionInfo;
IDispatch * pDispatch = NULL;
if (pulNumFetched != NULL){
*pulNumFetched = 0;
}
//
// Initialize the elements to be returned
//
for (ulIndex= 0; ulIndex < ulNumElementsRequested; ulIndex++){
VariantInit(&pvar[ulIndex]);
}
if(!_pbSessions || (_lCurrentPosition == _lLBound +(LONG)_cElements) ){
if (_pbSessions){
NetApiBufferFree(_pbSessions);
_pbSessions = NULL;
}
hresult = FPNWEnumSessions(_pszServerName,
&_cElements,
&_dwResumeHandle,
&_pbSessions);
if(hresult == S_FALSE){
RRETURN(S_FALSE);
}
_lLBound = 0;
_lCurrentPosition = _lLBound;
}
//
// Get each element and place it into the return array
// Don't request more than we have
//
for (lNewCurrent=_lCurrentPosition, lNumFetched=0;
lNewCurrent<(LONG)(_lLBound+_cElements) &&
lNumFetched < ulNumElementsRequested;
lNewCurrent++, lNumFetched++){
pConnectionInfo = (PNWCONNECTIONINFO)(_pbSessions +
lNewCurrent*sizeof(NWCONNECTIONINFO));
hresult = CFPNWSession::Create((LPTSTR)_pszServerADsPath,
pConnectionInfo,
ADS_OBJECT_BOUND,
IID_IDispatch,
_Credentials,
(void **)&pDispatch);
BAIL_ON_FAILURE(hresult);
V_VT(&(pvar[lNumFetched])) = VT_DISPATCH;
V_DISPATCH(&(pvar[lNumFetched])) = pDispatch;
}
//
// Tell the caller how many we got (which may be less than the number
// requested), and save the current position
//
if (pulNumFetched != NULL)
*pulNumFetched = lNumFetched;
_lCurrentPosition = lNewCurrent;
//
// If we're returning less than they asked for return S_FALSE, but
// they still have the data (S_FALSE is a success code)
//
return (lNumFetched < ulNumElementsRequested) ?
S_FALSE
: S_OK;
error:
#if DBG
if(FAILED(hresult)){
FPNWEnumSessionDebugOut((DEB_TRACE,
"hresult Failed with value: %ld \n", hresult ));
}
#endif
RRETURN(S_FALSE);
}
//
// helper function
//
HRESULT
CFPNWSessionsEnumVar::GetObject(BSTR bstrSessionName, VARIANT *pvar)
{
HRESULT hr = S_OK;
DWORD dwConnectionId;
PNWCONNECTIONINFO pConnectionInfo = NULL;
IDispatch *pDispatch = NULL;
DWORD i;
if(!_pbSessions){
RRETURN_EXP_IF_ERR(E_ADS_UNKNOWN_OBJECT);
}
//
// scan the buffer _pbSessions to find one where the ConnectionId
// matches the one in bstrSessionName and get this object
//
dwConnectionId = (DWORD)_wtol(bstrSessionName);
for( i=0; i<_cElements; i++){
pConnectionInfo = (PNWCONNECTIONINFO)(_pbSessions+
i*sizeof(PNWCONNECTIONINFO));
if(pConnectionInfo->dwConnectionId = dwConnectionId){
//
// return this struct in the static create for the object
//
hr = CFPNWSession::Create(_pszServerADsPath,
pConnectionInfo,
ADS_OBJECT_BOUND,
IID_IDispatch,
_Credentials,
(void **) &pDispatch );
BAIL_IF_ERROR(hr);
break;
}
}
if(i == _cElements){
//
// no such element
//
hr = E_ADS_UNKNOWN_OBJECT;
goto cleanup;
}
//
// stick this IDispatch pointer into caller provided variant
//
VariantInit(pvar);
V_VT(pvar) = VT_DISPATCH;
V_DISPATCH(pvar) = pDispatch;
cleanup:
RRETURN_EXP_IF_ERR(hr);
}
HRESULT
FPNWEnumSessions(LPTSTR pszServerName,
PDWORD pdwEntriesRead,
PDWORD pdwResumeHandle,
LPBYTE * ppMem
)
{
DWORD dwErrorCode;
dwErrorCode = ADsNwConnectionEnum(pszServerName,
1, //info level desired
(PNWCONNECTIONINFO *)ppMem,
pdwEntriesRead,
pdwResumeHandle);
if(*ppMem == NULL || (dwErrorCode != NERR_Success)){
//
//no more entries returned by sessions
//
RRETURN(S_FALSE);
}
RRETURN(S_OK);
}