|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
cenumses.cxx
Abstract:
Contains methods for implementing the Enumeration of session on a server. Has methods for the CWinNTSessionsCollection object as well as the CWinNTSessionsEnumVar object.
Author:
Ram Viswanathan (ramv) 11-28-95
Revision History:
--*/
#include "winnt.hxx"
#pragma hdrstop
#if DBG
DECLARE_INFOLEVEL(EnumSession); DECLARE_DEBUG(EnumSession); #define EnumSessionDebugOut(x) EnumSessionInlineDebugOut x
#endif
CWinNTSessionsCollection::CWinNTSessionsCollection() { _pszServerADsPath = NULL; _pszServerName = NULL; _pszClientName = NULL; _pszUserName = NULL; _pDispMgr = NULL; _pCSessionsEnumVar = NULL; ENLIST_TRACKING(CWinNTSessionsCollection); }
CWinNTSessionsCollection::~CWinNTSessionsCollection() {
if(_pszServerADsPath){ FreeADsStr(_pszServerADsPath); }
if(_pszServerName){ FreeADsStr(_pszServerName); } if(_pszClientName){ FreeADsStr(_pszClientName); } if(_pszUserName){ FreeADsStr(_pszUserName); }
delete _pDispMgr; if(_pCSessionsEnumVar){ _pCSessionsEnumVar->Release(); }
}
HRESULT CWinNTSessionsCollection::Create(LPTSTR pszServerADsPath, LPTSTR pszClientName, LPTSTR pszUserName, CWinNTCredentials& Credentials, CWinNTSessionsCollection ** ppCWinNTSessionsCollection ) {
BOOL fStatus = FALSE; HRESULT hr; CWinNTSessionsCollection *pCWinNTSessionsCollection = NULL; POBJECTINFO pServerObjectInfo = NULL;
//
// create the Sessions collection object
//
pCWinNTSessionsCollection = new CWinNTSessionsCollection();
if(pCWinNTSessionsCollection == NULL){ hr = E_OUTOFMEMORY; goto cleanup; }
pCWinNTSessionsCollection->_pszServerADsPath = AllocADsStr(pszServerADsPath);
if(!(pCWinNTSessionsCollection->_pszServerADsPath)){ hr = E_OUTOFMEMORY; goto cleanup; }
hr = BuildObjectInfo(pszServerADsPath, &pServerObjectInfo ); BAIL_IF_ERROR(hr);
pCWinNTSessionsCollection->_pszServerName = AllocADsStr(pServerObjectInfo->ComponentArray[1]);
if(!(pCWinNTSessionsCollection->_pszServerName)){ hr = E_OUTOFMEMORY; goto cleanup; }
pCWinNTSessionsCollection->_Credentials = Credentials; hr = pCWinNTSessionsCollection->_Credentials.RefServer( pCWinNTSessionsCollection->_pszServerName); BAIL_IF_ERROR(hr);
if (pszUserName){ pCWinNTSessionsCollection->_pszUserName = AllocADsStr(pszUserName); if(!(pCWinNTSessionsCollection->_pszUserName)){ hr = E_OUTOFMEMORY; goto cleanup; } }
if(pszClientName){ pCWinNTSessionsCollection->_pszClientName = AllocADsStr(pszClientName); if(!(pCWinNTSessionsCollection->_pszClientName)){ hr = E_OUTOFMEMORY; goto cleanup; } }
pCWinNTSessionsCollection->_pDispMgr = new CAggregatorDispMgr; if (pCWinNTSessionsCollection->_pDispMgr == NULL){ hr = E_OUTOFMEMORY; goto cleanup; }
hr = LoadTypeInfoEntry(pCWinNTSessionsCollection->_pDispMgr, LIBID_ADs, IID_IADsCollection, (IADsCollection *)pCWinNTSessionsCollection, DISPID_NEWENUM );
BAIL_IF_ERROR(hr);
*ppCWinNTSessionsCollection = pCWinNTSessionsCollection;
cleanup: if(pServerObjectInfo){ FreeObjectInfo(pServerObjectInfo); } if(SUCCEEDED(hr)){ RRETURN(hr); } delete pCWinNTSessionsCollection; RRETURN_EXP_IF_ERR (hr);
}
/* IUnknown methods for Sessions collection object */
STDMETHODIMP CWinNTSessionsCollection::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); }
/* ISupportErrorInfo method */ STDMETHODIMP CWinNTSessionsCollection::InterfaceSupportsErrorInfo( THIS_ REFIID riid ) { if (IsEqualIID(riid, IID_IADsCollection)) { RRETURN(S_OK); } else { RRETURN(S_FALSE); } }
DEFINE_IDispatch_Implementation(CWinNTSessionsCollection);
/* IADsCollection methods */
STDMETHODIMP CWinNTSessionsCollection::get__NewEnum(THIS_ IUnknown * FAR* retval) { HRESULT hr; CWinNTSessionsEnumVar *pCSessionsEnumVar = NULL;
if(!retval){ RRETURN_EXP_IF_ERR(E_POINTER); } *retval = NULL;
hr = CWinNTSessionsEnumVar::Create(_pszServerADsPath, _pszClientName, _pszUserName, _Credentials, &pCSessionsEnumVar);
BAIL_ON_FAILURE(hr);
ADsAssert(pCSessionsEnumVar);
_pCSessionsEnumVar = pCSessionsEnumVar;
hr = _pCSessionsEnumVar->QueryInterface(IID_IUnknown, (void **)retval); BAIL_ON_FAILURE(hr);
RRETURN(S_OK);
error: delete pCSessionsEnumVar; RRETURN_EXP_IF_ERR(hr); }
STDMETHODIMP CWinNTSessionsCollection::GetObject(THIS_ BSTR bstrSessionName, VARIANT *pvar )
{ LPTSTR pszSession = NULL; LPTSTR pszUserName; LPTSTR pszClientName; 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 = SplitIntoUserAndClient(pszSession, &pszUserName, &pszClientName); BAIL_IF_ERROR(hr);
hr = CWinNTSession::Create(_pszServerADsPath, pszClientName, pszUserName, 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 CWinNTSessionsCollection::Add(THIS_ BSTR bstrName, VARIANT varNewItem) { RRETURN_EXP_IF_ERR(E_NOTIMPL); }
STDMETHODIMP CWinNTSessionsCollection::Remove(THIS_ BSTR bstrSessionName) {
LPTSTR pszSession = NULL; LPTSTR pszUserName; LPTSTR pszClientName; TCHAR szUncClientName[MAX_PATH]; TCHAR szUncServerName[MAX_PATH]; HRESULT hr; NET_API_STATUS nasStatus;
pszSession = AllocADsStr(bstrSessionName); if(!pszSession){ RRETURN_EXP_IF_ERR(E_OUTOFMEMORY); }
hr = SplitIntoUserAndClient(pszSession, &pszUserName, &pszClientName); BAIL_IF_ERROR(hr);
hr = MakeUncName(_pszServerName, szUncServerName); BAIL_IF_ERROR(hr);
hr = MakeUncName(pszClientName, szUncClientName); BAIL_IF_ERROR(hr);
nasStatus = NetSessionDel(szUncServerName, szUncClientName, pszUserName );
if(nasStatus != NERR_Success){ hr = HRESULT_FROM_WIN32(nasStatus); }
cleanup: FreeADsStr(pszSession); RRETURN_EXP_IF_ERR(hr);
}
//
// CWinNTSessionsEnumVar methods follow
//
//+---------------------------------------------------------------------------
//
// Function: CWinNTSessionsEnumVar::CWinNTSessionsEnumVar
//
// Synopsis:
//
//
// Arguments:
//
//
// Returns:
//
// Modifies:
//
// History: 11-22-95 RamV Created.
//
//----------------------------------------------------------------------------
CWinNTSessionsEnumVar::CWinNTSessionsEnumVar() {
_pszServerName = NULL; _pszServerADsPath = NULL; _pszClientName = NULL; _pszUserName = NULL; _pbSessions = NULL; _cElements = 0; _lLBound = 0; _lCurrentPosition = _lLBound; _dwTotalEntries = 0; _dwResumeHandle = 0;
}
//+---------------------------------------------------------------------------
//
// Function: CWinNTSessionsEnumVar::~CWinNTSessionsEnumVar
//
// Synopsis:
//
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 11-22-95 RamV Created.
//
//----------------------------------------------------------------------------
CWinNTSessionsEnumVar::~CWinNTSessionsEnumVar() {
if(_pszServerName){ FreeADsStr(_pszServerName); } if(_pszServerADsPath){ FreeADsStr(_pszServerADsPath); } if(_pszClientName){ FreeADsStr(_pszClientName); } if(_pszUserName){ FreeADsStr(_pszUserName); }
if(_pbSessions){ NetApiBufferFree(_pbSessions); } }
HRESULT CWinNTSessionsEnumVar::Create(LPTSTR pszServerADsPath, LPTSTR pszClientName, LPTSTR pszUserName, CWinNTCredentials& Credentials, CWinNTSessionsEnumVar \ **ppCSessionsEnumVar) {
HRESULT hr; BOOL fStatus = FALSE; POBJECTINFO pServerObjectInfo = NULL; CWinNTSessionsEnumVar FAR* pCSessionsEnumVar = NULL;
*ppCSessionsEnumVar = NULL;
pCSessionsEnumVar = new CWinNTSessionsEnumVar();
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);
if(pszClientName){
pCSessionsEnumVar->_pszClientName = AllocADsStr(pszClientName);
if(!(pCSessionsEnumVar->_pszClientName)){ hr = E_OUTOFMEMORY; goto cleanup; }
}
if(pszUserName){ pCSessionsEnumVar->_pszUserName = AllocADsStr(pszUserName);
if(!(pCSessionsEnumVar->_pszUserName)){ hr = E_OUTOFMEMORY; goto cleanup; } }
*ppCSessionsEnumVar = pCSessionsEnumVar;
cleanup: if(pServerObjectInfo){ FreeObjectInfo(pServerObjectInfo); }
if(SUCCEEDED(hr)){ RRETURN(hr); }
delete pCSessionsEnumVar; RRETURN_EXP_IF_ERR(hr); }
//+---------------------------------------------------------------------------
//
// Function: CWinNTSessionsEnumVar::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 CWinNTSessionsEnumVar::Next(ULONG ulNumElementsRequested, VARIANT FAR* pvar, ULONG FAR* pulNumFetched) {
HRESULT hresult; ULONG ulIndex; LONG lNewCurrent; ULONG lNumFetched; LPSESSION_INFO_1 lpSessionInfo; IDispatch * pDispatch = NULL; LPTSTR pszClientName = NULL; LPTSTR pszUserName = 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; }
if(_dwTotalEntries == _cElements && (_dwTotalEntries !=0)){ //
// we got all elements already, no need to do another call
//
RRETURN(S_FALSE); }
hresult = WinNTEnumSessions(_pszServerName, _pszClientName, _pszUserName, &_cElements, &_dwTotalEntries, &_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++){
lpSessionInfo = (LPSESSION_INFO_1)(_pbSessions + lNewCurrent*sizeof(SESSION_INFO_1));
pszClientName = lpSessionInfo->sesi1_cname; pszUserName = lpSessionInfo->sesi1_username;
hresult = CWinNTSession::Create(_pszServerADsPath, pszClientName, pszUserName, 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)){ EnumSessionDebugOut((DEB_TRACE, "hresult Failed with value: %ld \n", hresult )); } #endif
RRETURN(S_FALSE); }
HRESULT WinNTEnumSessions(LPTSTR pszServerName, LPTSTR pszClientName, LPTSTR pszUserName, PDWORD pdwEntriesRead, PDWORD pdwTotalEntries, PDWORD pdwResumeHandle, LPBYTE * ppMem )
{
NET_API_STATUS nasStatus;
UNREFERENCED_PARAMETER(pszClientName); UNREFERENCED_PARAMETER(pszUserName);
//
// why have these parameters if they are unreferenced? Because we might
// use them in the future when more complicated enumerations are desired
//
nasStatus = NetSessionEnum(pszServerName, NULL, NULL, 1, //info level desired
ppMem, MAX_PREFERRED_LENGTH, pdwEntriesRead, pdwTotalEntries, pdwResumeHandle);
if(*ppMem == NULL || (nasStatus != NERR_Success)){ //
//no more entries returned by sessions
//
RRETURN(S_FALSE); }
RRETURN(S_OK);
}
//
// helper functions
//
HRESULT SplitIntoUserAndClient(LPTSTR pszSession, LPTSTR * ppszUserName, LPTSTR * ppszClientName )
{
HRESULT hr = S_OK; int i=0;
//
// assumption: Valid strings are passed to this function
// i.e. bstrSession is valid
// we have the format username\clientname
// suppose we have no username then it is "\clientname"
// suppose we dont have clientname it is username\
*ppszUserName = pszSession; *ppszClientName = pszSession;
if((*ppszClientName = _tcschr(pszSession, TEXT('\\')))== NULL) { //
// invalid name specified
//
RRETURN(E_FAIL); } **ppszClientName = TEXT('\0'); (*ppszClientName)++; RRETURN(S_OK); }
|