Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1567 lines
36 KiB

/******************************************************************
Session.CPP -- C provider class implementation
Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved
Description: Session Provider
******************************************************************/
#include "precomp.h"
#include "Session.h"
CSession MyCSession (
PROVIDER_NAME_SESSION ,
Namespace
) ;
/*****************************************************************************
*
* FUNCTION : CSession::CSession
*
* DESCRIPTION : Constructor
*
*****************************************************************************/
CSession :: CSession (
LPCWSTR lpwszName,
LPCWSTR lpwszNameSpace
) : Provider ( lpwszName , lpwszNameSpace )
{
}
/*****************************************************************************
*
* FUNCTION : CSession::~CSession
*
* DESCRIPTION : Destructor
*
*****************************************************************************/
CSession :: ~CSession ()
{
}
/*****************************************************************************
*
* FUNCTION : CSession::EnumerateInstances
*
* DESCRIPTION : Returns all the instances of this class.
*
*****************************************************************************/
HRESULT CSession :: EnumerateInstances (
MethodContext *pMethodContext,
long lFlags
)
{
HRESULT hRes = WBEM_S_NO_ERROR ;
DWORD dwPropertiesReq = SESSION_ALL_PROPS;
#ifdef NTONLY
hRes = EnumNTSessionInfo (
NULL,
NULL,
502,
pMethodContext,
dwPropertiesReq
);
#endif
#if 0
#ifdef WIN9XONLY
hRes = Enum9XSessionInfo (
50,
pMethodContext,
dwPropertiesReq
);
#endif
#endif // #if 0
return hRes ;
}
/*****************************************************************************
*
* FUNCTION : CSession::GetObject
*
* DESCRIPTION : Find a single instance based on the key properties for the
* class.
*
*****************************************************************************/
HRESULT CSession :: GetObject (
CInstance *pInstance,
long lFlags ,
CFrameworkQuery &Query
)
{
HRESULT hRes = WBEM_S_NO_ERROR;
CHString t_ComputerName ;
CHString t_UserName;
if ( pInstance->GetCHString ( IDS_ComputerName , t_ComputerName ) == FALSE )
{
hRes = WBEM_E_INVALID_PARAMETER ;
}
if ( SUCCEEDED ( hRes ) )
{
if ( pInstance->GetCHString ( IDS_UserName , t_UserName ) == FALSE )
{
hRes = WBEM_E_INVALID_PARAMETER ;
}
}
if ( SUCCEEDED ( hRes ) )
{
DWORD dwPropertiesReq = 0;
if ( Query.AllPropertiesAreRequired () )
{
dwPropertiesReq = SESSION_ALL_PROPS;
}
else
{
SetPropertiesReq ( Query,dwPropertiesReq );
}
short t_Level;
#ifdef NTONLY
GetNTLevelInfo ( dwPropertiesReq, &t_Level );
hRes = FindAndSetNTSession ( t_ComputerName, t_UserName.GetBuffer(0), t_Level, dwPropertiesReq, pInstance, Get );
#endif
#if 0
#ifdef WIN9XONLY
Get9XLevelInfo ( dwPropertiesReq, &t_Level );
hRes = FindAndSet9XSession ( t_ComputerName, t_UserName, t_Level, dwPropertiesReq, pInstance, Get );
#endif
#endif // #if 0
}
return hRes ;
}
/*****************************************************************************
*
* FUNCTION : CSession:: DeleteInstance
*
* DESCRIPTION : Deletes an Session if it exists
*
*****************************************************************************/
HRESULT CSession :: DeleteInstance (
const CInstance &Instance,
long lFlags
)
{
HRESULT hRes = WBEM_S_NO_ERROR;
CHString t_ComputerName ;
CHString t_UserName;
if ( Instance.GetCHString ( IDS_ComputerName , t_ComputerName ) == FALSE )
{
hRes = WBEM_E_INVALID_PARAMETER ;
}
if ( SUCCEEDED ( hRes ) )
{
if ( Instance.GetCHString ( IDS_UserName , t_UserName ) == FALSE )
{
hRes = WBEM_E_INVALID_PARAMETER ;
}
}
if ( SUCCEEDED ( hRes ) )
{
CInstancePtr pInstance; // This will not be used in this method.
#ifdef NTONLY
hRes = FindAndSetNTSession ( t_ComputerName, t_UserName.GetBuffer(0), 10, 0, pInstance, Delete );
#endif
#if 0
#ifdef WIN9XONLY
hRes = FindAndSet9XSession ( t_ComputerName, t_UserName, 50, 0, pInstance, Delete );
#endif
#endif // #if 0
}
return hRes ;
}
/*****************************************************************************
*
* FUNCTION : CSession::ExecQuery
*
* DESCRIPTION : Optimizing a query on filtering Properties and the Key value
*
*****************************************************************************/
HRESULT CSession :: ExecQuery (
MethodContext *pMethodContext,
CFrameworkQuery &Query,
long lFlags
)
{
HRESULT hRes = WBEM_S_NO_ERROR;
DWORD dwPropertiesReq;
short t_Level;
if ( Query.AllPropertiesAreRequired () )
{
dwPropertiesReq = SESSION_ALL_PROPS;
}
else
{
SetPropertiesReq ( Query,dwPropertiesReq );
}
#ifdef NTONLY
GetNTLevelInfo ( dwPropertiesReq, &t_Level );
#endif
#if 0
#ifdef WIN9XONLY
Get9XLevelInfo ( dwPropertiesReq, &t_Level );
#endif
#endif // #if 0
CHStringArray t_ComputerValues;
CHStringArray t_UserValues;
hRes = Query.GetValuesForProp(
IDS_ComputerName,
t_ComputerValues
);
hRes = Query.GetValuesForProp(
IDS_UserName,
t_UserValues
);
if ( SUCCEEDED ( hRes ) )
{
short t_Level;
#ifdef NTONLY
GetNTLevelInfo ( dwPropertiesReq, &t_Level );
hRes = OptimizeNTQuery ( t_ComputerValues, t_UserValues, t_Level, pMethodContext, dwPropertiesReq );
#endif
#if 0
#ifdef WIN9XONLY
Get9XLevelInfo ( dwPropertiesReq, &t_Level );
hRes = Optimize9XQuery ( t_ComputerValues, t_UserValues, t_Level, pMethodContext, dwPropertiesReq );
#endif
#endif // #if 0
}
return hRes;
}
#ifdef NTONLY
/*****************************************************************************
*
* FUNCTION : CSession::EnumNTSessionInfo
*
* DESCRIPTION : Enumerating all the Sessions
*
*****************************************************************************/
HRESULT CSession :: EnumNTSessionInfo (
LPWSTR lpComputerName,
LPWSTR lpUserName,
short a_Level,
MethodContext *pMethodContext,
DWORD dwPropertiesReq
)
{
NET_API_STATUS t_Status = NERR_Success;
HRESULT hRes = WBEM_S_NO_ERROR;
DWORD dwNoOfEntriesRead = 0;
DWORD dwTotalSessions = 0;
DWORD dwResumeHandle = 0;
void *pBuf = NULL;
void *pTmpBuf = NULL;
while ( ( t_Status == NERR_Success ) || ( t_Status == ERROR_MORE_DATA ) )
{
t_Status = NetSessionEnum(
NULL,
lpComputerName,
lpUserName,
a_Level,
(LPBYTE *) &pBuf,
-1,
&dwNoOfEntriesRead,
&dwTotalSessions,
&dwResumeHandle
);
if ( t_Status == NERR_Success )
{
if ( dwNoOfEntriesRead == 0 )
{
break;
}
else
{
try
{
pTmpBuf = pBuf;
for ( int i = 0; i < dwNoOfEntriesRead; i++ )
{
CInstancePtr pInstance ( CreateNewInstance ( pMethodContext ), FALSE );
hRes = LoadData ( a_Level, pBuf, dwPropertiesReq, pInstance );
if ( SUCCEEDED ( hRes ) )
{
hRes = pInstance->Commit();
if ( FAILED ( hRes ) )
{
break;
}
}
// here need to go to the next structure based on the level, we will typecast with the apropriate structure
// and then increment by one
switch ( a_Level )
{
case 502 : SESSION_INFO_502 *pTmpTmpBuf502;
pTmpTmpBuf502 = ( SESSION_INFO_502 *) pTmpBuf;
pTmpTmpBuf502 ++;
pTmpBuf = ( void * ) pTmpTmpBuf502;
break;
case 2: SESSION_INFO_2 *pTmpTmpBuf2;
pTmpTmpBuf2 = (SESSION_INFO_2 *) pTmpBuf;
pTmpTmpBuf2 ++;
pTmpBuf = ( void * ) pTmpTmpBuf2;
break;
case 1: SESSION_INFO_1 *pTmpTmpBuf1;
pTmpTmpBuf1 = ( SESSION_INFO_1 *) pTmpBuf;
pTmpTmpBuf1 ++;
pTmpBuf = ( void * ) pTmpTmpBuf1;
break;
case 10: SESSION_INFO_10 *pTmpTmpBuf10;
pTmpTmpBuf10 = ( SESSION_INFO_10 *) pTmpBuf;
pTmpTmpBuf10 ++;
pTmpBuf = ( void * ) pTmpTmpBuf10;
break;
}
}
if ( FAILED ( hRes ) )
{
break;
}
}
catch ( ... )
{
NetApiBufferFree ( pBuf );
pBuf = NULL;
throw;
}
NetApiBufferFree ( pBuf );
pBuf = NULL;
}
}
else
{
if ( t_Status == ERROR_ACCESS_DENIED )
{
hRes = WBEM_E_ACCESS_DENIED;
}
else
{
if ( t_Status == ERROR_NOT_ENOUGH_MEMORY )
{
hRes = WBEM_E_OUT_OF_MEMORY;
}
else
{
hRes = WBEM_E_FAILED;
}
}
}
}
return hRes;
}
/*****************************************************************************
*
* FUNCTION : CSession::FindAndSetNTSession
*
* DESCRIPTION : Find a single instance based on the key properties for the
* class.
*
*****************************************************************************/
HRESULT CSession::FindAndSetNTSession ( LPCWSTR a_ComputerName, LPWSTR a_UserName, short a_Level, DWORD dwPropertiesReq,
CInstance *pInstance, DWORD eOperation )
{
HRESULT hRes = WBEM_S_NO_ERROR;
NET_API_STATUS t_Status = NERR_Success;
CHString t_TempKey;
t_TempKey.Format ( L"%s%s",L"\\\\", a_ComputerName );
DWORD dwNoOfEntriesRead = 0;
DWORD dwTotalSessions = 0;
DWORD dwResumeHandle = 0;
void *pBuf = NULL;
// since it will be only one structure
t_Status = NetSessionEnum(
NULL,
t_TempKey.GetBuffer ( 0 ),
a_UserName,
a_Level,
(LPBYTE *) &pBuf,
-1,
&dwNoOfEntriesRead,
&dwTotalSessions,
&dwResumeHandle
);
hRes = ( t_Status != NERR_Success ) && ( dwNoOfEntriesRead == 0 ) ? WBEM_E_NOT_FOUND : hRes;
if ( SUCCEEDED ( hRes ) )
{
try
{
switch ( eOperation )
{
case Get: hRes = LoadData ( a_Level, pBuf, dwPropertiesReq, pInstance );
break;
case Delete: hRes = t_Status = NetSessionDel (
NULL,
t_TempKey.GetBuffer ( 0 ),
a_UserName
);
if ( t_Status == NERR_Success )
{
hRes = WBEM_S_NO_ERROR;
}
else
{
if ( t_Status == ERROR_ACCESS_DENIED )
{
hRes = WBEM_E_ACCESS_DENIED;
}
else
{
if ( t_Status == ERROR_NOT_ENOUGH_MEMORY )
{
hRes = WBEM_E_OUT_OF_MEMORY;
}
else
{
hRes = WBEM_E_FAILED;
}
}
}
break;
default: hRes = WBEM_E_PROVIDER_NOT_CAPABLE;
break;
}
}
catch ( ... )
{
if ( pBuf != NULL )
{
NetApiBufferFree(pBuf);
pBuf = NULL;
}
throw;
}
if ( pBuf != NULL )
{
NetApiBufferFree(pBuf);
pBuf = NULL;
}
}
return hRes ;
}
/*****************************************************************************
*
* FUNCTION : Session::OptimizeNTQuery
*
* DESCRIPTION : Optimizes a query based on the key values.
*
*****************************************************************************/
HRESULT CSession::OptimizeNTQuery (
CHStringArray& a_ComputerValues,
CHStringArray& a_UserValues,
short a_Level,
MethodContext *pMethodContext,
DWORD dwPropertiesReq
)
{
HRESULT hRes = WBEM_S_NO_ERROR;
NET_API_STATUS t_Status = NERR_Success;
if ( ( a_ComputerValues.GetSize() == 0 ) && ( a_UserValues.GetSize() == 0 ) )
{
// This is a query for which there is no where clause, so it means only a few Properties are requested
// hence we need to deliver only those properties of instances to the WinMgmt while enumerating Sessions
hRes = EnumNTSessionInfo (
NULL,
NULL,
a_Level,
pMethodContext,
dwPropertiesReq
);
}
else
if ( a_UserValues.GetSize() != 0 )
{
for ( int i = 0; i < a_UserValues.GetSize(); i++ )
{
hRes = EnumNTSessionInfo (
NULL,
a_UserValues.GetAt( i ).GetBuffer ( 0 ),
a_Level,
pMethodContext,
dwPropertiesReq
);
}
}
else
if ( a_ComputerValues.GetSize() != 0 )
{
CHString t_ComputerName;
for ( int i = 0; i < a_ComputerValues.GetSize(); i++ )
{
t_ComputerName.Format ( L"%s%s", L"\\\\", (LPCWSTR)a_ComputerValues.GetAt(i) );
hRes = EnumNTSessionInfo (
t_ComputerName.GetBuffer(0),
NULL,
a_Level,
pMethodContext,
dwPropertiesReq
);
}
}
else
{
hRes = WBEM_E_PROVIDER_NOT_CAPABLE;
}
return hRes;
}
/*****************************************************************************
*
* FUNCTION : CSession::GetNTLevelInfo
*
* DESCRIPTION : Getting the level info, so that the appropriate structure
* Can be passed to make a call.
*
*****************************************************************************/
void CSession :: GetNTLevelInfo (
DWORD dwPropertiesReq,
short *a_Level
)
{
//
// enuminstances uses level 502
//
// as NetSessionEnum is going to fail for non-admin user for level 502
// we cannot be specific about level as ordinary user can obtain some
// values for some properties when using downgrading level
//
// decision was taken to make all call with 502 level then !
//
*a_Level = 502;
/*
if ( ( dwPropertiesReq == SESSION_ALL_PROPS ) ||
( (dwPropertiesReq & SESSION_PROP_TransportName) == SESSION_PROP_TransportName )
)
{
*a_Level = 502;
}
else
if ( (dwPropertiesReq & SESSION_PROP_ClientType) == SESSION_PROP_ClientType )
{
*a_Level = 2;
}
else
if ( ( (dwPropertiesReq & SESSION_PROP_NumOpens) == SESSION_PROP_NumOpens ) ||
( (dwPropertiesReq & SESSION_PROP_SessionType) == SESSION_PROP_SessionType )
)
{
*a_Level = 1;
}
else
{
// Since keys will be always required we need to atleast use Level 10 structure and level 0 cannot be used since,
// it gives only username, where as computername is also a key.
*a_Level = 10;
}
*/
}
#endif
/*****************************************************************************
*
* FUNCTION : CSession::LoadData
* DESCRIPTION : Loading an instance with the obtained information
*
*****************************************************************************/
HRESULT CSession :: LoadData (
short a_Level,
void *pTmpBuf,
DWORD dwPropertiesReq ,
CInstance *pInstance
)
{
HRESULT hRes = WBEM_S_NO_ERROR;
// every property is to be set based on the level and then typecasting that buffer with that level.
if ( dwPropertiesReq & SESSION_PROP_Computer)
{
CHString t_ComputerName;
switch ( a_Level )
{
#ifdef NTONLY
case 502 : t_ComputerName = ( (SESSION_INFO_502 *) pTmpBuf )->sesi502_cname;
break;
#endif
case 2: t_ComputerName = ( (SESSION_INFO_2 *) pTmpBuf )->sesi2_cname;
break;
case 1: t_ComputerName = ( (SESSION_INFO_1 *) pTmpBuf )->sesi1_cname;
break;
case 10: t_ComputerName = ( (SESSION_INFO_10 *) pTmpBuf )->sesi10_cname;
break;
#if 0
#ifdef WIN9XONLY
case 50: t_ComputerName = ( (SESSION_INFO_50 *) pTmpBuf )->sesi50_cname;
break;
#endif
#endif // #if 0
}
if ( SUCCEEDED ( hRes ) )
{
if ( pInstance->SetCHString ( IDS_ComputerName, t_ComputerName ) == FALSE )
{
hRes = WBEM_E_PROVIDER_FAILURE ;
}
}
}
if ( SUCCEEDED ( hRes ) )
{
if ( dwPropertiesReq & SESSION_PROP_User )
{
CHString t_User;
switch ( a_Level )
{
#ifdef NTONLY
case 502 : t_User = ( (SESSION_INFO_502 *) pTmpBuf )->sesi502_username;
break;
#endif
case 2: t_User = ( (SESSION_INFO_2 *) pTmpBuf )->sesi2_username;
break;
case 1: t_User = ( (SESSION_INFO_1 *) pTmpBuf )->sesi1_username;
break;
case 10: t_User = ( (SESSION_INFO_10 *) pTmpBuf )->sesi10_username;
break;
#if 0
#ifdef WIN9XONLY
case 50: t_User = ( (SESSION_INFO_50 *) pTmpBuf )->sesi50_username;
break;
#endif
#endif // #if 0
}
if ( SUCCEEDED ( hRes ) )
{
if ( pInstance->SetCHString ( IDS_UserName, t_User ) == FALSE )
{
hRes = WBEM_E_PROVIDER_FAILURE ;
}
}
}
}
if ( SUCCEEDED ( hRes ) )
{
if ( dwPropertiesReq & SESSION_PROP_ActiveTime )
{
DWORD t_ActiveTime;
switch ( a_Level )
{
#ifdef NTONLY
case 502 : t_ActiveTime = ( (SESSION_INFO_502 *) pTmpBuf )->sesi502_time;
break;
#endif
case 2: t_ActiveTime = ( (SESSION_INFO_2 *) pTmpBuf )->sesi2_time;
break;
case 1: t_ActiveTime = ( (SESSION_INFO_1 *) pTmpBuf )->sesi1_time;
break;
case 10: t_ActiveTime = ( (SESSION_INFO_10 *) pTmpBuf )->sesi10_time;
break;
#if 0
#ifdef WIN9XONLY
case 50: t_ActiveTime = ( (SESSION_INFO_50 *) pTmpBuf )->sesi50_time;
break;
#endif
#endif // #if 0
}
if ( SUCCEEDED ( hRes ) )
{
if ( pInstance->SetWORD ( IDS_ActiveTime, t_ActiveTime ) == FALSE )
{
hRes = WBEM_E_PROVIDER_FAILURE ;
}
}
}
}
if ( SUCCEEDED ( hRes ) )
{
if ( dwPropertiesReq & SESSION_PROP_IdleTime )
{
DWORD t_IdleTime;
switch ( a_Level )
{
#ifdef NTONLY
case 502 : t_IdleTime = ( (SESSION_INFO_502 *) pTmpBuf )->sesi502_idle_time;
break;
#endif
case 2: t_IdleTime = ( (SESSION_INFO_2 *) pTmpBuf )->sesi2_idle_time;
break;
case 1: t_IdleTime = ( (SESSION_INFO_1 *) pTmpBuf )->sesi1_idle_time;
break;
case 10: t_IdleTime = ( (SESSION_INFO_10 *) pTmpBuf )->sesi10_idle_time;
break;
#if 0
#ifdef WIN9XONLY
case 50: t_IdleTime = ( (SESSION_INFO_50 *) pTmpBuf )->sesi50_idle_time;
break;
#endif
#endif
}
if ( SUCCEEDED ( hRes ) )
{
if ( pInstance->SetWORD ( IDS_IdleTime, t_IdleTime ) == FALSE )
{
hRes = WBEM_E_PROVIDER_FAILURE ;
}
}
}
}
if ( SUCCEEDED ( hRes ) )
{
if ( dwPropertiesReq & SESSION_PROP_NumOpens )
{
DWORD t_NumOpens;
switch ( a_Level )
{
#ifdef NTONLY
case 502 : t_NumOpens = ( (SESSION_INFO_502 *) pTmpBuf )->sesi502_num_opens;
break;
#endif
case 2: t_NumOpens = ( (SESSION_INFO_2 *) pTmpBuf )->sesi2_num_opens;
break;
case 1: t_NumOpens = ( (SESSION_INFO_1 *) pTmpBuf )->sesi1_num_opens;
break;
#if 0
#ifdef WIN9XONLY
case 50: t_NumOpens = ( (SESSION_INFO_50 *) pTmpBuf )->sesi50_num_opens;
break;
#endif
#endif
}
if ( SUCCEEDED ( hRes ) )
{
if ( pInstance->SetWORD ( IDS_ResourcesOpened, t_NumOpens ) == FALSE )
{
hRes = WBEM_E_PROVIDER_FAILURE ;
}
}
}
}
if ( SUCCEEDED ( hRes ) )
{
if ( dwPropertiesReq & SESSION_PROP_TransportName )
{
CHString t_TransportName;
#ifdef NTONLY
if ( a_Level == 502 )
{
t_TransportName = ( (SESSION_INFO_502 *) pTmpBuf )->sesi502_transport;
}
#endif
#if 0
#ifdef WIN9XONLY
if ( a_Level == 50 )
{
WCHAR w_TName[100];
w_TName[0] = ( (SESSION_INFO_50 *) pTmpBuf )->sesi50_protocol;
w_TName [ 1 ] = _T('\0');
t_TransportName = w_TName;
}
#endif
#endif
if ( SUCCEEDED ( hRes ) )
{
if ( pInstance->SetCHString ( IDS_TransportName, t_TransportName ) == FALSE )
{
hRes = WBEM_E_PROVIDER_FAILURE ;
}
}
}
}
if ( SUCCEEDED ( hRes ) )
{
if ( dwPropertiesReq & SESSION_PROP_ClientType )
{
CHString t_ClientType;
switch ( a_Level )
{
#ifdef NTONLY
case 502 : t_ClientType = ( (SESSION_INFO_502 *) pTmpBuf)->sesi502_cltype_name;
break;
#endif
#if 0
#ifdef WIN9XONLY
case 2: t_ClientType = ( (SESSION_INFO_2 *) pTmpBuf )->sesi2_cltype_name;
break;
#endif
#endif // #if 0
}
if ( SUCCEEDED ( hRes ) )
{
if ( pInstance->SetCHString ( IDS_ClientType, t_ClientType ) == FALSE )
{
hRes = WBEM_E_PROVIDER_FAILURE ;
}
}
}
}
#ifdef NTONLY
if ( SUCCEEDED ( hRes ) )
{
if ( dwPropertiesReq & SESSION_PROP_SessionType )
{
DWORD dwflags;
DWORD dwSessionType;
switch ( a_Level )
{
case 502 : dwflags = ( (SESSION_INFO_502 *) pTmpBuf )->sesi502_user_flags;
break;
}
switch ( dwflags )
{
case SESS_GUEST: dwSessionType = 0;
break;
case SESS_NOENCRYPTION: dwSessionType = 1;
break;
default : dwSessionType = dwSessionType = 2;
}
if ( SUCCEEDED ( hRes ) )
{
if ( pInstance->SetDWORD ( IDS_SessionType, dwSessionType ) == FALSE )
{
hRes = WBEM_E_PROVIDER_FAILURE ;
}
}
}
}
#endif
return hRes;
}
#if 0
#ifdef WIN9XONLY
/*****************************************************************************
*
* FUNCTION : CSession::Enum9XSessionInfo
*
* DESCRIPTION : Enumerating all the Sessions on 9X
*
*****************************************************************************/
HRESULT CSession :: Enum9XSessionInfo (
short a_Level,
MethodContext *pMethodContext,
DWORD dwPropertiesReq
)
{
NET_API_STATUS t_Status = NERR_Success;
HRESULT hRes = WBEM_S_NO_ERROR;
unsigned short dwNoOfEntriesRead = 0;
unsigned short dwTotalSessions = 0;
void *pBuf = NULL;
void *pTmpBuf = NULL;
DWORD dwSize = 0;
// Determine the size of the structure, for the level passed.
switch ( a_Level )
{
case 1: dwSize = sizeof ( SESSION_INFO_1 );
break;
case 2: dwSize = sizeof ( SESSION_INFO_2 );
break;
case 10: dwSize = sizeof ( SESSION_INFO_10 );
break;
case 50: dwSize = sizeof ( SESSION_INFO_50 );
break;
}
unsigned short cbBuffer = MAX_ENTRIES * dwSize;
pBuf = ( char FAR * ) malloc ( cbBuffer );
if ( pBuf != NULL )
{
try
{
t_Status = NetSessionEnum(
NULL,
a_Level,
(char FAR *) pBuf,
cbBuffer,
&dwNoOfEntriesRead,
&dwTotalSessions
);
if ( ( t_Status == ERROR_MORE_DATA ) || ( dwTotalSessions > dwNoOfEntriesRead ) )
{
// Free the buffer and make a API call again by allocating a buffer of the required size.
free ( pBuf );
pBuf = NULL;
cbBuffer = ( dwTotalSessions * dwSize );
pBuf = ( char FAR * ) malloc ( cbBuffer );
if ( pBuf != NULL )
{
try
{
t_Status = NetSessionEnum(
NULL,
a_Level,
( char FAR *) pBuf,
cbBuffer,
&dwNoOfEntriesRead,
&dwTotalSessions
);
if ( t_Status != NERR_Success )
{
hRes = WBEM_E_FAILED;
}
}
catch ( ... )
{
if ( pBuf != NULL )
{
free ( pBuf );
}
pBuf = NULL;
}
}
else
{
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
}
}
}
catch ( ... )
{
if ( pBuf != NULL )
{
free ( pBuf );
pBuf = NULL;
}
throw;
}
}
else
{
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
}
if ( SUCCEEDED ( hRes ) )
{
if ( ( dwNoOfEntriesRead > 0 ) && ( pBuf != NULL ) )
{
try
{
pTmpBuf = pBuf;
for ( int i = 0; i < dwNoOfEntriesRead; i++ )
{
CInstancePtr pInstance ( CreateNewInstance ( pMethodContext ), FALSE );
hRes = LoadData ( a_Level, pBuf, dwPropertiesReq, pInstance );
if ( SUCCEEDED ( hRes ) )
{
hRes = pInstance->Commit();
if ( FAILED ( hRes ) )
{
break;
}
}
// here need to go to the next structure based on the level, we will typecast with the apropriate structure
// and then increment by one
switch ( a_Level )
{
case 2: SESSION_INFO_2 *pTmpTmpBuf2;
pTmpTmpBuf2 = (SESSION_INFO_2 *) pTmpBuf;
pTmpTmpBuf2 ++;
pTmpBuf = ( void * ) pTmpTmpBuf2;
break;
case 1: SESSION_INFO_1 *pTmpTmpBuf1;
pTmpTmpBuf1 = ( SESSION_INFO_1 *) pTmpBuf;
pTmpTmpBuf1 ++;
pTmpBuf = ( void * ) pTmpTmpBuf1;
break;
case 10: SESSION_INFO_10 *pTmpTmpBuf10;
pTmpTmpBuf10 = ( SESSION_INFO_10 *) pTmpBuf;
pTmpTmpBuf10 ++;
pTmpBuf = ( void * ) pTmpTmpBuf10;
break;
case 50: SESSION_INFO_50 *pTmpTmpBuf50;
pTmpTmpBuf50 = ( SESSION_INFO_50 *) pTmpBuf;
pTmpTmpBuf50 ++;
pTmpBuf = ( void * ) pTmpTmpBuf50;
break;
default: hRes = WBEM_E_FAILED;
}
}
}
catch ( ... )
{
free ( pBuf );
pBuf = NULL;
throw;
}
free ( pBuf );
pBuf = NULL;
}
}
return hRes;
}
/*****************************************************************************
*
* FUNCTION : CSession::FindAndSet9XSession
*
* DESCRIPTION : Find a single instance based on the key properties for the
* class.
*
*****************************************************************************/
HRESULT CSession::FindAndSet9XSession (
LPCWSTR a_ComputerName,
LPWSTR a_UserName,
short a_Level,
DWORD dwPropertiesReq,
CInstance *pInstance,
DWORD eOperation
)
{
HRESULT hRes = WBEM_S_NO_ERROR;
NET_API_STATUS t_Status = NERR_Success;
CHString t_TempKey;
t_TempKey.Format ( L"%s%s",L"\\\\", a_ComputerName );
unsigned short dwNoOfEntriesRead = 0;
unsigned short dwTotalSessions = 0;
void *pBuf = NULL;
void *pTmpBuf = NULL;
DWORD dwSize = 0;
// Determine the size of the structure, for the level passed.
switch ( a_Level )
{
case 1: dwSize = sizeof ( SESSION_INFO_1 );
break;
case 2: dwSize = sizeof ( SESSION_INFO_2 );
break;
case 10: dwSize = sizeof ( SESSION_INFO_10 );
break;
case 50: dwSize = sizeof ( SESSION_INFO_50 );
break;
}
unsigned short cbBuffer = 0;
t_Status = NetSessionGetInfo(
NULL,
(const char FAR *) ( a_UserName.GetBuffer ( 0 ) ),
a_Level,
( char FAR * ) pBuf,
cbBuffer,
&dwTotalSessions
);
hRes = dwTotalSessions == 0 ? WBEM_E_NOT_FOUND : hRes;
if ( SUCCEEDED ( hRes ) )
{
// here we need to read all the entries associated with the user, and then
// search from this list for a given computer
if ( t_Status != NERR_BufTooSmall )
{
cbBuffer = dwTotalSessions * dwSize;
pBuf = ( char FAR * ) malloc ( cbBuffer );
if ( pBuf != NULL )
{
t_Status = NetSessionGetInfo(
NULL,
(const char FAR *) ( a_UserName.GetBuffer ( 0 ) ),
a_Level,
( char FAR * ) pBuf,
cbBuffer,
&dwTotalSessions
);
try
{
// now search for a given computer
void *pTempBuf = pBuf;
int i = 0;
for ( i = 0; i < dwTotalSessions; i ++ )
{
CHString t_CompName;
switch ( a_Level )
{
case 2: SESSION_INFO_2 *pTmpTmpBuf2;
pTmpTmpBuf2 = (SESSION_INFO_2 *) pTmpBuf;
t_CompName = pTmpTmpBuf2->sesi2_cname;
break;
case 1: SESSION_INFO_1 *pTmpTmpBuf1;
pTmpTmpBuf1 = (SESSION_INFO_1 *) pTmpBuf;
t_CompName = pTmpTmpBuf1->sesi1_cname;
break;
case 10: SESSION_INFO_10 *pTmpTmpBuf10;
pTmpTmpBuf10 = (SESSION_INFO_10 *) pTmpBuf;
t_CompName = pTmpTmpBuf10->sesi10_cname;
break;
case 50: SESSION_INFO_50 *pTmpTmpBuf50;
pTmpTmpBuf50 = (SESSION_INFO_50 *) pTmpBuf;
t_CompName = pTmpTmpBuf50->sesi50_cname;
break;
}
if ( a_ComputerName.CompareNoCase ( t_TempKey ) == 0 )
{
break;
}
// otherwise need to go to the next entry;
switch ( a_Level )
{
case 2: SESSION_INFO_2 *pTmpTmpBuf2;
pTmpTmpBuf2 = (SESSION_INFO_2 *) pTmpBuf;
pTmpTmpBuf2++;
pTmpBuf = ( void * ) pTmpTmpBuf2;
break;
case 1: SESSION_INFO_1 *pTmpTmpBuf1;
pTmpTmpBuf1 = (SESSION_INFO_1 *) pTmpBuf;
pTmpTmpBuf1++;
pTmpBuf = ( void * ) pTmpTmpBuf1;
break;
case 10: SESSION_INFO_10 *pTmpTmpBuf10;
pTmpTmpBuf10 = (SESSION_INFO_10 *) pTmpBuf;
pTmpTmpBuf10++;
pTmpBuf = ( void * ) pTmpTmpBuf10;
break;
case 50: SESSION_INFO_50 *pTmpTmpBuf50;
pTmpTmpBuf50 = (SESSION_INFO_50 *) pTmpBuf;
pTmpTmpBuf50++;
pTmpBuf = ( void * ) pTmpTmpBuf50;
break;
}
}
if ( i >= dwTotalSessions )
{
hRes = WBEM_E_NOT_FOUND;
}
}
catch ( ... )
{
free ( pBuf );
throw;
}
}
else
{
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
}
}
else
{
hRes = WBEM_E_FAILED;
}
}
if ( SUCCEEDED ( hRes ) )
{
try
{
switch ( eOperation )
{
case Get: hRes = LoadData ( a_Level, pBuf, dwPropertiesReq, pInstance );
break;
// Expects a Session Key as a parameter and as a result we need to read more than one structure for every instance.
// but the documents say it requires a sharename.
/* case Delete: hRes = t_Status = NetSessionDel(
NULL,
(LPTSTR) t_TempKey.GetBuffer ( 0 ),
(LPTSTR) a_UserName.GetBuffer ( 0 ) ;
);
hRes = t_Status == NERR_Success ? hRes : WBEM_E_FAILED;
break;*/
default: hRes = WBEM_E_PROVIDER_NOT_CAPABLE;
break;
}
}
catch ( ... )
{
free ( pBuf );
pBuf = NULL;
throw;
}
free ( pBuf );
pBuf = NULL;
}
return hRes ;
}
/*****************************************************************************
*
* FUNCTION : Session::Optimize9XQuery
*
* DESCRIPTION : Optimizes a query based on the key values.
*
*****************************************************************************/
HRESULT CSession::Optimize9XQuery (
CHStringArray &a_ComputerValues,
CHStringArray &a_UserValues,
short a_Level,
MethodContext *pMethodContext,
DWORD dwPropertiesReq
)
{
HRESULT hRes = WBEM_S_NO_ERROR;
NET_API_STATUS t_Status = NERR_Success;
if ( a_ComputerValues.GetSize() == 0 )
{
// This is a query for which there is no where clause, so it means only a few Properties are requested
// hence we need to deliver only those properties of instances to the WinMgmt while enumerating Sessions
hRes = Enum9XSessionInfo (
a_Level,
pMethodContext,
dwPropertiesReq
);
}
else
if ( a_UserValues.GetSize() != 0 )
{
DWORD dwNoOfEntriesRead = 0;
DWORD dwTotalSessions = 0;
void *pBuf = NULL;
void *pTmpBuf = NULL;
DWORD dwSize = 0;
BOOL bNoMoreEnums = FALSE;
// Determine the size of the structure, for the level passed.
switch ( a_Level )
{
case 1: dwSize = sizeof ( SESSION_INFO_1 );
break;
case 2: dwSize = sizeof ( SESSION_INFO_2 );
break;
case 10: dwSize = sizeof ( SESSION_INFO_10 );
break;
case 50: dwSize = sizeof ( SESSION_INFO_50 );
break;
}
for ( int i = 0; i < a_UserValues.GetSize(); i++ )
{
unsigned short cbBuffer = 0;
t_Status = NetSessionGetInfo(
NULL,
(const char FAR *) ( a_UserValues.GetAt ( i ).GetBuffer ( 0 ) ),
a_Level,
( char FAR * ) pBuf,
cbBuffer,
(unsigned short FAR *) dwTotalSessions
);
if ( dwTotalSessions == 0 )
{
continue;
}
if ( SUCCEEDED ( hRes ) )
{
// here we need to read all the entries associated with the user, and then
// search from this list for a given computer
if ( t_Status != NERR_BufTooSmall )
{
cbBuffer = dwTotalSessions * dwSize;
pBuf = ( char FAR * ) malloc ( cbBuffer );
if ( pBuf != NULL )
{
t_Status = NetSessionGetInfo(
NULL,
(const char FAR *) ( a_UserValues.GetAt ( i ).GetBuffer ( 0 ) ),
a_Level,
( char FAR * ) pBuf,
cbBuffer,
(unsigned short FAR *) dwTotalSessions
);
try
{
void *pTempBuf = pBuf;
int i = 0;
for ( i = 0; i < dwTotalSessions; i ++ )
{
CInstancePtr pInstance ( CreateNewInstance ( pMethodContext ), FALSE );
hRes = LoadData ( a_Level, pBuf, dwPropertiesReq, pInstance );
if ( SUCCEEDED ( hRes ) )
{
hRes = pInstance->Commit();
if ( FAILED ( hRes ) )
{
bNoMoreEnums = TRUE;
break;
}
}
if ( bNoMoreEnums )
{
break;
}
// otherwise need to go to the next entry;
switch ( a_Level )
{
case 2: SESSION_INFO_2 *pTmpTmpBuf2;
pTmpTmpBuf2 = (SESSION_INFO_2 *) pTmpBuf;
pTmpTmpBuf2++;
pTmpBuf = ( void * ) pTmpTmpBuf2;
break;
case 1: SESSION_INFO_1 *pTmpTmpBuf1;
pTmpTmpBuf1 = (SESSION_INFO_1 *) pTmpBuf;
pTmpTmpBuf1++;
pTmpBuf = ( void * ) pTmpTmpBuf1;
break;
case 10: SESSION_INFO_10 *pTmpTmpBuf10;
pTmpTmpBuf10 = (SESSION_INFO_10 *) pTmpBuf;
pTmpTmpBuf10++;
pTmpBuf = ( void * ) pTmpTmpBuf10;
break;
case 50: SESSION_INFO_50 *pTmpTmpBuf50;
pTmpTmpBuf50 = (SESSION_INFO_50 *) pTmpBuf;
pTmpTmpBuf50++;
pTmpBuf = ( void * ) pTmpTmpBuf50;
break;
}
}
}
catch ( ... )
{
free ( pBuf );
pBuf = NULL;
throw;
}
free ( pBuf );
pBuf = NULL;
}
else
{
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
}
}
}
}
}
else
{
hRes = WBEM_E_PROVIDER_NOT_CAPABLE;
}
return hRes;
}
/*****************************************************************************
*
* FUNCTION : CSession::Get9XLevelInfo
*
* DESCRIPTION : Getting the level info, so that the appropriate structure
* Can be passed to make a call.
*
*****************************************************************************/
void CSession :: Get9XLevelInfo (
DWORD dwPropertiesReq,
short *a_Level
)
{
// Right now making an assumption that Transport/Protocol name is not required
// as otherwise we will need to make 2 api calls if we need to get Protocol and Clienttype.
// There is no support for the other levels other than level 50.
*a_Level = 50;
/*if ( dwPropertiesReq == SESSION_ALL_PROPS )
{
*a_Level = 2;
}
else
if (dwPropertiesReq & SESSION_PROP_NumOpens)
{
*a_Level = 1;
}
else
{
*a_Level = 10;
}*/
}
#endif
#endif // #if 0
/*****************************************************************************
*
* FUNCTION : CSession::SetPropertiesReq
*
* DESCRIPTION : Setting a bitmap for the required properties
*
*****************************************************************************/
void CSession :: SetPropertiesReq (
CFrameworkQuery &Query,
DWORD &dwPropertiesReq
)
{
dwPropertiesReq = 0;
if ( Query.IsPropertyRequired ( IDS_ComputerName ) )
{
dwPropertiesReq |= SESSION_PROP_Computer;
}
if ( Query.IsPropertyRequired ( IDS_UserName ) )
{
dwPropertiesReq |= SESSION_PROP_User;
}
if ( Query.IsPropertyRequired ( IDS_SessionType ) )
{
dwPropertiesReq |= SESSION_PROP_SessionType;
}
if ( Query.IsPropertyRequired ( IDS_ClientType ) )
{
dwPropertiesReq |= SESSION_PROP_ClientType;
}
if ( Query.IsPropertyRequired ( IDS_TransportName ) )
{
dwPropertiesReq |= SESSION_PROP_TransportName;
}
if ( Query.IsPropertyRequired ( IDS_ResourcesOpened ) )
{
dwPropertiesReq |= SESSION_PROP_NumOpens;
}
if ( Query.IsPropertyRequired ( IDS_ActiveTime ) )
{
dwPropertiesReq |= SESSION_PROP_ActiveTime;
}
if ( Query.IsPropertyRequired ( IDS_IdleTime ) )
{
dwPropertiesReq |= SESSION_PROP_IdleTime;
}
}