windows-nt/Source/XPSP1/NT/ds/adsi/winnt/cenumses.cxx
2020-09-26 16:20:57 +08:00

745 lines
18 KiB
C++

/*++
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);
}