/******************************************************************
Copyright (C) 2000 Microsoft Corp.

  Terms.CPP -- WMI provider class implementation
  
    Generated by Microsoft WMI Code Generation Engine
    
      TO DO: - See individual function headers
      - When linking, make sure you link to framedyd.lib & 
      msvcrtd.lib (debug) or framedyn.lib & msvcrt.lib (retail).
      
        Description: 
        
          
            
******************************************************************/
#include "stdafx.h"
#include <fwcommon.h>  // This must be the first include.
#include "Winstation.h"
#include "registry.h"
#include "winsta.h"
#include "resource.h"
#include <regapi.h>
#include <sddl.h>
#include <provider.h>


#define ARRAYSIZE( rg ) sizeof( rg ) / sizeof( rg[0] )
#define GUID_LENGTH 40
TCHAR tchErrorMessage[ 80 ] = {0};

const static WCHAR* pErrorClass = L"\\\\.\\root\\cimv2:TerminalError";


/*****************************************************************************
*
*  FUNCTION    :   CWin32_Terminal::CWin32_Terminal
*
*  DESCRIPTION :   Constructor
*
*  INPUTS      :   none
*
*  RETURNS     :   nothing
*
*  COMMENTS    :   Calls the Provider constructor.
*
*****************************************************************************/
CWin32_Terminal::CWin32_Terminal (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) : Provider( lpwszName, lpwszNameSpace )
{
    int retval = 1;

    if ( g_hInstance != NULL)
    {
        TRC2((TB, "CWin32_Terminal_ctor"));

        _tcscpy(m_szEnableTerminal, _T("fEnableTerminal"));

        _tcscpy(m_szTerminalName, _T("TerminalName"));

        _tcscpy(m_szNewTerminalName, _T("NewTerminalName"));

        _tcscpy(m_szEnable, _T("Enable"));

        _tcscpy(m_szRename, _T("Rename"));

        _tcscpy(m_szDelete, _T("Delete"));
        
    }
}


//==================
/*****************************************************************************
*
*  FUNCTION    :   CWin32_Terminal::~CWin32_Terminal
*  DESCRIPTION :   Destructor
*  INPUTS      :   none
*  RETURNS     :   nothing
*****************************************************************************/

CWin32_Terminal::~CWin32_Terminal ()
{
    
}


//==================
/*****************************************************************************
*
*  FUNCTION    :    CWin32_Terminal::EnumerateInstances
*
*  DESCRIPTION :    Returns all the instances of this class.
*
*  INPUTS      :    A pointer to the MethodContext for communication with WinMgmt.
*                   A long that contains the flags described in 
*                   IWbemServices::CreateInstanceEnumAsync.  Note that the following
*                   flags are handled by (and filtered out by) WinMgmt:
*                   WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY, 
*                   WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
*  RETURNS     :    WBEM_S_NO_ERROR if successful
*
*  COMMENTS    :    All instances on the machine are returned here and
*                   all properties that this class knows how to populate must 
*                   be filled in.  If there are no instances, return 
*                   WBEM_S_NO_ERROR.  
*****************************************************************************/



HRESULT CWin32_Terminal::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
    HRESULT hr = WBEM_S_NO_ERROR;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;    	
    CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}

	hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        

	TRC2((TB,"Terminal@EnumerateInstances: GetWinstationList ret 0x%x" , hr )); 	
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {   
            CInstance* pInstance = CreateNewInstance(pMethodContext);
            
            if( pInstance == NULL)
            {
                ERR((TB,"Terminal@EnumerateInstances: CreateNewInstance failed"));                
                
                hr = WBEM_E_OUT_OF_MEMORY;
                
                break;
            }              
            
            hr = LoadPropertyValues( pInstance, BIT_ALL_PROPERTIES, &pWS[ ulNum ] );
            
            if (SUCCEEDED( hr ) ) 
            {
                hr = pInstance->Commit();       
            }            
            pInstance->Release( );
        }
    }

    if( pWS != NULL)
    {
        CoTaskMemFree(pWS);
    }
    
    return hr;
}


//=--------------------

/*****************************************************************************
*
*  FUNCTION    :    CWin32_Terminal::GetObject
*
*  DESCRIPTION :    Find a single instance based on the key property, TerminalName. 
*
*  INPUTS      :    A pointer to a CInstance object containing the key properties. 
*                   A long that contains the flags described in 
*                   IWbemServices::GetObjectAsync.  
*
*  RETURNS     :    WBEM_S_NO_ERROR if the instance can be found
*                   WBEM_E_NOT_FOUND if the instance described by the key properties 
*                   could not be found
*                   WBEM_E_FAILED if the instance could be found but another error 
*                   occurred. 
*
*****************************************************************************/

HRESULT CWin32_Terminal::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;   
    LONG lSize;
    ULONGLONG ulRequiredProperties = 0;
    PWS  pWS = NULL;
    CHString chTermName;

    TRC2((TB,"TSCFGWMI!CWin32_Terminal_GetObject"));
    
    CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL )
    {
        ERR((TB,"Terminal@GetObject: invalid pointer" ));
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    pInstance->GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szEnableTerminal))
        ulRequiredProperties |= BIT_FENABLETERMINAL;

    hr = StackObj.m_pCfgComp->GetWSInfo( ( LPTSTR )( LPCTSTR )chTermName, &lSize, &pWS);
    
    if( SUCCEEDED (hr) && pWS != NULL )        
    {
        hr = LoadPropertyValues(pInstance, ulRequiredProperties, pWS);        
    }
    else
    {
        hr = WBEM_E_INVALID_OBJECT;
    }
    

    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
    }    

    return hr ;
}

//=--------------------
/*****************************************************************************
*
*  FUNCTION    :    CWin32_Terminal::ExecQuery
*
*  DESCRIPTION :    You are passed a method context to use in the creation of 
*                   instances that satisfy the query, and a CFrameworkQuery 
*                   which describes the query.  Create and populate all 
*                   instances which satisfy the query.  You may return more 
*                   instances or more properties than are requested and WinMgmt 
*                   will post filter out any that do not apply.
*                  There are two different ways query processing
*                  can be used to improve performance.  
* 
* Method 1 - Returns data for only those fields that were requested.  This can  
*            optimize performance if some properties are very expensive to retrieve.  
*
* Method 2 - Returns only the requested records in the "Where" clause. There is a method
*            that can be run against the CFrameworkQuery object where you pass it the name
*            of a property, and it will tell you all the values they requested.  For example,  
*            if the query is of the form 
*            'Select * from Win32_Terminal where TerminalName = "RDP-Tcp" or TerminalName = "ICA-Tcp"',
*            GetValuesForProp(L"TerminalName") sends back an array that contains {"RDP-Tcp", "ICA-Tcp"}.  
*            Or if the query was of the form 
*            'Select * from Win32_Terminal where TerminalName = "RDP-Tcp" AND fEnableTerminal = TRUE' 
*            (note that this query, unlike the one in the paragraph above, uses AND), then 
*            GetValuesForProp(L"TerminalName") will return {"RDP-Tcp"}.
*
*****************************************************************************/
HRESULT CWin32_Terminal::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{    
   
    HRESULT hr = WBEM_E_NOT_FOUND;
    ULONGLONG ulRequiredProperties = 0;
    CHStringArray asNames;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;
    
    // Method 2
    Query.GetValuesForProp(m_szTerminalName, asNames);
    
    BOOL bGetAllInstances = asNames.GetSize() == 0;
    
    // Method 1
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szEnableTerminal))
        ulRequiredProperties |= BIT_FENABLETERMINAL;
    
    CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
	
    
	hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {  
            
            // Method 2 - Check if the query CAN be processed by 'name'. If yes, return only those names.
            
            if( bGetAllInstances || IsInList(asNames, pWS[ulNum].Name))
            {                
                CInstance* pInstance = CreateNewInstance(pMethodContext); 
                
                if( pInstance != NULL)
                {            
                    pInstance->SetCHString(m_szTerminalName, CHString(pWS[ulNum].Name));

                    hr = LoadPropertyValues( pInstance, ulRequiredProperties, &pWS[ ulNum ] );
            
                    if( SUCCEEDED( hr ) )
                    {
                        hr = pInstance->Commit();
                    }                
                    pInstance->Release();
                }
            }
        }
    }
    
    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
    }
    
    return hr;
    
}


//=-----------

BOOL CWin32_Terminal::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
    DWORD dwSize = asArray.GetSize();
    
    for (DWORD x=0; x < dwSize; x++)
    {
        if (asArray[x].CompareNoCase(pszString) == 0)
        {
            return TRUE;
        }
    }
    
    return FALSE;
}

//=--------------------
/*****************************************************************************
*
*  FUNCTION    : CWin32_Terminal::PutInstance
*
*  DESCRIPTION :   
*
*  INPUTS      :    A pointer to a CInstance object containing the key properties. 
*                   A long that contains the flags described in 
*                   IWbemServices::PutInstanceAsync.  
*
*  RETURNS     :    WBEM_E_PROVIDER_NOT_CAPABLE if PutInstance is not available
*                   WBEM_E_FAILED if there is an error delivering the instance
*                   WBEM_E_INVALID_PARAMETER if any of the instance properties 
*                   are incorrect.
*                   WBEM_S_NO_ERROR if instance is properly delivered
*
*  COMMENTS    : TO DO: If you don't intend to support writing to your provider, 
*                       or are creating a 'method only' provider, remove this 
*                       method.
*
*****************************************************************************/
HRESULT CWin32_Terminal::PutInstance ( const CInstance &Instance, long lFlags)
{

    /*
    HRESULT hr = WBEM_S_NO_ERROR; 
    DWORD dwfEnable = 0;
    CHString chTermName; 
    ULONG ulTerminals = 0;
    ULONG ulSize = 0;
    ULONG ulNum = 0;
    PWS pWS = NULL;

    static USERCONFIG g_uc;

    static ASYNCCONFIG g_ac;
    
    if( g_pCfgComp == NULL ) 
    {
        ERR((TB,"Terminal@PutInstance: invalid interface" ));
        
        return WBEM_E_INITIALIZATION_FAILURE;
    }
    
    Instance.GetDWORD(m_szEnableTerminal, dwfEnable);
    
    if ( dwfEnable != 0 && dwfEnable !=1 )
    {
        return WBEM_E_INVALID_PARAMETER;
    }
    
    Instance.GetCHString(m_szTerminalName, chTermName);
    
    if(chTermName.GetLength( ) > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if(chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }

    hr = g_pCfgComp->ForceUpdate();
    

    if( SUCCEEDED( hr ))
    {        
        hr = g_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    }  
    
    do
    {        
        if( SUCCEEDED( hr ) && pWS != NULL )
        {           
            for ( ulNum = 0; ulNum < ulTerminals ; ulNum++)
            {               
                if( _tcsicmp( (LPCTSTR) &pWS[ulNum].Name, (LPTSTR)(LPCTSTR) chTermName) == 0)
                {
                    hr = g_pCfgComp->EnableWinstation( (LPTSTR) (LPCTSTR) chTermName,  dwfEnable);
                    break;
                }
            }

            if( ulNum >= ulTerminals )
            {
                ULONG ulSize = 0;

                lstrcpy( pWS->Name, (LPTSTR)(LPCTSTR)chTermName);
                pWS->fEnableWinstation = 1;
                pWS->uMaxInstanceCount = 0xffffffff;
                lstrcpy( pWS->Comment, L"");
                lstrcpy( pWS->pdName, L"tcp");
                lstrcpy( pWS->wdName, L"Microsoft RDP 5.1");
                pWS->PdClass = 2;
                pWS->LanAdapter = 0;
        
    
                RegDefaultUserConfigQuery( NULL ,
                    &g_uc,
                    sizeof( USERCONFIG ) ,
                    &ulSize );

                hr = g_pCfgComp->CreateNewWS( *pWS, sizeof( USERCONFIG ) , &g_uc, NULL);            
                TRC2((TB,"Terminal@PutInstance: CreateNewWS returned 0x%x\n", hr));
            }
        }       
        if( FAILED( hr ) )
        {
            CHString sRelPath;
        
            Instance.GetCHString(L"__RelPath", sRelPath);
            CInstance *pErrorInstance = NULL;
        
            CWbemProviderGlue::GetInstanceByPath(pErrorClass, &pErrorInstance);
        
            if( pErrorInstance != NULL )
            {
                LoadString( g_hInstance , IDS_ERR_PUTTERMINAL, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                pErrorInstance->SetWCHARSplat(L"Description", tchErrorMessage);
            
                LoadString( g_hInstance , IDS_ERR_PUTINSTANCE, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                pErrorInstance->SetWCHARSplat(L"Operation", tchErrorMessage);
            
                pErrorInstance->SetCHString(L"ParameterInfo", sRelPath);
                pErrorInstance->SetWCHARSplat(L"ProviderName", PROVIDER_NAME_Win32_WIN32_TERMINAL_Prov);
                pErrorInstance->SetDWORD(L"StatusCode", WBEM_E_INVALID_PARAMETER);
            
                pErrorInstance->SetCHString(L"TerminalName", chTermName );
            
                IWbemClassObject *pObj = pErrorInstance->GetClassObjectInterface();
            
                MethodContext *pMethodContext = Instance.GetMethodContext(); 
            
                if( pObj != NULL )
                {
                    if (pMethodContext != NULL)
                    {
                        pMethodContext->SetStatusObject(pObj);
                    }
                
                
                    pObj->Release();
                }
                pErrorInstance->Release();
            }
        }
    }while (0);

    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);        
    }
   
    return hr;
    */
    return WBEM_E_PROVIDER_NOT_CAPABLE;

    
}

//=----------------------------------------------------------------------------------------------------------

HRESULT CWin32_Terminal::DeleteInstance ( const CInstance &Instance,  long lFlags )
{
    
    return WBEM_E_PROVIDER_NOT_CAPABLE;
/*
    HRESULT hr = WBEM_E_NOT_FOUND;
    
    CHString chTermName;
    
    if( g_pCfgComp == NULL )
    {
        return WBEM_E_INITIALIZATION_FAILURE;
    }
    
    Instance.GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength( ) > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if (chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }    

    hr = g_pCfgComp->DeleteWS((LPTSTR)(LPCTSTR) chTermName);

    TRC2((TB,"Terminal@ExecMethod: Delete returned 0x%x\n" , hr ));
    
    return hr;
  */     
    
}

//=----------------------------------------------------------------------------------------------------------
HRESULT CWin32_Terminal::ExecMethod ( const CInstance& Inst,
                                     const BSTR bstrMethodName,
                                     CInstance *pInParams,
                                     CInstance *pOutParams,
                                     long lFlags)
                                     
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    CHString chTermName;
	ICfgComp *pCfgComp = NULL;

    if( pInParams == NULL)
    {
        return WBEM_E_INVALID_METHOD_PARAMETERS;
    }

    CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    Inst.GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength( ) > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if (chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    
    if( _wcsicmp(bstrMethodName, m_szEnable ) == 0 )
    {
        // Enables or Disables the Terminal.
        // Return Value: 0 if Success or an error.
        // uint32 Enable ([In] Boolean fEnable)
        
        DWORD dwfEnable = 0;
        ULONG  Size = 0;
        bool bRet;
        
        bRet = pInParams->GetDWORD(m_szEnableTerminal, dwfEnable);
        
        if ( !bRet || ( dwfEnable != 0 && dwfEnable != 1 ) )
        {
            return WBEM_E_INVALID_METHOD_PARAMETERS;
        }
        
        hr = StackObj.m_pCfgComp->EnableWinstation( (LPTSTR)(LPCTSTR) chTermName, dwfEnable);            
        
        TRC2((TB,"Terminal@ExecMethod: Enable returned 0x%x\n" , hr ));

        if( SUCCEEDED( hr ) )
        {
            hr = StackObj.m_pCfgComp->ForceUpdate();
        }
        
        if( SUCCEEDED( hr ) && pOutParams != NULL )
        {
            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
        }                 
    }
    else if( _wcsicmp( bstrMethodName , m_szRename ) == 0 )
    {
        //  Renames the Terminal.
        //  uint32 Rename([In] string NewTerminalName) 
        
        CHString chNewTermName;

        pInParams->GetCHString(m_szNewTerminalName, chNewTermName);
        
        if ( chNewTermName.GetLength() > WINSTATIONNAME_LENGTH)
        {
            return WBEM_E_VALUE_OUT_OF_RANGE;
        }
        
        if ( chNewTermName.IsEmpty() != 0)
        {
            return WBEM_E_ILLEGAL_NULL;
        }
        
        hr = StackObj.m_pCfgComp->RenameWinstation((LPTSTR)(LPCTSTR) chTermName, (LPTSTR)(LPCTSTR) chNewTermName);
        
        TRC2((TB,"Terminal@ExecMethod: Rename returned 0x%x\n" , hr ));

        if( SUCCEEDED( hr ) )
        {
            hr = StackObj.m_pCfgComp->ForceUpdate();
        }
        
        if (SUCCEEDED (hr) && pOutParams != NULL )
        {
            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
            
        }       
    }
    
    else if (_wcsicmp(bstrMethodName, m_szDelete) == 0)
    {
        //  Delete the Terminal.  
        //  uint32 Delete() ;
        
        hr = StackObj.m_pCfgComp->DeleteWS((LPTSTR)(LPCTSTR) chTermName);

        TRC2((TB,"Terminal@ExecMethod: Delete returned 0x%x\n" , hr ));
        
        if ( SUCCEEDED (hr) && pOutParams != NULL )
        {                
            
            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
        }
        else
        {
            return WBEM_E_INVALID_METHOD_PARAMETERS;
        }                       
    }
    
    else
    {
        hr = WBEM_E_INVALID_METHOD;
    }  
    TRC2((TB,"Terminal@ExecMethod: Delete returned 0x%x\n" , hr ));  
	
    return hr;
}
//=--------------------


HRESULT CWin32_Terminal::LoadPropertyValues( CInstance *pInstance, ULONGLONG ulRequiredProperties, PWS pWS)
{
	    
    
    if( pInstance == NULL )
    { 
        TRC2((TB,"Terminal@LoadPropertyValues: invalid pointer" ));
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    if( ulRequiredProperties & BIT_TERMINALNAME)
    {                
        pInstance->SetCharSplat(m_szTerminalName, pWS->Name);
        
    } 
    
    if( ulRequiredProperties & BIT_FENABLETERMINAL)
    {                
        pInstance->SetDWORD(m_szEnableTerminal, pWS->fEnableWinstation);
        
    }  	
    
    return S_OK;
}


//------------------------------

CWin32_TSGeneralSetting::CWin32_TSGeneralSetting (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
Provider( lpwszName, lpwszNameSpace )
{
    if ( g_hInstance != NULL)
    {
        TRC2((TB, "CWin32_TSGeneralSetting_ctor"));
        
        _tcscpy(m_szTerminalProtocol, _T("TerminalProtocol"));

        _tcscpy(m_szTransport, _T("Transport"));

        _tcscpy(m_szComment, _T("Comment"));

        _tcscpy(m_szWindowsAuthentication, _T("WindowsAuthentication"));

        _tcscpy(m_szEncryptionLevel, _T("MinEncryptionLevel"));

        _tcscpy(m_szTerminalName, _T("TerminalName"));

        _tcscpy(m_szSetEncryptionLevel, _T("SetEncryptionLevel"));
               
    }

    RegGetMachinePolicy(&m_gpPolicy);
}
//=--------------------

CWin32_TSGeneralSetting::~CWin32_TSGeneralSetting ()
{
    
}



//=---------------------

BOOL CWin32_TSGeneralSetting::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
    DWORD dwSize = asArray.GetSize();
    
    for (DWORD x=0; x < dwSize; x++)
    {
        if (asArray[x].CompareNoCase(pszString) == 0)
        {
            return TRUE;
        }
    }
    
    return FALSE;
}

//=--------------------

HRESULT CWin32_TSGeneralSetting::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    LONG lSize;
    ULONGLONG ulRequiredProperties = 0;
    PWS pWS = NULL;
    CHString chTermName;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL )
    {
        ERR((TB,"TSGeneralSetting@GetObject: invalid pointer" ));
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    
    pInstance->GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }

    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szComment))
        ulRequiredProperties |= BIT_COMMENT;
    
    if (Query.IsPropertyRequired(m_szEncryptionLevel))
        ulRequiredProperties |= BIT_ENCRYPTIONLEVEL;
    
    if (Query.IsPropertyRequired(m_szTerminalProtocol))
        ulRequiredProperties |= BIT_TERMINALPROTOCOL;
    
    if (Query.IsPropertyRequired(m_szTransport))
        ulRequiredProperties |= BIT_TRANSPORT;
    
    if (Query.IsPropertyRequired(m_szWindowsAuthentication))
        ulRequiredProperties |= BIT_WINDOWSAUTHENTICATION;
    
    hr = StackObj.m_pCfgComp->GetWSInfo( (LPTSTR) (LPCTSTR) chTermName, &lSize, &pWS);
    
    TRC2((TB,"TSGeneralSetting@GetObject: returned 0x%x\n" , hr ));   
    
    
    if( SUCCEEDED( hr ) && (pWS != NULL) )
    {           
        hr = LoadPropertyValues(pInstance, ulRequiredProperties, pWS );

        if( !(SUCCEEDED( hr )) )
        {        
            hr = WBEM_E_INVALID_OBJECT;
        }
        
    }
    else
    {
        hr = WBEM_E_INVALID_OBJECT;
    }


    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
    }
    
    return hr ;
}

//=--------------------

/*****************************************************************************
*
*  FUNCTION    :    CWin32_TSGeneralSetting::EnumerateInstances
*
*  DESCRIPTION :    Returns all the instances of this class.
*
*  INPUTS      :    A pointer to the MethodContext for communication with WinMgmt.
*                   A long that contains the flags described in 
*                   IWbemServices::CreateInstanceEnumAsync.  Note that the following
*                   flags are handled by (and filtered out by) WinMgmt:
*                   WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY, 
*                   WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
*  RETURNS     :    WBEM_S_NO_ERROR if successful
*
*  COMMENTS    :    All instances on the machine are returned here and
*                   all properties that this class knows how to populate must 
*                   be filled in.  If there are no instances, return 
*                   WBEM_S_NO_ERROR.  
*****************************************************************************/


HRESULT CWin32_TSGeneralSetting::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
	
    HRESULT hr = WBEM_S_NO_ERROR;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {   
            CInstance* pInstance = CreateNewInstance(pMethodContext);
            
            if( pInstance == NULL)
            {
                ERR((TB,"TSGeneralSetting@EnumerateInstances: CreateNewInstance failed" ));
                
                hr = WBEM_E_OUT_OF_MEMORY;
                
                break;
            }
            TRC2((TB,"TSGeneralSetting@EnumerateInstances: GetWinstationList ret 0x%x\n" , hr )); 
            
            hr = LoadPropertyValues(pInstance, BIT_ALL_PROPERTIES, &pWS[ ulNum ] );
            
            if( SUCCEEDED( hr ) )
            {
                hr = pInstance->Commit();                               
            }
            
            pInstance->Release( );
        }        
    }
    

    
    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }

    return hr;
}


//=----------------------------------------------------------------------------------------------------------
HRESULT CWin32_TSGeneralSetting::ExecMethod ( const CInstance& Inst,
                                                    const BSTR bstrMethodName,
                                                    CInstance *pInParams,
                                                    CInstance *pOutParams,
                                                    long lFlags)
                                                    
{
    
    HRESULT hr = WBEM_E_NOT_FOUND;
    CHString chTermName;
    PUSERCONFIG pUser = NULL;
    LONG lSize;
    OSVERSIONINFOW OsVersionInfo;
    OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    Inst.GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength( ) > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if (chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    
    if( _wcsicmp(bstrMethodName, m_szSetEncryptionLevel ) == 0 )
    {
        // Sets the EncryptionLevel to one of Low, Medium or High. 
        // uint32 SetEncryptionLevel ([In] uint32 EncryptionLevel)
        
        DWORD dwData = 0 ;
        DWORD dwStatus = 0;
        ULONG  Size = 0;
        bool bRet;
        
        RegGetMachinePolicy(&m_gpPolicy);
        
        do
        {
            if( pInParams != NULL )
            {  
                
                bRet = pInParams->GetDWORD(m_szEncryptionLevel, dwData);
                
                TRC2((TB,"m_gpPolicy.fPolicyMinEncryptionLevel ret 0x%x\n", m_gpPolicy.fPolicyMinEncryptionLevel));                 
                
                if( m_gpPolicy.fPolicyMinEncryptionLevel == 0 )
                {
                    TRC2((TB,"Condition to update fPolicyMinEncryptionLevel satisfied"));     
                    
                    hr = StackObj.m_pCfgComp->GetUserConfig( (LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE);

                    if( SUCCEEDED( hr ) && pUser != NULL )
                    {                    
                        if( GetVersionEx( &OsVersionInfo))
                        {
                            if( OsVersionInfo.dwMajorVersion == 5 && OsVersionInfo.dwMinorVersion == 0)
                            {

                                if( dwData < 1 || dwData > 3)
                                {
                                    hr = WBEM_E_INVALID_PARAMETER;

                                    break;
                                }
                    
                                pUser->MinEncryptionLevel = dwData;
                    
                                hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR) (LPCTSTR) chTermName, lSize, pUser , &dwStatus );

                                if( SUCCEEDED( hr ))
                                {
                                    hr = StackObj.m_pCfgComp->ForceUpdate();
                                }
                                
                            }
                            else
                            {                               
                                if( dwData < 2 || dwData > 3)
                                {
                                    hr = WBEM_E_INVALID_PARAMETER;

                                    break;
                                }
                    
                                pUser->MinEncryptionLevel = dwData;
                    
                                hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR) (LPCTSTR) chTermName, lSize, pUser , &dwStatus );  
                                
                                if( SUCCEEDED( hr ))
                                {
                                    hr = StackObj.m_pCfgComp->ForceUpdate();
                                }
                            }
                        }
                    }
                }
                else
                {
                    hr = WBEM_E_INVALID_OPERATION;

                    break;
                }
                TRC2((TB,"TSGeneralSetting@ExecMethod: SetEncryptionLevel returned 0x%x\n" , hr));                     
                
            }            
            else
            {
                hr = WBEM_E_INVALID_METHOD_PARAMETERS;
            }  
            
        }while (0);

        if (pUser != NULL)
        {
            CoTaskMemFree (pUser);
        }        
    }
    else
    {
        hr = WBEM_E_INVALID_METHOD;
    }
	
    return hr;
}


//=--------------------


HRESULT CWin32_TSGeneralSetting::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{
    
    HRESULT hr = WBEM_E_NOT_FOUND;
    ULONGLONG ulRequiredProperties = 0;
    CHStringArray asNames;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    // Method 2
    Query.GetValuesForProp(m_szTerminalName, asNames);
    
    BOOL bGetAllInstances = asNames.GetSize() == 0;
    
    // Method 1
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szComment))
        ulRequiredProperties |= BIT_COMMENT;
    
    if (Query.IsPropertyRequired(m_szEncryptionLevel))
        ulRequiredProperties |= BIT_ENCRYPTIONLEVEL;
    
    if (Query.IsPropertyRequired(m_szTerminalProtocol))
        ulRequiredProperties |= BIT_TERMINALPROTOCOL;
    
    if (Query.IsPropertyRequired(m_szTransport))
        ulRequiredProperties |= BIT_TRANSPORT;
    
    if (Query.IsPropertyRequired(m_szWindowsAuthentication))
        ulRequiredProperties |= BIT_WINDOWSAUTHENTICATION;
    
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {
            if( bGetAllInstances || IsInList(asNames, pWS[ulNum].Name))
            {
                
                CInstance* pInstance = CreateNewInstance(pMethodContext);
                
                if( pInstance == NULL)
                {
                    ERR((TB,"TSGeneralSetting@ExecQuery: CreateNewInstance failed"));                    
                    
                    hr = WBEM_E_OUT_OF_MEMORY;
                    
                    break;
                }
                
                pInstance->SetCHString(m_szTerminalName, CHString(pWS[ulNum].Name));

                hr = LoadPropertyValues( pInstance, ulRequiredProperties, &pWS[ ulNum ] );
                
                if( SUCCEEDED( hr ) )
                {
                    hr = pInstance->Commit();
                }
                
                pInstance->Release();
            }
        }
    }
    
    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);        
    }
    
    return hr;
}




//=----------

HRESULT CWin32_TSGeneralSetting::LoadPropertyValues( CInstance *pInstance, ULONGLONG ulRequiredProperties, PWS pWS)
{
    HRESULT hr = WBEM_S_NO_ERROR;
    ULONG  ulTerminals = 0;
    ULONG  ulNumPd = 0; 
    ULONG ulSize = 0;
    LONG lSize = 0;
    PUSERCONFIG pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL )
    {
        ERR((TB,"TSGeneralSetting@LoadPropertyValues: invalid pointer"));
        
        return WBEM_E_ILLEGAL_NULL;       
    }
    
    if( ulRequiredProperties & BIT_TERMINALNAME)
    {
        pInstance->SetCharSplat(m_szTerminalName, pWS->Name);    
    }
    
    TRC2((TB,"TSGeneralSetting@LoadPropertyValues: GetTerminalName"));

    if( pWS != NULL )
    {
    
        if( ulRequiredProperties & BIT_TERMINALPROTOCOL )
        {      
            pInstance->SetWCHARSplat(m_szTerminalProtocol, pWS->wdName);
        
            TRC2((TB,"TSGeneralSetting@LoadPropertyValues: GetTerminalProtocol"));              
        }
    
        if( ulRequiredProperties & BIT_TRANSPORT)
        {
        
            pInstance->SetWCHARSplat(m_szTransport, pWS->pdName);
        
            TRC2((TB,"TSGeneralSetting@LoadPropertyValues: GetTransportTypes"));
        
        }
    
        if( ulRequiredProperties & BIT_COMMENT )
        {
        
            pInstance->SetWCHARSplat(m_szComment, pWS->Comment);
        
            TRC2((TB,"TSGeneralSetting@LoadPropertyValues: GetComment"));
        }
    
        
        hr = StackObj.m_pCfgComp->GetUserConfig(pWS->Name, &lSize, &pUser, TRUE);
        
        
        if(( ulRequiredProperties & BIT_WINDOWSAUTHENTICATION) && ( SUCCEEDED(hr) ) && pUser != NULL) 
        {      
            pInstance->SetDWORD(m_szWindowsAuthentication, pUser->fUseDefaultGina);
            
            TRC2((TB,"TSGeneralSetting@LoadPropertyValues: GetComment ret 0x%x\n" , hr));
        }
        
        
        if(( ulRequiredProperties & BIT_ENCRYPTIONLEVEL) && ( SUCCEEDED (hr) ) && pUser != NULL)
        {            
            RegGetMachinePolicy(&m_gpPolicy);

            if( m_gpPolicy.fPolicyMinEncryptionLevel != 0 )
            {
                pInstance->SetDWORD(m_szEncryptionLevel, m_gpPolicy.MinEncryptionLevel );
            }
            else
            {
                pInstance->SetDWORD(m_szEncryptionLevel, pUser->MinEncryptionLevel);
            }
            
            TRC2((TB,"TSGeneralSetting@LoadPropertyValues: GetEncryptionLevel ret 0x%x\n" , hr));        
        }
    }
    
	
    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);
    }
    
    return hr;
}
//=--------------------

HRESULT CWin32_TSGeneralSetting::PutInstance ( const CInstance &Instance, long lFlags)
{
	
    HRESULT hr= WBEM_S_NO_ERROR;
    DWORD dwData = 0;
    DWORD dwStatus = 0;
    ULONG  ulSize = 0; 
    LONG  lSize = 0;
    CHString chTermName;
    CHString chData;
    PUSERCONFIG pUser = NULL;   
    PWS  pWS = NULL;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    Instance.GetCHString(m_szTerminalName, chTermName);
    
    if(chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    hr = StackObj.m_pCfgComp->GetWSInfo((LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS);
    
    do
    {        
        if (SUCCEEDED ( hr ) && pWS != NULL)
        {
            hr = StackObj.m_pCfgComp->GetUserConfig( (LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE);
            
            if(SUCCEEDED (hr)  && pUser != NULL )
            {
                
                Instance.GetCHString(m_szTerminalProtocol, chData);
                
                if (chData.GetLength() > WINSTATIONNAME_LENGTH )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
                    
                    break;
                }
                
                wcscpy(pWS->wdName, (LPTSTR) (LPCTSTR) chData);
                
                Instance.GetCHString(m_szTransport, chData);
                
                if (chData.GetLength() > WINSTATIONNAME_LENGTH )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
                    
                    break;
                }
                
                wcscpy(pWS->pdName, (LPTSTR)(LPCTSTR) chData);
                
                Instance.GetCHString(m_szComment, chData);
                
                if ( chData.GetLength() > WINSTATIONCOMMENT_LENGTH )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
                    
                    break;
                }
                
                wcscpy(pWS->Comment, (LPTSTR) (LPCTSTR) chData);
                
                
                Instance.GetDWORD(m_szWindowsAuthentication, dwData);
                
                if (dwData != 0 && dwData != 1)
                {
                    hr = WBEM_E_INVALID_PARAMETER;
                    
                    break;
                }
                
                pUser->fUseDefaultGina = dwData;
                
                hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR) (LPCTSTR) chTermName, lSize, pUser , &dwStatus );
                
                TRC2((TB,"TSGeneralSetting@PutInstance: SetUserConfig ret 0x%x\n" , dwStatus));
                
                hr = StackObj.m_pCfgComp->UpDateWS( pWS, (DWORD)BIT_ALL_PROPERTIES , &dwStatus, TRUE );
                
                TRC2((TB,"TSGeneralSetting@PutInstance: UpdateWS ret 0x%x\n" , dwStatus));                                                

                if( SUCCEEDED( hr ))
                {
                    hr = StackObj.m_pCfgComp->ForceUpdate();
                }
            }
            else
            {                
                CHString sRelPath;
                
                Instance.GetCHString(L"__RelPath", sRelPath);
                CInstance *pErrorInstance = NULL;
                
             
                TRC2((TB,"TSGeneralSetting@PutInstance: ret 0x%x\n" , hr));
                
                if( SUCCEEDED( hr ) )
                {
                    if (pErrorInstance != NULL)
                    {
                        LoadString( g_hInstance , IDS_ERR_PUTTSGCONFIG, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                        pErrorInstance->SetWCHARSplat(L"Description", tchErrorMessage);
                        
                        LoadString( g_hInstance , IDS_ERR_PUTINSTANCE, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                        pErrorInstance->SetWCHARSplat(L"Operation", tchErrorMessage);
                        
                        pErrorInstance->SetCHString(L"ParameterInfo", sRelPath);
                        pErrorInstance->SetWCHARSplat(L"ProviderName", PROVIDER_NAME_Win32_WIN32_TSGENERALSETTING_Prov);
                        pErrorInstance->SetDWORD(L"StatusCode", WBEM_E_INVALID_PARAMETER);
                        
                        IWbemClassObject *pObj = pErrorInstance->GetClassObjectInterface();
                        
                        if (pObj != NULL)
                        {                        
                            MethodContext *pMethodContext = Instance.GetMethodContext();  
                            
                            if (pMethodContext != NULL)
                                pMethodContext->SetStatusObject(pObj);
                            
                            pObj->Release();
                        }
                        pErrorInstance->Release();
                    }
                    
                }
                TRC2((TB,"TSGeneralSetting@PutInstance: ret 0x%x\n" , hr));
            }
            
        } 
    }while (0);

    
    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);
    }    

    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }
    
    return hr;
}


//=-------------------------------------------------------
CWin32_TSLogonSetting::CWin32_TSLogonSetting (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
Provider( lpwszName, lpwszNameSpace )
{	

    if ( g_hInstance != NULL)
    {
        TRC2((TB, "CWin32_TSLogonSetting_ctor"));

        _tcscpy(m_szClientLogonInfoPolicy, _T("ClientLogonInfoPolicy"));

        _tcscpy(m_szPromptForPassword, _T("PromptForPassword"));

        _tcscpy(m_szUserName, _T("UserName"));

        _tcscpy(m_szDomain, _T("Domain"));

        _tcscpy(m_szPassword, _T("Password"));

        _tcscpy(m_szTerminalName, _T("TerminalName"));

        _tcscpy(m_szExplicitLogon, _T("ExplicitLogon"));

        _tcscpy(m_szSetPromptForPassword, _T("SetPromptForPassword"));
    }
    RegGetMachinePolicy(&m_gpPolicy);
}
//=--------------------

CWin32_TSLogonSetting::~CWin32_TSLogonSetting ()
{
    
}

//=------------

BOOL CWin32_TSLogonSetting::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
    DWORD dwSize = asArray.GetSize();
    
    for (DWORD x=0; x < dwSize; x++)
    {
        if (asArray[x].CompareNoCase(pszString) == 0)
        {
            return TRUE;
        }
    }
    
    return FALSE;
}


//=--------------------

HRESULT CWin32_TSLogonSetting::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{
    HRESULT hr= WBEM_E_NOT_FOUND;
    LONG  lSize ;
    ULONGLONG ulRequiredProperties = 0;
    PWS pWS = NULL;
    CHString chTermName;

    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL  )
    {
        TRC2((TB,"TSLogonSetting@GetObject: invalid pointer"));
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    pInstance->GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szClientLogonInfoPolicy))
        ulRequiredProperties |= BIT_CLIENTLOGONINFOPOLICY;
    
    if (Query.IsPropertyRequired(m_szDomain))
        ulRequiredProperties |= BIT_DOMAIN;
    
    if (Query.IsPropertyRequired(m_szPromptForPassword))
        ulRequiredProperties |= BIT_PROMPTFORPASSWORD;
    
    if (Query.IsPropertyRequired(m_szUserName))
        ulRequiredProperties |= BIT_USERNAME;
    
    if ( pInstance != NULL )
    {
        hr = StackObj.m_pCfgComp->GetWSInfo((LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS);

        if( SUCCEEDED( hr ) && pWS != NULL )
        {
            hr = LoadPropertyValues(pInstance, ulRequiredProperties, pWS );
        }                
    }
    	
    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }

    return hr;
}
//=--------------------
/*****************************************************************************
*
*  FUNCTION    :    CWin32_TSLogonSetting::EnumerateInstances
*
*  DESCRIPTION :    Returns all the instances of this class.
*
*  INPUTS      :    A pointer to the MethodContext for communication with WinMgmt.
*                   A long that contains the flags described in 
*                   IWbemServices::CreateInstanceEnumAsync.  Note that the following
*                   flags are handled by (and filtered out by) WinMgmt:
*                   WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY, 
*                   WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
*  RETURNS     :    WBEM_S_NO_ERROR if successful
*
*  COMMENTS    :    All instances on the machine are returned here and
*                   all properties that this class knows how to populate must 
*                   be filled in.  If there are no instances, return 
*                   WBEM_S_NO_ERROR.  
*****************************************************************************/

HRESULT CWin32_TSLogonSetting::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
	
    HRESULT hr = WBEM_S_NO_ERROR;
    ULONG  ulTerminals = 0;
    LONG ulNum = 0;
    ULONG  ulSize = 0; 
    PWS pWS = NULL;

	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {   
            CInstance* pInstance = CreateNewInstance(pMethodContext);
            
            if( pInstance == NULL)
            {
                ERR ((TB,"TSLogonSetting@EnumerateInstances: CreateNewInstance failed"));
                                
                hr = WBEM_E_OUT_OF_MEMORY;
                
                break;
            }
            TRC2((TB,"TSLogonSetting@EnumerateInstances: GetWinstationList ret 0x%x\n" , hr));

            hr = LoadPropertyValues(pInstance, BIT_ALL_PROPERTIES, &pWS[ulNum] );
            
            if( SUCCEEDED( hr ) )
            {
                hr = pInstance->Commit();
            }
            pInstance->Release();
        }        
    } 
    

    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }

    
    return hr;
}
//=--------------------
//=------@resume here 
HRESULT CWin32_TSLogonSetting::LoadPropertyValues( CInstance *pInstance, ULONGLONG ulRequiredProperties, PWS pWS)
{
	
    HRESULT hr = WBEM_S_NO_ERROR;
    ULONG  ulTerminals = 0;
    ULONG  ulSize = 0; 
    LONG lSize = 0;
    USERCONFIGW* pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL  )
    {
        ERR((TB,"TSLogonSetting@LoadPropertyValues: invalid pointer" ));
        
        return WBEM_E_ILLEGAL_NULL;       
    }
    
    if( ulRequiredProperties & BIT_TERMINALNAME)
    {
        pInstance->SetCharSplat(m_szTerminalName, pWS->Name);    
    }
    
    TRC2((TB,"TSLogonSetting@LoadPropertyValues: GetTerminalName" ));
    
    hr = StackObj.m_pCfgComp->GetUserConfig(pWS->Name, &lSize, &pUser, TRUE);
    
    TRC2((TB,"TSLogonSetting@LoadPropertyValues ret 0x%x\n" , hr ));
    
    if ( SUCCEEDED (hr) && pUser != NULL )
    {
        
        if( ulRequiredProperties & BIT_CLIENTLOGONINFOPOLICY)
        {         
            pInstance->SetDWORD(m_szClientLogonInfoPolicy, pUser->fInheritAutoLogon);
        }
        TRC2((TB,"TSLogonSetting@LoadPropertyValues: ClientLogonInfoPolicy" ));                  
        
        if( ulRequiredProperties & BIT_PROMPTFORPASSWORD)
        {
            RegGetMachinePolicy(&m_gpPolicy);

            if( m_gpPolicy.fPolicyPromptForPassword != 0 )
            {
                pInstance->SetDWORD(m_szPromptForPassword, m_gpPolicy.fPromptForPassword);
            }
            else
            {
                pInstance->SetDWORD(m_szPromptForPassword, pUser->fPromptForPassword);
            }
        }
        TRC2((TB,"TSLogonSetting@LoadPropertyValues: PromptForPassword" ));         
        
        if( ulRequiredProperties & BIT_USERNAME)
        {                          
            pInstance->SetWCHARSplat(m_szUserName, pUser->UserName);
        }
        TRC2((TB,"TSLogonSetting@LoadPropertyValues: UserName" ));                
        
        if( ulRequiredProperties & BIT_DOMAIN)
        {                          
            pInstance->SetWCHARSplat(m_szDomain, pUser->Domain);
        }
        TRC2((TB,"TSLogonSetting@LoadPropertyValues: Domain" ));        
    } 

	
    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);
        
    }

    return hr;
}

//=--------------------

HRESULT CWin32_TSLogonSetting::PutInstance ( const CInstance &Instance, long lFlags)
{

    HRESULT hr= WBEM_S_NO_ERROR;
    DWORD dwData = 0;
    CHString chTermName;
    DWORD dwStatus = 0;
    LONG lSize;
    PUSERCONFIG pUser = NULL;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    
    Instance.GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    
    hr = StackObj.m_pCfgComp->GetUserConfig((LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE);
    
    do
    {
        
        if( SUCCEEDED( hr ) && pUser != NULL )
        {
            Instance.GetDWORD(m_szClientLogonInfoPolicy, dwData);
            
            if( dwData != 0 && dwData != 1 )
            {
                hr = WBEM_E_INVALID_PARAMETER;
                
                break;
            }
            
            pUser->fInheritAutoLogon = dwData;
            
            hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR)(LPCTSTR) chTermName, lSize, pUser , &dwStatus ); 
            
            if( SUCCEEDED( hr ) )
            {
                hr = StackObj.m_pCfgComp->ForceUpdate();
            }
        }        
        else
        {
            TRC2((TB,"TSLogonSetting@PutInstance ret 0x%x\n" , hr ));             
            
            CHString sRelPath;
            
            Instance.GetCHString(L"__RelPath", sRelPath);
            CInstance *pErrorInstance = NULL;
            
            hr = CWbemProviderGlue::GetInstanceByPath(pErrorClass, &pErrorInstance );
            
            if( SUCCEEDED( hr ))
            {
                TRC2((TB,"TSLogonSetting@PutInstance: GetInstanceByPath ret 0x%x\n" , hr ));

                if( pErrorInstance != NULL )
                {
                    
                    LoadString( g_hInstance , IDS_ERR_PUTTSLCONFIG, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                    pErrorInstance->SetWCHARSplat(L"Description", tchErrorMessage);
                    
                    LoadString( g_hInstance , IDS_ERR_PUTINSTANCE, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                    pErrorInstance->SetWCHARSplat(L"Operation", tchErrorMessage);
                    
                    pErrorInstance->SetCHString(L"ParameterInfo", sRelPath);
                    pErrorInstance->SetWCHARSplat(L"ProviderName", PROVIDER_NAME_Win32_WIN32_TSLOGONSETTING_Prov);
                    pErrorInstance->SetDWORD(L"StatusCode", WBEM_E_INVALID_PARAMETER);
                    
                    IWbemClassObject *pObj = pErrorInstance->GetClassObjectInterface();
                    if( pObj != NULL )
                    {
                        
                        MethodContext *pMethodContext = Instance.GetMethodContext();  
                        
                        
                        if( pMethodContext != NULL )
                        {
                            pMethodContext->SetStatusObject(pObj);
                        }
                        
                        pObj->Release();
                    }
                    pErrorInstance->Release();
                }
                
            }            
        }
    }while (0);

	
    if( pUser != NULL )
    {
        CoTaskMemFree(pUser);        
    }
    
    return hr;
}
//=--------------------

HRESULT CWin32_TSLogonSetting::ExecMethod ( const CInstance& Inst,
                                                  const BSTR bstrMethodName,
                                                  CInstance *pInParams,
                                                  CInstance *pOutParams,
                                                  long lFlags)
                                                  
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    PUSERCONFIG pUser = NULL;

	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
	
    if( pInParams == NULL)
    {
        return WBEM_E_INVALID_METHOD_PARAMETERS;
    }
            
    
    // Sets the properties UserName, Password and Domain which specify 
    // the credentials explicitly to be used for authentication.
                              
    //  uint32 ExplicitLogon([In] string UserName, [In] string Password, [In] string Domain)
    
    if (_wcsicmp(bstrMethodName, m_szExplicitLogon) == 0)
    {
        
        DWORD dwData = 0;
        DWORD dwStatus = 0;
        CHString chData;
        CHString chTermName;
        LONG lSize;
        
        
        Inst.GetCHString(m_szTerminalName, chTermName);
        
        if( chTermName.GetLength( ) > WINSTATIONNAME_LENGTH )
        {
            return WBEM_E_VALUE_OUT_OF_RANGE;
        }
        
        if( chTermName.IsEmpty() != 0)
        {
            return WBEM_E_ILLEGAL_NULL;
        }
        
    
        hr = StackObj.m_pCfgComp->GetUserConfig( (LPTSTR) (LPCTSTR) chTermName , &lSize, &pUser, TRUE);
        
        do
        {
            if( SUCCEEDED( hr ) && pUser != NULL )
            {
                dwData = pUser->fInheritAutoLogon;
                
                if( dwData == 0 )
                {   
                    chData.Empty();

                    pInParams->GetCHString( m_szUserName, chData );
                    
                    if( chData.GetLength() > USERNAME_LENGTH )
                    {
                        hr = WBEM_E_VALUE_OUT_OF_RANGE;
                        
                        break;
                    }

                    wcscpy(pUser->UserName, (LPTSTR) (LPCTSTR) chData);                        

                    chData.Empty();
                    
                    pInParams->GetCHString( m_szDomain, chData );
                    
                    if( chData.GetLength() > APPSERVERNAME_LENGTH )
                    {
                        hr = WBEM_E_VALUE_OUT_OF_RANGE;
                        
                        break;
                    }

                    wcscpy(pUser->Domain, (LPTSTR) (LPCTSTR) chData);                        

                    chData.Empty();
                    
                    pInParams->GetCHString( m_szPassword, chData );
                    
                    if( chData.GetLength() > PASSWORD_LENGTH )
                    {
                        hr = WBEM_E_VALUE_OUT_OF_RANGE;
                        
                        break;
                    }
                    
                    wcscpy( pUser->Password, (LPTSTR) (LPCTSTR) chData );                        
                    
                    hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR) (LPCTSTR) chTermName, lSize, pUser , &dwStatus );
                    
                    if( SUCCEEDED (hr) && pOutParams != NULL )
                    {
                        StackObj.m_pCfgComp->ForceUpdate();

                        pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                        
                        TRC2((TB,"TSLogonSetting@ExecMethod: ExplicitLogon ret 0x%x\n" , hr ));
                    } 
                }
                else
                {
                    hr = WBEM_E_INVALID_OPERATION;

                    break;                        
                }
                
            }
        }while(0);
        
    }
    
    else if( _wcsicmp( bstrMethodName, m_szSetPromptForPassword ) == 0 )
    {
        
        DWORD dwData = 0;
        DWORD dwStatus = 0;
        CHString chTermName;
        LONG lSize;
        bool bRet;
        
        
        Inst.GetCHString(m_szTerminalName, chTermName);
        
        if( chTermName.GetLength( ) > WINSTATIONNAME_LENGTH )
        {
            return WBEM_E_VALUE_OUT_OF_RANGE;
        }
        
        if( chTermName.IsEmpty() != 0)
        {
            return WBEM_E_ILLEGAL_NULL;
        }
        
        hr = StackObj.m_pCfgComp->GetUserConfig( (LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE);
        
        RegGetMachinePolicy(&m_gpPolicy);
        
        do
        {
            if( SUCCEEDED (hr) && pInParams != NULL && pUser != NULL )
            {      
                bRet = pInParams->GetDWORD( m_szPromptForPassword, dwData );
                
                if( ( m_gpPolicy.fPolicyPromptForPassword == 0) && bRet != 0 )
                {                    
                    if( dwData != 0 && dwData != 1 )
                    {
                        hr = WBEM_E_INVALID_METHOD_PARAMETERS;
                        
                        break;
                    }
                    
                    pUser->fPromptForPassword = dwData;
                    
                    hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR)(LPCTSTR) chTermName, lSize, pUser , &dwStatus );
                    
                    if ( SUCCEEDED (hr) && pOutParams != NULL )
                    {
                        StackObj.m_pCfgComp->ForceUpdate();

                        pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                        
                        TRC2((TB,"TSLogonSetting@ExecMethod: PromptForPassword ret 0x%x\n" , hr ));
                    } 
                }
                else
                {
                    hr = WBEM_E_INVALID_OPERATION;

                    break;
                }
                
            }
        } while (0);
        
    }
    
    else
    {
        hr = WBEM_E_INVALID_METHOD;
    }
    
    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);
        
    }

    return hr;
}

//=----------------------------


HRESULT CWin32_TSLogonSetting::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    ULONGLONG ulRequiredProperties = 0;
    CHStringArray asNames;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;

	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
	
    
    // Method 2
    Query.GetValuesForProp(m_szTerminalName, asNames);
    
    BOOL bGetAllInstances = asNames.GetSize() == 0;
    
    // Method 1
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szClientLogonInfoPolicy))
        ulRequiredProperties |= BIT_CLIENTLOGONINFOPOLICY;
    
    if (Query.IsPropertyRequired(m_szDomain))
        ulRequiredProperties |= BIT_DOMAIN;
        
    if (Query.IsPropertyRequired(m_szPromptForPassword))
        ulRequiredProperties |= BIT_PROMPTFORPASSWORD;
    
    if (Query.IsPropertyRequired(m_szUserName))
        ulRequiredProperties |= BIT_USERNAME;
    
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++ )
        {  
            
            
            // Method 2 - Check to see if the query CAN be processed by 'name', if so,
            // only return those names.
            if( bGetAllInstances || IsInList(asNames, pWS[ulNum].Name) )
            {
                
                CInstance* pInstance = CreateNewInstance(pMethodContext);
                
                if( pInstance == NULL )
                {
                    ERR( (TB,"TSLogonSetting@ExecQuery: CreateNewInstance failed" ) );
                    
                    hr = WBEM_E_OUT_OF_MEMORY;
                    
                    break;
                }
                
                pInstance->SetCHString( m_szTerminalName, CHString(pWS[ulNum].Name) );

                hr = LoadPropertyValues( pInstance, ulRequiredProperties, &pWS[ ulNum ] );
                
                if( SUCCEEDED( hr ) )
                {
                    hr = pInstance->Commit();
                }
                
                pInstance->Release();
            }
        }
    }
    
    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }  	
    
    return hr;
    
}




//=--------------------Win32_TSSessionSettingsConfig------------------------



CWin32_TSSessionSetting::CWin32_TSSessionSetting (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
Provider( lpwszName, lpwszNameSpace )
{
    if ( g_hInstance != NULL)
    {
        TRC2((TB, "CWin32_TSSessionSetting_ctor"));

        _tcscpy(m_szTimeLimitPolicy, _T("TimeLimitPolicy"));

        _tcscpy(m_szActiveSessionLimit, _T("ActiveSessionLimit"));

        _tcscpy(m_szDisconnectedSessionLimit, _T("DisconnectedSessionLimit"));

        _tcscpy(m_szIdleSessionLimit, _T("IdleSessionLimit"));

        _tcscpy(m_szBrokenConnectionPolicy, _T("BrokenConnectionPolicy"));

        _tcscpy(m_szReconnectionPolicy, _T("ReconnectionPolicy"));

        _tcscpy(m_szBrokenConnectionAction, _T("BrokenConnectionAction"));

        _tcscpy(m_szSessionLimitType, _T("SessionLimitType"));

        _tcscpy(m_szValueLimit, _T("ValueLimit"));

        _tcscpy(m_szTerminalName, _T("TerminalName"));

        _tcscpy(m_szTimeLimit, _T("TimeLimit"));

        _tcscpy(m_szBrokenConnection, _T("BrokenConnection"));

               
    }
}
//=--------------------
CWin32_TSSessionSetting::~CWin32_TSSessionSetting ()
{
    
}

//=-----------------

BOOL CWin32_TSSessionSetting::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
    DWORD dwSize = asArray.GetSize();
    
    for (DWORD x=0; x < dwSize; x++)
    {
        if (asArray[x].CompareNoCase(pszString) == 0)
        {
            return TRUE;
        }
    }
    
    return FALSE;
}

//=--------------------

HRESULT CWin32_TSSessionSetting::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    ULONGLONG ulRequiredProperties = 0;
    DWORD dwData = 0;
    CHString chTermName; 
    LONG  lSize ;
 //   PUSERCONFIG pUser = NULL;
    PWS pWS = NULL;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL  )
    {
        ERR((TB,"TSSessionSetting@GetObject: invalid pointer" ));
        
        return WBEM_E_ILLEGAL_NULL;       
    }
    
    pInstance->GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if(chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }


    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;

    if (Query.IsPropertyRequired(m_szTimeLimitPolicy))
        ulRequiredProperties |= BIT_ACTIVESESSIONPOLICY;

    if (Query.IsPropertyRequired(m_szBrokenConnectionPolicy))
        ulRequiredProperties |= BIT_BROKENCONNECTIONPOLICY;

    if (Query.IsPropertyRequired(m_szActiveSessionLimit))
        ulRequiredProperties |= BIT_ACTIVESESSIONLIMIT;
    
    if (Query.IsPropertyRequired(m_szBrokenConnectionAction))
        ulRequiredProperties |= BIT_BROKENCONNECTIONACTION;
    
    if (Query.IsPropertyRequired(m_szDisconnectedSessionLimit))
        ulRequiredProperties |= BIT_DISCONNECTEDSESSIONLIMIT;
    
    if (Query.IsPropertyRequired(m_szIdleSessionLimit))
        ulRequiredProperties |= BIT_IDLESESSIONLIMIT;
    
    if (Query.IsPropertyRequired(m_szReconnectionPolicy))
        ulRequiredProperties |= BIT_RECONNECTIONPOLICY;

    hr = StackObj.m_pCfgComp->GetWSInfo((LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS);
    
    if ( pInstance != NULL && SUCCEEDED( hr ) && pWS != NULL )
    {
        hr = LoadPropertyValues(pInstance, ulRequiredProperties, pWS );
    }
    
    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }
    	
    return hr;
}

//=--------------------
/*****************************************************************************
*
*  FUNCTION    :    CWin32_TSSessionSetting::EnumerateInstances
*
*  DESCRIPTION :    Returns all the instances of this class.
*
*  INPUTS      :    A pointer to the MethodContext for communication with WinMgmt.
*                   A long that contains the flags described in 
*                   IWbemServices::CreateInstanceEnumAsync.  Note that the following
*                   flags are handled by (and filtered out by) WinMgmt:
*                   WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY, 
*                   WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
*  RETURNS     :    WBEM_S_NO_ERROR if successful
*
*  COMMENTS    :    All instances on the machine are returned here and
*                   all properties that this class knows how to populate must 
*                   be filled in.  If there are no instances, return 
*                   WBEM_S_NO_ERROR.  
*****************************************************************************/

HRESULT CWin32_TSSessionSetting::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{	
    HRESULT hr = WBEM_S_NO_ERROR;
    ULONG  ulTerminals = 0;
    ULONG ulNum = 0;
    ULONG  ulSize = 0; 
    LONG lSize = 0;
    PWS  pWS = NULL;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {   
            CInstance* pInstance = CreateNewInstance(pMethodContext);
            
            if( pInstance == NULL)
            {
                ERR((TB,"TSSessionSetting@EnumerateInstances: CreateNewInstance failed" ));
                                
                hr = WBEM_E_OUT_OF_MEMORY;
                
                break;
            }
            TRC2((TB,"TSSessionSetting@EnumerateInstances: GetWinstationList ret 0x%x\n" , hr  ));

            hr = LoadPropertyValues(pInstance, BIT_ALL_PROP, &pWS[ulNum] );

            if( SUCCEEDED( hr ) )
            {
                hr = pInstance->Commit();
                                
            }
            
            pInstance->Release( );            
        }
        
    }  
    

    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }

    return hr;
}

//=--------------------

HRESULT CWin32_TSSessionSetting::LoadPropertyValues( CInstance *pInstance, ULONGLONG ulRequiredProperties, PWS pWS)
{
	
    HRESULT hr = WBEM_S_NO_ERROR;
    LONG lSize ;
    DWORD dwData = 0;
    USERCONFIGW* pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL ) 
    {
        ERR((TB,"TSSessionSetting@LoadPropertyValues: invalid pointer"  ));
        
        return WBEM_E_ILLEGAL_NULL;       
    }
    
    
    if ( pInstance != NULL && pWS != NULL )
    {
        if( ulRequiredProperties & BIT_TERMINALNAME)
        {
            pInstance->SetCharSplat(m_szTerminalName, pWS->Name);        
        }
        
        hr = StackObj.m_pCfgComp->GetUserConfig(pWS->Name, &lSize, &pUser, TRUE);
        
        TRC2((TB,"TSSessionSetting@LoadPropertyValues: GetUserConfig ret 0x%x\n" , hr   ));
        
        if ( SUCCEEDED (hr) && pUser != NULL )
        {
            
            if( ulRequiredProperties & BIT_ACTIVESESSIONPOLICY)
            {                
                pInstance->SetDWORD(m_szTimeLimitPolicy, pUser->fInheritMaxSessionTime);                
            }
            TRC2((TB,"TSSessionSetting@LoadPropertyValues: TimeLimitPolicy"   ));
            
            
            if( ulRequiredProperties & BIT_ACTIVESESSIONLIMIT)
            {                          
                pInstance->SetDWORD(m_szActiveSessionLimit, pUser->MaxConnectionTime);
                
            }
            TRC2((TB,"TSSessionSetting@LoadPropertyValues: MaxConnectionTime"   ));          
            
            if( ulRequiredProperties & BIT_DISCONNECTEDSESSIONLIMIT)
            {                          
                pInstance->SetDWORD(m_szDisconnectedSessionLimit, pUser->MaxDisconnectionTime);
                
            }
            TRC2((TB,"TSSessionSetting@LoadPropertyValues: MaxDisconnectionTime" ));      
            
            if( ulRequiredProperties & BIT_IDLESESSIONLIMIT)
            {                          
                pInstance->SetDWORD(m_szIdleSessionLimit, pUser->MaxIdleTime);
                
            }
            TRC2((TB,"TSSessionSetting@LoadPropertyValues: MaxIdleTime" ));        
            
            if( ulRequiredProperties &  BIT_BROKENCONNECTIONPOLICY)
            {                          
                pInstance->SetDWORD(m_szBrokenConnectionPolicy, pUser->fInheritResetBroken);
                
            }
            TRC2((TB,"TSSessionSetting@LoadPropertyValues: BrokenConnectionPolicy" ));         
            
            if( ulRequiredProperties & BIT_BROKENCONNECTIONACTION)
            {                          
                pInstance->SetDWORD(m_szBrokenConnectionAction, pUser->fResetBroken);
                
            }
            TRC2((TB,"TSSessionSetting@LoadPropertyValues: BrokenConnectionAction" ));         
            
            if( ulRequiredProperties & BIT_RECONNECTIONPOLICY)
            {                          
                pInstance->SetDWORD(m_szReconnectionPolicy, pUser->fInheritReconnectSame);
                
            }
            TRC2((TB,"TSSessionSetting@LoadPropertyValues: ReconnectionPolicy" )); 
                       
        }
        
    }

    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);
        
    }

    return hr;
    
}

//=--------------------

HRESULT CWin32_TSSessionSetting::PutInstance ( const CInstance &Instance, long lFlags)
{
	
    HRESULT hr= WBEM_S_NO_ERROR;
    CHString chTermName ;
    DWORD dwData = 0;
    DWORD dwStatus = 0;
    LONG lSize;
    USERCONFIGW* pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    
    Instance.GetCHString(m_szTerminalName, chTermName);
    
    if(chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    hr = StackObj.m_pCfgComp->GetUserConfig((LPTSTR) (LPCTSTR) chTermName, &lSize, &pUser, TRUE);
    
    do
    {
        if( SUCCEEDED( hr ) && pUser != NULL )
        {
            Instance.GetDWORD(m_szTimeLimitPolicy, dwData);
            
            if (dwData != 0 && dwData != 1 )
            {
                hr = WBEM_E_INVALID_PARAMETER;
                
                break;
            }
            
            pUser->fInheritMaxSessionTime = dwData;
            pUser->fInheritMaxDisconnectionTime = dwData;
            pUser->fInheritMaxIdleTime = dwData;
            
            Instance.GetDWORD( m_szBrokenConnectionPolicy, dwData );
            
            if( dwData != 0 && dwData != 1 )
            {
                hr = WBEM_E_INVALID_PARAMETER;
                
                break;
            }
            
            pUser->fInheritResetBroken = dwData;
            
            Instance.GetDWORD( m_szReconnectionPolicy, dwData );
            
            if (dwData != 0 && dwData != 1 )
            {
                hr = WBEM_E_INVALID_PARAMETER;
                
                break;
            }
            
            pUser->fInheritReconnectSame = dwData;
            
            hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR) (LPCTSTR) chTermName, lSize, pUser , &dwStatus );
            
            TRC2((TB,"TSSessionSetting@PutInstance: SetUserConfig ret 0x%x\n" , dwStatus ));  
            
            if( SUCCEEDED( hr ))
            {
                hr = StackObj.m_pCfgComp->ForceUpdate();
            }
        }
        
        else
        {
            ERR((TB,"TSSessionSetting@PutInstance: Failed" ));
            
            CHString sRelPath;
            
            Instance.GetCHString(L"__RelPath", sRelPath);
            CInstance *pErrorInstance = NULL;
            
            hr = CWbemProviderGlue::GetInstanceByPath(pErrorClass, &pErrorInstance );
            
            if( SUCCEEDED( hr ) )
            {
                TRC2((TB,"TSSessionSetting@PutInstance: GetInstanceByPath succeeded" ));

                if (pErrorInstance != NULL)
                {
                    
                    LoadString( g_hInstance , IDS_ERR_PUTTSSCONFIG, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                    pErrorInstance->SetWCHARSplat(L"Description", tchErrorMessage);
                    
                    LoadString( g_hInstance , IDS_ERR_PUTINSTANCE, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                    pErrorInstance->SetWCHARSplat(L"Operation", tchErrorMessage);
                    
                    pErrorInstance->SetCHString(L"ParameterInfo", sRelPath);
                    pErrorInstance->SetWCHARSplat(L"ProviderName", PROVIDER_NAME_Win32_WIN32_TSSESSIONSETTING_Prov);
                    pErrorInstance->SetDWORD(L"StatusCode", WBEM_E_INVALID_PARAMETER);
                    
                    IWbemClassObject *pObj = pErrorInstance->GetClassObjectInterface();
                    if (pObj != NULL)
                    {
                        
                        MethodContext *pMethodContext = Instance.GetMethodContext();  
                        
                        if (pMethodContext != NULL)
                        {
                            pMethodContext->SetStatusObject(pObj);
                        }
                        
                        pObj->Release();
                    }
                    pErrorInstance->Release();
                }
                
            }
            TRC2((TB,"TSSessionSetting@PutInstance: GetInstanceByPath ret 0x%x\n" , hr ));     
        }
    }while (0);

    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);        
    }
    	
    return hr;
}

//=--------------------

HRESULT CWin32_TSSessionSetting::ExecMethod ( const CInstance& Inst,
                                                    const BSTR bstrMethodName,
                                                    CInstance *pInParams,
                                                    CInstance *pOutParams,
                                                    long lFlags)
                                                    
{
	
    HRESULT hr= WBEM_E_NOT_FOUND;
    CHString chTermName;
    PUSERCONFIG pUser = NULL;
    LONG lSize;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}    
    
    Inst.GetCHString( m_szTerminalName, chTermName );
    
    if( chTermName.GetLength( ) > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty( ) != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    hr = StackObj.m_pCfgComp->GetUserConfig((LPTSTR) (LPCTSTR) chTermName, &lSize, &pUser, TRUE);
    
    do
    {
        if( SUCCEEDED (hr) && pUser != NULL && pInParams != NULL )
        {
            
            // SessionLimitType is an enumeration of the properties:
            // ActiveSessionLimit, DisconnectedSessionLimit and IdleSessionLimit
            // which specify the Maximum allowed time for Active, Disconnected Session 
            // Idle session limits. Value specifies the time in minutes.
                              
            // uint32 TimeLimit([In] uint32 SessionLimitType, [In] uint32 ValueLimit)
            
            if( _wcsicmp( bstrMethodName, m_szTimeLimit ) == 0 )
            {
                
                CHString chData;
                DWORD dwData = 0;
                DWORD dwStatus = 0;
                DWORD dwSessionType; 
                bool bRet;
                
                chData.Empty();
                
                pInParams->GetCHString( m_szSessionLimitType, chData );
                
                if( chData.IsEmpty() != 0 )
                {
                    hr = WBEM_E_INVALID_METHOD_PARAMETERS;

                    break;
                }
                
                if( chData.CompareNoCase( m_szActiveSessionLimit ) == 0 )
                {
                    dwData = pUser->fInheritMaxSessionTime;

                    if( dwData == 0 )
                    {
                        bRet = pInParams->GetDWORD(m_szValueLimit, dwData);
                        
                        if ( !bRet )
                        {
                            hr = WBEM_E_INVALID_PARAMETER;
                            
                            break;
                        }
                        
                        pUser->MaxConnectionTime = dwData;
                        
                        hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR) (LPCTSTR) chTermName, lSize, pUser , &dwStatus );
                        
                        if( SUCCEEDED( hr ) && pOutParams != NULL )
                        {
                            hr = StackObj.m_pCfgComp->ForceUpdate();

                            pOutParams->SetDWORD( L"ReturnValue", WBEM_S_NO_ERROR );
                            
                            TRC2((TB,"TSSessionSetting@ExecMethod:  TimeLimit - ActiveSessionLimit ret 0x%x\n" , hr  ));         
                        } 
                    }
                    else
                    {
                        hr = WBEM_E_INVALID_OPERATION;
                        
                        break;                        
                    }
                }
                else if( chData.CompareNoCase( m_szDisconnectedSessionLimit ) == 0 )
                {
                    dwData = pUser->fInheritMaxSessionTime;
                    
                    if( dwData == 0 )
                    {
                        bRet = pInParams->GetDWORD(m_szValueLimit, dwData);
                        
                        if ( !bRet )
                        {
                            hr = WBEM_E_INVALID_PARAMETER;
                            
                            break;
                        }
                        
                        pUser->MaxDisconnectionTime = dwData;
                        
                        hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR) (LPCTSTR) chTermName, lSize, pUser , &dwStatus );
                        
                        if( SUCCEEDED( hr ) && pOutParams != NULL )
                        {
                            StackObj.m_pCfgComp->ForceUpdate();

                            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                            
                            TRC2((TB,"TSSessionSetting@ExecMethod:  TimeLimit - DisconnectedSessionLimit ret 0x%x\n" , hr  ));      
                        } 
                    }
                    else
                    {
                        hr = WBEM_E_INVALID_OPERATION;
                        
                        break;
                        
                    }
                }
                else if( chData.CompareNoCase(m_szIdleSessionLimit) == 0)
                {
                    dwData = pUser->fInheritMaxSessionTime;

                    if( dwData == 0 )
                    {
                        bRet = pInParams->GetDWORD(m_szValueLimit, dwData);
                        

                        if ( !bRet )
                        {
                            hr = WBEM_E_INVALID_PARAMETER;
                            
                            break;
                        }
                        
                        pUser->MaxIdleTime = dwData;
                        
                        hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR) (LPCTSTR) chTermName, lSize, pUser , &dwStatus );
                        
                        if( SUCCEEDED( hr ) && pOutParams != NULL )
                        {
                            StackObj.m_pCfgComp->ForceUpdate();

                            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                            
                            TRC2((TB,"TSSessionSetting@ExecMethod:  TimeLimit - IdleSessionLimit ret 0x%x\n" , hr  ));    
                        } 
                    }
                    else
                    {
                        hr = WBEM_E_INVALID_OPERATION;
                        
                        break;
                        
                    }
                }
                else 
                {
                    hr = WBEM_E_INVALID_METHOD_PARAMETERS;
                    
                    break;
                }                     
            }
            
            else if( _wcsicmp( bstrMethodName, m_szBrokenConnection ) == 0 )
            {
                
                DWORD dwData = 0;
                DWORD dwStatus = 0; 
                bool bRet;
                
                dwData = pUser->fInheritResetBroken;

                if( dwData == 0 )
                {
                    bRet = pInParams->GetDWORD(m_szBrokenConnectionAction, dwData);
                    

                    if ( !bRet )
                    {
                        hr = WBEM_E_INVALID_PARAMETER;
                        
                        break;
                    }
                    
                    pUser->fResetBroken = dwData;
                    
                    hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR) (LPCTSTR) chTermName, lSize, pUser , &dwStatus );
                    
                    if( SUCCEEDED( hr ) && pOutParams != NULL )
                    {
                        StackObj.m_pCfgComp->ForceUpdate();

                        pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                        
                        TRC2((TB,"TSSessionSetting@ExecMethod:  BrokenConnection ret 0x%x\n" , hr  ));
                    } 
                    
                }
                else
                {
                    
                    hr = WBEM_E_INVALID_OPERATION;
                    
                    break;
                    
                }                
            }                         
        }
        
    } while( 0 );


    if( pUser != NULL )
    {
        CoTaskMemFree(pUser);
    }
	
    return hr;
}


//=--------------------------

HRESULT CWin32_TSSessionSetting::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    ULONGLONG ulRequiredProperties = 0;
    CHStringArray asNames;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;	

	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    // Method 2
    Query.GetValuesForProp(m_szTerminalName, asNames);
    
    BOOL bGetAllInstances = asNames.GetSize() == 0;
    
    // Method 1
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;

	if (Query.IsPropertyRequired(m_szTimeLimitPolicy))
        ulRequiredProperties |= BIT_ACTIVESESSIONPOLICY;

    if (Query.IsPropertyRequired(m_szBrokenConnectionPolicy))
        ulRequiredProperties |= BIT_BROKENCONNECTIONPOLICY;
    
    if (Query.IsPropertyRequired(m_szActiveSessionLimit))
        ulRequiredProperties |= BIT_ACTIVESESSIONLIMIT;
    
    if (Query.IsPropertyRequired(m_szBrokenConnectionAction))
        ulRequiredProperties |= BIT_BROKENCONNECTIONACTION;
    
    if (Query.IsPropertyRequired(m_szDisconnectedSessionLimit))
        ulRequiredProperties |= BIT_DISCONNECTEDSESSIONLIMIT;
    
    if (Query.IsPropertyRequired(m_szIdleSessionLimit))
        ulRequiredProperties |= BIT_IDLESESSIONLIMIT;
    
    if (Query.IsPropertyRequired(m_szReconnectionPolicy))
        ulRequiredProperties |= BIT_RECONNECTIONPOLICY;
   
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {  
            
            // Method 2
            if (bGetAllInstances || IsInList(asNames, pWS[ulNum].Name))
            {
                
                CInstance* pInstance = CreateNewInstance(pMethodContext);
                
                if( pInstance == NULL)
                {
                    TRC2((TB,"TSSessionSetting@ExecQuery: CreateNewInstance failed" ));
                    
                    hr = WBEM_E_OUT_OF_MEMORY;
                    
                    break;
                }
                
                pInstance->SetCHString(m_szTerminalName, CHString(pWS[ulNum].Name));

                hr = LoadPropertyValues( pInstance, ulRequiredProperties, &pWS[ ulNum ] );
                
                if( SUCCEEDED( hr ) )
                {
                    hr = pInstance->Commit();
                }
                
                pInstance->Release();
            }
        }
    }
    	
    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);
    }
    	
    return hr;
    
}

//=----------------------Win32_TSEnvironmentSetting---------------------


CWin32_TSEnvironmentSetting::CWin32_TSEnvironmentSetting (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
Provider( lpwszName, lpwszNameSpace )
{
    if ( g_hInstance != NULL)
    {
        TRC2((TB, "CWin32_TSEnvironmentSetting_ctor"));

        _tcscpy(m_szInitialProgramPolicy, _T("InitialProgramPolicy"));

        _tcscpy(m_szInitialProgramPath, _T("InitialProgramPath"));

        _tcscpy(m_szStartIn, _T("StartIn"));

        _tcscpy(m_szClientWallPaper, _T("ClientWallPaper"));

        _tcscpy(m_szTerminalName, _T("TerminalName"));

        _tcscpy(m_szInitialProgram, _T("InitialProgram"));
               
    }
}
//=--------------------

CWin32_TSEnvironmentSetting::~CWin32_TSEnvironmentSetting ()
{
}

//=---------------


BOOL CWin32_TSEnvironmentSetting::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
    DWORD dwSize = asArray.GetSize();
    
    for (DWORD x=0; x < dwSize; x++)
    {
        if (asArray[x].CompareNoCase(pszString) == 0)
        {
            return TRUE;
        }
    }
    
    return FALSE;
}


//=--------------------

HRESULT CWin32_TSEnvironmentSetting::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    DWORD dwData = 0;
    CHString chTermName;
    LONG  lSize ;
    ULONGLONG ulRequiredProperties = 0;
    PWS pWS = NULL;
  //  PUSERCONFIG pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if(  pInstance == NULL )
    {
        ERR((TB,"TSEnvironmentSetting@GetObject: invalid pointer" ));
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    pInstance->GetCHString(m_szTerminalName, chTermName);
    
    if(chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if (chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }

    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szClientWallPaper))
        ulRequiredProperties |= BIT_CLIENTWALLPAPER;
    
    if (Query.IsPropertyRequired(m_szInitialProgramPath))
        ulRequiredProperties |= BIT_INITIALPROGRAMPATH;
    
    if (Query.IsPropertyRequired(m_szInitialProgramPolicy))
        ulRequiredProperties |= BIT_INITIALPROGRAMPOLICY;
    
    if (Query.IsPropertyRequired(m_szStartIn))
        ulRequiredProperties |= BIT_STARTIN;
    
    if ( pInstance != NULL )
    {
        
        hr = StackObj.m_pCfgComp->GetWSInfo((LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS);

        if( SUCCEEDED( hr ) && pWS != NULL )
        {
            hr = LoadPropertyValues(pInstance, ulRequiredProperties, pWS );
        }                        
    }    	

    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }
	
    return hr;
}

//=--------------------
/*****************************************************************************
*
*  FUNCTION    :    CWin32_TSEnvironmentSetting::EnumerateInstances
*
*  DESCRIPTION :    Returns all the instances of this class.
*
*  INPUTS      :    A pointer to the MethodContext for communication with WinMgmt.
*                   A long that contains the flags described in 
*                   IWbemServices::CreateInstanceEnumAsync.  Note that the following
*                   flags are handled by (and filtered out by) WinMgmt:
*                   WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY, 
*                   WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
*  RETURNS     :    WBEM_S_NO_ERROR if successful
*
*  COMMENTS    :    All instances on the machine are returned here and
*                   all properties that this class knows how to populate must 
*                   be filled in.  If there are no instances, return 
*                   WBEM_S_NO_ERROR.  
*****************************************************************************/

HRESULT CWin32_TSEnvironmentSetting::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
    
    HRESULT hr = WBEM_S_NO_ERROR;
    DWORD dwData = 0;
    ULONG  ulTerminals = 0;
    ULONG ulNum = 0;
    ULONG  ulSize = 0; 
    LONG  lSize = 0;
    PWS  pWS = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}

    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ); ulNum++)
        {   
            CInstance* pInstance = CreateNewInstance(pMethodContext);
            
            if( pInstance == NULL)
            {
                ERR((TB,"TSEnvironmentSetting@EnumerateInstances: CreateNewInstance Failed" ));                
                
                hr = WBEM_E_OUT_OF_MEMORY;
                
                break;
            }            

            hr = LoadPropertyValues(pInstance, BIT_ALL_PROPERTIES, &pWS[ulNum] );
            
            if( SUCCEEDED( hr ) )
            {
                hr = pInstance->Commit();                                
            }
            
            pInstance->Release( );
        }
    }   
    
    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);
    }
    
    return hr;
}

//=--------------------

HRESULT CWin32_TSEnvironmentSetting::LoadPropertyValues( CInstance *pInstance, ULONGLONG ulRequiredProperties, PWS pWS)
{
 	
    HRESULT hr = WBEM_S_NO_ERROR;
    LONG lSize ;
    DWORD dwData = 0;
    USERCONFIGW* pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL  )
    {
        ERR((TB,"TSEnvironmentSetting@LoadPropertyValues: invalid pointer" ));
        
        return WBEM_E_ILLEGAL_NULL;       
    }
    
    if ( pWS != NULL )
    {
        if( ulRequiredProperties & BIT_TERMINALNAME)
        {
            pInstance->SetCharSplat(m_szTerminalName, pWS->Name);
        }
        
        hr = StackObj.m_pCfgComp->GetUserConfig(pWS->Name, &lSize, &pUser, TRUE);
        
        TRC2((TB,"TSEnvironmentSetting@LoadPropertyValues: GetTerminalName ret 0x%x\n" , hr  ));
        
        if ( SUCCEEDED (hr) && pUser != NULL )
        {
            
            if( ulRequiredProperties & BIT_INITIALPROGRAMPOLICY)
            {
                
                pInstance->SetDWORD(m_szInitialProgramPolicy, pUser->fInheritInitialProgram);
                
            }
            TRC2((TB,"TSEnvironmentSetting@LoadPropertyValues: InitialProgramPolicy"  ));
            
            if( ulRequiredProperties & BIT_INITIALPROGRAMPATH)
            {                          
                pInstance->SetWCHARSplat(m_szInitialProgramPath, pUser->InitialProgram);
                
            }
            TRC2((TB,"TSEnvironmentSetting@LoadPropertyValues: InitialProgramPath"  ));
            
            if( ulRequiredProperties & BIT_STARTIN)
            {                          
                pInstance->SetWCHARSplat(m_szStartIn, pUser->WorkDirectory);
                
            }
            TRC2((TB,"TSEnvironmentSetting@LoadPropertyValues: StartIn"  ));
            
            if( ulRequiredProperties & BIT_CLIENTWALLPAPER)
            {                          
                pInstance->SetDWORD(m_szClientWallPaper, pUser->fWallPaperDisabled);
                
            }
            TRC2((TB,"TSEnvironmentSetting@LoadPropertyValues: ClientWallPaper"  ));            
        }                  
    }
        
    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);
    }
	
    return hr;
    
}

//=--------------------

HRESULT CWin32_TSEnvironmentSetting::PutInstance ( const CInstance &Instance, long lFlags)
{	
    HRESULT hr= WBEM_S_NO_ERROR;
    DWORD dwData = 0;
    DWORD dwStatus = 0;
    CHString chTermName;
    LONG lSize;
    PUSERCONFIG pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    Instance.GetCHString(m_szTerminalName, chTermName);
    
    if(chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if (chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    
    hr = StackObj.m_pCfgComp->GetUserConfig((LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE);
    
    do
    {
        
        if( SUCCEEDED (hr) && pUser != NULL )
        {
            Instance.GetDWORD(m_szInitialProgramPolicy, dwData);
            
            if( dwData != 0 && dwData != 1 )
            {
                hr = WBEM_E_INVALID_PARAMETER;
                
                break;
            }
            
            pUser->fInheritInitialProgram = dwData;
            
            Instance.GetDWORD( m_szClientWallPaper, dwData );
            
            if( dwData != 0 && dwData != 1 )
            {
                hr = WBEM_E_INVALID_PARAMETER;
                
                break;
            }
            
            pUser->fWallPaperDisabled = dwData;
            
            hr = StackObj.m_pCfgComp->SetUserConfig((LPTSTR)(LPCTSTR) chTermName, lSize, pUser , &dwStatus );
            
            if( SUCCEEDED( hr ))
            {
                hr = StackObj.m_pCfgComp->ForceUpdate();
            }
            
        }
        else
        {
            TRC2((TB,"TSEnvironmentSetting@PutInstance: ret 0x%x\n" , hr  ));  
            
            CHString sRelPath;
            
            Instance.GetCHString(L"__RelPath", sRelPath);
            CInstance *pErrorInstance = NULL;
            
            
            hr = CWbemProviderGlue::GetInstanceByPath(pErrorClass, &pErrorInstance );
            
            if( SUCCEEDED( hr ) )
            {
                TRC2((TB,"TSEnvironmentSetting@PutInstance: ret 0x%x\n" , hr  ));  
                
                if (pErrorInstance != NULL)
                {
                    LoadString( g_hInstance , IDS_ERR_PUTTSECONFIG, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                    pErrorInstance->SetWCHARSplat(L"Description", tchErrorMessage);
                    
                    LoadString( g_hInstance , IDS_ERR_PUTINSTANCE, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                    pErrorInstance->SetWCHARSplat(L"Operation", tchErrorMessage);
                    
                    pErrorInstance->SetCHString(L"ParameterInfo", sRelPath);
                    pErrorInstance->SetWCHARSplat(L"ProviderName", PROVIDER_NAME_Win32_WIN32_TSENVIRONMENTSETTING_Prov);
                    pErrorInstance->SetDWORD(L"StatusCode", WBEM_E_INVALID_PARAMETER);
                    
                    
                    IWbemClassObject *pObj = pErrorInstance->GetClassObjectInterface();
                    if (pObj != NULL)
                    {
                        
                        MethodContext *pMethodContext = Instance.GetMethodContext();  
                        
                        
                        if (pMethodContext != NULL)
                        {
                            pMethodContext->SetStatusObject(pObj);
                        }
                        
                        
                        pObj->Release();
                    }
                    pErrorInstance->Release();
                }
                
            }
        }
    }while (0);

    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);
    }
	
    return hr;
}


//=--------------------


HRESULT CWin32_TSEnvironmentSetting::ExecMethod ( const CInstance& Inst,
                                                        const BSTR bstrMethodName,
                                                        CInstance *pInParams,
                                                        CInstance *pOutParams,
                                                        long lFlags)
                                                        
{	   
    HRESULT hr = WBEM_E_NOT_FOUND;
    CHString chTermName;
    PUSERCONFIG pUser = NULL;

	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}

    Inst.GetCHString( m_szTerminalName, chTermName );
    
    if( chTermName.GetLength( ) > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }
       
    
    // Sets the properties InitialProgramPath and StartIn which 
    // specify the name and path of the program and the working 
    // directory path for the program the user wants to start on 
    // logon to the Terminal Server.              
    
    // uint32 InitialProgram([In] string InitialProgramPath, [In] string Startin)
    
    do
    {
        if (_wcsicmp(bstrMethodName, m_szInitialProgram) == 0)
        {
            
            DWORD dwData = 0;
            DWORD dwStatus = 0;
            CHString chData;
            LONG lSize;
            
            hr = StackObj.m_pCfgComp->GetUserConfig((LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE);
            
            if( SUCCEEDED (hr) && pUser != NULL )
            {
                
                dwData = pUser->fInheritInitialProgram;
                
                if( (dwData == 0) && pInParams != NULL )
                {   
                    chData.Empty();                       
                    
                    pInParams->GetCHString(m_szInitialProgramPath, chData);
                    
                    if( chData.GetLength() > 256 )
                    {                        
                        hr = WBEM_E_VALUE_OUT_OF_RANGE;
                        
                        break;
                    }
                                      
                    wcscpy( pUser->InitialProgram, (LPTSTR)(LPCTSTR) chData );
                    
                    chData.Empty();
                                        
                    pInParams->GetCHString( m_szStartIn, chData );
                    
                    if( chData.GetLength() > 256 )
                    {
                        hr = WBEM_E_VALUE_OUT_OF_RANGE;
                        
                        break;
                    }
                    
                    wcscpy( pUser->WorkDirectory, (LPTSTR) (LPCTSTR) chData );
                    
                    hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR) (LPCTSTR) chTermName, lSize, pUser , &dwStatus );
                    
                    if( SUCCEEDED( hr ) && pOutParams != NULL )
                    {
                        StackObj.m_pCfgComp->ForceUpdate();

                        pOutParams->SetDWORD( L"ReturnValue", WBEM_S_NO_ERROR );
                    }
                }
                else
                {
                    hr = WBEM_E_INVALID_OPERATION;
                    
                    break;                    
                }
            }
        }
    }while (0);

    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);        
    }    

    return hr;
}


//=-----------------------

HRESULT CWin32_TSEnvironmentSetting::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{
    // return (WBEM_E_PROVIDER_NOT_CAPABLE);
    
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    ULONGLONG ulRequiredProperties = 0;
    CHStringArray asNames;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;

	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
   
    // Method 2
    Query.GetValuesForProp(m_szTerminalName, asNames);
    
    BOOL bGetAllInstances = asNames.GetSize() == 0;
    
    // Method 1
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szClientWallPaper))
        ulRequiredProperties |= BIT_CLIENTWALLPAPER;
    
    if (Query.IsPropertyRequired(m_szInitialProgramPath))
        ulRequiredProperties |= BIT_INITIALPROGRAMPATH;
    
    if (Query.IsPropertyRequired(m_szInitialProgramPolicy))
        ulRequiredProperties |= BIT_INITIALPROGRAMPOLICY;
    
    if (Query.IsPropertyRequired(m_szStartIn))
        ulRequiredProperties |= BIT_STARTIN;
    
    
    hr = StackObj.m_pCfgComp->GetWinstationList( &ulTerminals, &ulSize, &pWS );
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals ; ulNum++)
        {        
            // Method 2
            if (bGetAllInstances || IsInList(asNames, pWS[ulNum].Name))
            {
                CInstance* pInstance = CreateNewInstance(pMethodContext);
                
                if( pInstance == NULL)
                {
                    TRC2((TB,"TSEnvironmentSetting@ExecQuery CreateNewInstance failed"  ));  
                    
                    hr = WBEM_E_OUT_OF_MEMORY;
                    
                    break;
                }
                
                pInstance->SetCHString( m_szTerminalName, CHString( pWS[ulNum].Name ) );

                hr = LoadPropertyValues( pInstance, ulRequiredProperties, &pWS[ ulNum ] );
                
                if (SUCCEEDED( hr ) )
                {
                    hr = pInstance->Commit();
                }
                
                pInstance->Release();
            }
        }
    }

    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }
    
    return hr;
    
}



//=----------------------Win32_TSRemoteControlSettingsConfig---------------------


CWin32_TSRemoteControlSetting::CWin32_TSRemoteControlSetting (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
Provider( lpwszName, lpwszNameSpace )
{

    if ( g_hInstance != NULL)
    {
        TRC2((TB, "CWin32_TSRemoteControlSetting_ctor"));

        _tcscpy(m_szRemoteControlPolicy, _T("RemoteControlPolicy"));

        _tcscpy(m_szLevelOfControl, _T("LevelOfControl"));

        _tcscpy(m_szTerminalName, _T("TerminalName"));

        _tcscpy(m_szRemoteControl, _T("RemoteControl"));        
    }

}

//=--------------------

CWin32_TSRemoteControlSetting::~CWin32_TSRemoteControlSetting ()
{
}



//=------------

BOOL CWin32_TSRemoteControlSetting::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
    DWORD dwSize = asArray.GetSize();
    
    for (DWORD x=0; x < dwSize; x++)
    {
        if (asArray[x].CompareNoCase(pszString) == 0)
        {
            return TRUE;
        }
    }
    
    return FALSE;
}

//=--------------------

HRESULT CWin32_TSRemoteControlSetting::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    DWORD dwData = 0;
    CHString chTermName;
    LONG  lSize ;
    PWS pWS = NULL;
    ULONGLONG ulRequiredProperties = 0;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL )
    {
        ERR((TB,"TSRemoteControlSetting@Getobject invalid pointer"  ));  
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    pInstance->GetCHString(m_szTerminalName, chTermName);
    
    if(chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if(chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }

    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szRemoteControlPolicy))
        ulRequiredProperties |= BIT_REMOTECONTROLPOLICY;
    
    if (Query.IsPropertyRequired(m_szLevelOfControl))
        ulRequiredProperties |= BIT_LEVELOFCONTROL;
    
    if( pInstance != NULL )
    {
        hr = StackObj.m_pCfgComp->GetWSInfo((LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS);

        if( SUCCEEDED( hr ) && pWS != NULL )
        {
            hr = LoadPropertyValues(pInstance, ulRequiredProperties, pWS );
        }               
    }

    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }
    
    return hr;    
}

//=--------------------

/*****************************************************************************
*
*  FUNCTION    :    CWin32_TSRemoteControlSetting::EnumerateInstances
*
*  DESCRIPTION :    Returns all the instances of this class.
*
*  INPUTS      :    A pointer to the MethodContext for communication with WinMgmt.
*                   A long that contains the flags described in 
*                   IWbemServices::CreateInstanceEnumAsync.  Note that the following
*                   flags are handled by (and filtered out by) WinMgmt:
*                   WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY, 
*                   WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
*  RETURNS     :    WBEM_S_NO_ERROR if successful
*
*  COMMENTS    :    All instances on the machine are returned here and
*                   all properties that this class knows how to populate must 
*                   be filled in.  If there are no instances, return 
*                   WBEM_S_NO_ERROR.  
*****************************************************************************/

HRESULT CWin32_TSRemoteControlSetting::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
	
    HRESULT hr = WBEM_S_NO_ERROR;
    DWORD dwData = 0;
    ULONG  ulTerminals = 0;
    ULONG  ulSize = 0; 
    LONG  lSize = 0;
    ULONG ulNum = 0;
    PWS  pWS = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    { 

		
        for ( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {   
			
            CInstance* pInstance = CreateNewInstance(pMethodContext);            

            if( pInstance == NULL)
            {
                ERR((TB,"TSRemoteControlSetting@EnumerateInstances CreateNewInstance failed"  ));               
                
                hr = WBEM_E_OUT_OF_MEMORY;
                
                break;
            }
            TRC2((TB,"TSRemoteControlSetting@EnumerateInstances: GetWinstationList ret 0x%x\n" , hr  ));    
            
            hr = LoadPropertyValues( pInstance, BIT_ALL_PROPERTIES, &pWS[ulNum] );
            
            if ( SUCCEEDED( hr ) )
            {
                hr = pInstance->Commit();
            }
			
            pInstance->Release( );

        } 
        
    }  

    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }

    return hr;
}

//=--------------------

HRESULT CWin32_TSRemoteControlSetting::LoadPropertyValues( CInstance *pInstance, ULONGLONG ulRequiredProperties, PWS pWS)
{	
    HRESULT hr = WBEM_S_NO_ERROR;
    LONG lSize ;
    DWORD dwData = 0;
    USERCONFIGW* pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL )
    {
        return WBEM_E_ILLEGAL_NULL;       
    }
    
    
    if ( pInstance != NULL && pWS != NULL )
    {
        if( ulRequiredProperties & BIT_TERMINALNAME)
        {
            pInstance->SetCharSplat(m_szTerminalName, pWS->Name);
        }
        
        TRC2((TB,"TSRemoteControlSetting@LoadPropertyValues: GetTerminalName"  ));
        
        hr = StackObj.m_pCfgComp->GetUserConfig(pWS->Name, &lSize, &pUser, TRUE);
        
        TRC2((TB,"TSRemoteControlSetting@LoadPropertyValues: GetUserConfig ret 0x%x\n" , hr  ));
        
        if ( SUCCEEDED (hr) && pUser != NULL )
        {
            
            if( ulRequiredProperties & BIT_REMOTECONTROLPOLICY)
            {
                
                pInstance->SetDWORD(m_szRemoteControlPolicy, pUser->fInheritShadow);
				
            }
            TRC2((TB,"TSRemoteControlSetting@LoadPropertyValues: RemoteControlPolicy"  ));
            
            if( ulRequiredProperties & BIT_LEVELOFCONTROL)
            {
                
                pInstance->SetDWORD(m_szLevelOfControl, pUser->Shadow);

            }
            TRC2((TB,"TSRemoteControlSetting@LoadPropertyValues: LevelOfControl"));            
        }                  

    }   

    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);
        
    }
	
    return hr;
}

//=--------------------

HRESULT CWin32_TSRemoteControlSetting::PutInstance ( const CInstance &Instance, long lFlags)
{
	
    HRESULT hr= WBEM_S_NO_ERROR;
    CHString chTermName ;
    DWORD dwData = 0;
    DWORD dwStatus = 0;
    LONG  lSize;
    PUSERCONFIG pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    
    Instance.GetCHString(m_szTerminalName, chTermName);
    
    if(chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    hr = StackObj.m_pCfgComp->GetUserConfig((LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE);
    
    do
    {
        if( SUCCEEDED( hr ) && pUser != NULL )
        {
            if( Instance.GetDWORD( m_szRemoteControlPolicy, dwData ) )
            {
                pUser->fInheritShadow = dwData;
                
                if ( dwData != 0 && dwData != 1 )
                {
                    hr = WBEM_E_INVALID_PARAMETER;
                    
                    break;
                }
                
                hr = StackObj.m_pCfgComp->SetUserConfig((LPTSTR)(LPCTSTR) chTermName, lSize, pUser , &dwStatus );
                
                if( SUCCEEDED( hr ))
                {
                    hr = StackObj.m_pCfgComp->ForceUpdate();
                }
            }
            
        }
        
        else
        {
            TRC2((TB,"TSRemoteControlSetting@PutInstance: ret 0x%x\n" , hr ));
            
            CHString sRelPath;
            
            Instance.GetCHString(L"__RelPath", sRelPath);
            CInstance *pErrorInstance = NULL;
            
            hr = CWbemProviderGlue::GetInstanceByPath(pErrorClass, &pErrorInstance );
            
            if(( SUCCEEDED( hr ) ) && (pErrorInstance != NULL))
            {
                
                LoadString( g_hInstance , IDS_ERR_PUTTSRCONFIG, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                pErrorInstance->SetWCHARSplat(L"Description", tchErrorMessage);
                
                LoadString( g_hInstance , IDS_ERR_PUTINSTANCE, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                pErrorInstance->SetWCHARSplat(L"Operation", tchErrorMessage);
                
                pErrorInstance->SetCHString(L"ParameterInfo", sRelPath);
                pErrorInstance->SetWCHARSplat(L"ProviderName", PROVIDER_NAME_Win32_WIN32_TSREMOTECONTROLSETTING_Prov);
                pErrorInstance->SetDWORD(L"StatusCode", WBEM_E_INVALID_PARAMETER);
                
                IWbemClassObject *pObj = pErrorInstance->GetClassObjectInterface();
                if (pObj != NULL)
                {
                    
                    MethodContext *pMethodContext = Instance.GetMethodContext();  
                    
                    if (pMethodContext != NULL)
                    {
                        pMethodContext->SetStatusObject(pObj);
                    }
                    
                    pObj->Release();
                }
                pErrorInstance->Release();
                
            }
            TRC2((TB,"TSRemoteControlSetting@PutInstance: GetInstanceByPath ret 0x%x\n" , hr ));           
        }
    }while (0);

    if( pUser != NULL )
    {
        CoTaskMemFree(pUser);        
    }

    return hr;
}

//=--------------------

HRESULT CWin32_TSRemoteControlSetting::ExecMethod ( const CInstance& Inst,
                                                          const BSTR bstrMethodName,
                                                          CInstance *pInParams,
                                                          CInstance *pOutParams,
                                                          long lFlags)
                                                          
{
	
    HRESULT hr= WBEM_E_NOT_FOUND;
    CHString chTermName;    

	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}

    Inst.GetCHString(m_szTerminalName, chTermName);
    
    if(chTermName.GetLength() > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if(chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
        
    
    // Sets the property LevelOfControl which specifies the level of control
    // which is one of Disable, EnableInputNotify, EnableInputNoNotify, 
    // EnableNoInputNotify, EnableNoInputNoNotify. 

    // uint32 RemoteControl([In] uint32 LevelOfControl);
    
    if( _wcsicmp( bstrMethodName, m_szRemoteControl ) == 0 )
    {
        
        DWORD dwRemoteData = 0;
        DWORD dwData = 0;
        DWORD dwStatus = 0;
        bool bRet;
        LONG lSize;
        PUSERCONFIG pUser = NULL;
        
        if ( pInParams != NULL )
        {
            
            hr = StackObj.m_pCfgComp->GetUserConfig( (LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE );
            
            do
            {
                if ( SUCCEEDED( hr ) && pUser != NULL )
                {
                    dwRemoteData = pUser->fInheritShadow;
                    
                    if ( SUCCEEDED( hr ) && ( dwRemoteData == 0 ))
                    {  
                        bRet = pInParams->GetDWORD(m_szLevelOfControl, dwData);
                        
                        if ( !bRet )
                        {
                            hr = WBEM_E_INVALID_PARAMETER;
                            
                            break;
                        }
                        
                        pUser->Shadow = ( SHADOWCLASS )dwData;
                        
                        hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR)(LPCTSTR) chTermName, lSize, pUser , &dwStatus );
                        
                        if( SUCCEEDED( hr ) && pOutParams )
                        {
                            hr = StackObj.m_pCfgComp->ForceUpdate();

                            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                            
                        }
                        TRC2((TB,"TSRemoteControlSetting@ExecMethod: LevelOfControl ret 0x%x\n" , hr ));
                    }
                    else
                    {
                        hr = WBEM_E_INVALID_OPERATION;
                    }
                    
                }
            }while (0);
            
            if ( pUser != NULL )
            {
                CoTaskMemFree(pUser);
            }
        }      
    }

    return hr;
}

//=-------------------------------

HRESULT CWin32_TSRemoteControlSetting::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    ULONGLONG ulRequiredProperties = 0;
    CHStringArray asNames;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}

    // Method 2
    Query.GetValuesForProp(m_szTerminalName, asNames);
    
    BOOL bGetAllInstances = asNames.GetSize() == 0;
    
    // Method 1
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szRemoteControlPolicy))
        ulRequiredProperties |= BIT_REMOTECONTROLPOLICY;
    
    if (Query.IsPropertyRequired(m_szLevelOfControl))
        ulRequiredProperties |= BIT_LEVELOFCONTROL;
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals ; ulNum++)
        {
            if( bGetAllInstances || IsInList(asNames, pWS[ulNum].Name))
            {
                
                CInstance* pInstance = CreateNewInstance(pMethodContext);
                
                if( pInstance == NULL)
                {
                    TRC2((TB,"TSRemoteControlSetting@ExecQuery: CreateNewInstance failed" ));
                    
                    hr = WBEM_E_OUT_OF_MEMORY;
                    
                    break;
                }
                
                pInstance->SetCHString(m_szTerminalName, CHString(pWS[ulNum].Name));

                hr = LoadPropertyValues( pInstance, ulRequiredProperties, &pWS[ ulNum ] );
                
                if( SUCCEEDED( hr ) )
                {
                    hr = pInstance->Commit();
                }
                
                pInstance->Release();
            }
        }
    }

    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
    }

    return hr;
    
}




//=----------------------Win32_TSClientSetting---------------------


CWin32_TSClientSetting::CWin32_TSClientSetting (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
Provider( lpwszName, lpwszNameSpace )
{  
    if ( g_hInstance != NULL)
    {
        TRC2((TB, "CWin32_TSClientSetting_ctor"));

        _tcscpy(m_szConnectionPolicy, _T("ConnectionPolicy"));

        _tcscpy(m_szConnectClientDrivesAtLogon, _T("ConnectClientDrivesAtLogon"));

        _tcscpy(m_szConnectPrinterAtLogon, _T("ConnectPrinterAtLogon"));

        _tcscpy(m_szDefaultToClientPrinter, _T("DefaultToClientPrinter"));

        _tcscpy(m_szWindowsPrinterMapping, _T("WindowsPrinterMapping"));

        _tcscpy(m_szLPTPortMapping, _T("LPTPortMapping"));

        _tcscpy(m_szCOMPortMapping, _T("COMPortMapping"));

        _tcscpy(m_szDriveMapping, _T("DriveMapping"));

        _tcscpy(m_szAudioMapping, _T("AudioMapping"));

        _tcscpy(m_szClipboardMapping, _T("ClipboardMapping"));

        _tcscpy(m_szTerminalName, _T("TerminalName"));

        _tcscpy(m_szPropertyName, _T("PropertyName"));

        _tcscpy(m_szValue, _T("Value"));

        _tcscpy(m_szConnectionSettings, _T("ConnectionSettings"));

        _tcscpy(m_szSetClientProperty, _T("SetClientProperty"));

        _tcscpy(m_szColorDepth, _T("ColorDepth"));

        _tcscpy(m_szSetColorDepth, _T("SetColorDepth"));

        _tcscpy(m_szColorDepthPolicy, _T("ColorDepthPolicy"));

        _tcscpy(m_szSetColorDepthPolicy, _T("SetColorDepthPolicy"));
        
               
    }
    RegGetMachinePolicy(&m_gpPolicy);
}
//=--------------------

CWin32_TSClientSetting::~CWin32_TSClientSetting ()
{
    
}


//=-----------------

BOOL CWin32_TSClientSetting::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
    DWORD dwSize = asArray.GetSize();
    
    for (DWORD x=0; x < dwSize; x++)
    {
        if (asArray[x].CompareNoCase(pszString) == 0)
        {
            return TRUE;
        }
    }
    
    return FALSE;
}


//=--------------------

HRESULT CWin32_TSClientSetting::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    DWORD dwData = 0;
    CHString chTermName; 
    LONG  lSize ;
    ULONGLONG ulRequiredProperties = 0;
    PWS pWS = NULL;
//    PUSERCONFIG pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL  )
    {
        ERR((TB,"TSClientSetting@GetObject: invalid pointer" ));
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    pInstance->GetCHString(m_szTerminalName, chTermName);
    
    if(chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szAudioMapping))
        ulRequiredProperties |= BIT_AUDIOMAPPING;
    
    if (Query.IsPropertyRequired(m_szClipboardMapping))
        ulRequiredProperties |= BIT_CLIPBOARDMAPPING;
    
    if (Query.IsPropertyRequired(m_szCOMPortMapping))
        ulRequiredProperties |= BIT_COMPORTMAPPING;
    
    if (Query.IsPropertyRequired(m_szConnectClientDrivesAtLogon))
        ulRequiredProperties |= BIT_CONNECTCLIENTDRIVESATLOGON;
    
    if (Query.IsPropertyRequired(m_szConnectionPolicy))
        ulRequiredProperties |= BIT_CONNECTIONPOLICY;
    
    if (Query.IsPropertyRequired(m_szConnectPrinterAtLogon))
        ulRequiredProperties |= BIT_CONNECTPRINTERATLOGON;
    
    if (Query.IsPropertyRequired(m_szDefaultToClientPrinter))
        ulRequiredProperties |= BIT_DEFAULTTOCLIENTPRINTER;
    
    if (Query.IsPropertyRequired(m_szDriveMapping))
        ulRequiredProperties |= BIT_DRIVEMAPPING;
    
    if (Query.IsPropertyRequired(m_szLPTPortMapping))
        ulRequiredProperties |= BIT_LPTPORTMAPPING;
    
    if (Query.IsPropertyRequired(m_szWindowsPrinterMapping))
        ulRequiredProperties |= BIT_WINDOWSPRINTERMAPPING;

    if (Query.IsPropertyRequired(m_szColorDepth))
        ulRequiredProperties |= BIT_COLORDEPTH;

    if (Query.IsPropertyRequired(m_szColorDepthPolicy))
        ulRequiredProperties |= BIT_COLORDEPTHPOLICY;


    if ( pInstance != NULL )
    {
        hr = StackObj.m_pCfgComp->GetWSInfo( (LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS );

        if( SUCCEEDED( hr ) && pWS != NULL )
        {
            hr = LoadPropertyValues( pInstance, ulRequiredProperties, pWS );
        }                
    }

    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);
    }	
    return hr;
    
}
//=--------------------
/*****************************************************************************
*
*  FUNCTION    :    CWin32_TSClientSetting::EnumerateInstances
*
*  DESCRIPTION :    Returns all the instances of this class.
*
*  INPUTS      :    A pointer to the MethodContext for communication with WinMgmt.
*                   A long that contains the flags described in 
*                   IWbemServices::CreateInstanceEnumAsync.  Note that the following
*                   flags are handled by (and filtered out by) WinMgmt:
*                   WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY, 
*                   WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
*  RETURNS     :    WBEM_S_NO_ERROR if successful
*
*  COMMENTS    :    All instances on the machine are returned here and
*                   all properties that this class knows how to populate must 
*                   be filled in.  If there are no instances, return 
*                   WBEM_S_NO_ERROR.  
*****************************************************************************/

HRESULT CWin32_TSClientSetting::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
	
    HRESULT hr = WBEM_S_NO_ERROR;
    DWORD dwData = 0;
    ULONG  ulTerminals = 0;
    ULONG  ulSize = 0; 
    LONG  lSize = 0;
    ULONG ulNum = 0;
    PWS  pWS = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
        
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {   
            CInstance* pInstance = CreateNewInstance(pMethodContext);
            
            if( pInstance == NULL)
            {
                ERR((TB,"TSClientSetting@EnumerateInstances: CreateNewInstance failed" ));                
                
                hr = WBEM_E_OUT_OF_MEMORY;
                
                break;
            }
            TRC2((TB,"TSClientSetting@EnumerateInstances: GetWinstationList ret 0x%x\n" , hr ));

            hr = LoadPropertyValues(pInstance, BIT_ALL_PROP, &pWS[ ulNum ] );
            
            if( SUCCEEDED( hr ) )
            {
                hr = pInstance->Commit();

            }
            pInstance->Release( );
        }
        
    }  

    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);
    }
  
    return hr;
}
//=--------------------

HRESULT CWin32_TSClientSetting::LoadPropertyValues( CInstance *pInstance, ULONGLONG ulRequiredProperties, PWS pWS)
{
	
    HRESULT hr = WBEM_S_NO_ERROR;
    LONG lSize ;
    DWORD dwData = 0;
    BOOL bData = 0;
    DWORD dwStatus = 0;
    USERCONFIGW* pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL  )
    {
        ERR((TB,"TSClientSetting@LoadPropertyValues: invalid pointer"));
        
        return WBEM_E_ILLEGAL_NULL;       
    }
    
    if( pInstance != NULL && pWS != NULL )
    {
        if( ulRequiredProperties & BIT_TERMINALNAME)
        {
	        pInstance->SetCharSplat(m_szTerminalName, pWS->Name);
        }

        TRC2((TB,"TSClientSetting@LoadPropertyValues: GetTerminalName"));
        
        hr = StackObj.m_pCfgComp->GetUserConfig(pWS->Name, &lSize, &pUser, TRUE);
        
        TRC2((TB,"TSClientSetting@LoadPropertyValues ret 0x%x\n" , hr));
        
        if( SUCCEEDED (hr) && pUser != NULL )
        {            
            if( ulRequiredProperties & BIT_CONNECTIONPOLICY)
            {                
                pInstance->SetDWORD(m_szConnectionPolicy, pUser->fInheritAutoClient);     
                
                TRC2((TB,"TSClientSetting@LoadPropertyValues: ConnectionPolicy" ));
            }
                     
            
            if( ulRequiredProperties & BIT_CONNECTCLIENTDRIVESATLOGON)
            {  
                pInstance->SetDWORD(m_szConnectClientDrivesAtLogon, pUser->fAutoClientDrives);      
                
                TRC2((TB,"TSClientSetting@LoadPropertyValues ConnectClientDrives"));
            }            
                           
            
            if( ulRequiredProperties & BIT_CONNECTPRINTERATLOGON)
            {  
                pInstance->SetDWORD(m_szConnectPrinterAtLogon, pUser->fAutoClientLpts);
                
                TRC2((TB,"TSClientSetting@LoadPropertyValues: ConnectPrinter"));
            }
            
            
            if( ulRequiredProperties & BIT_DEFAULTTOCLIENTPRINTER)
            {                
                pInstance->SetDWORD(m_szDefaultToClientPrinter, pUser->fForceClientLptDef); 
                
                TRC2((TB,"TSClientSetting@LoadPropertyValues: DefaultToClientPrinter"));
            }
                        
            
            if( ulRequiredProperties & BIT_LPTPORTMAPPING)
            { 
                RegGetMachinePolicy(&m_gpPolicy);

                if( m_gpPolicy.fPolicyDisableLPT != 0 )
                {
                    pInstance->SetDWORD(m_szLPTPortMapping, m_gpPolicy.fDisableLPT);
                }
                else
                {
                    pInstance->SetDWORD(m_szLPTPortMapping, pUser->fDisableLPT);
                }                
                
                TRC2((TB,"TSClientSetting@LoadPropertyValues: WindowsPrinterMapping"));
            }
                        
            
            if( ulRequiredProperties & BIT_WINDOWSPRINTERMAPPING)
            {
                RegGetMachinePolicy(&m_gpPolicy);

                if( m_gpPolicy.fPolicyDisableCpm != 0 )
                {
                    pInstance->SetDWORD(m_szWindowsPrinterMapping, m_gpPolicy.fDisableCpm);
                }
                else
                {
                    pInstance->SetDWORD(m_szWindowsPrinterMapping, pUser->fDisableCpm);
                }    
                
                TRC2((TB,"TSClientSetting@LoadPropertyValues: LPTPortMapping"));            
            }
            
            
            if( ulRequiredProperties & BIT_COMPORTMAPPING)
            {  
                RegGetMachinePolicy(&m_gpPolicy);

                if( m_gpPolicy.fPolicyDisableCcm != 0 )
                {
                    pInstance->SetDWORD(m_szCOMPortMapping, m_gpPolicy.fDisableCcm);
                }
                else
                {
                    pInstance->SetDWORD(m_szCOMPortMapping, pUser->fDisableCcm);
                }
                 
                TRC2((TB,"TSClientSetting@LoadPropertyValues: COMPortMapping"));
            }
            
            
            if( ulRequiredProperties & BIT_DRIVEMAPPING)
            { 
                RegGetMachinePolicy(&m_gpPolicy);

                if( m_gpPolicy.fPolicyDisableCdm != 0 )
                {
                    pInstance->SetDWORD(m_szDriveMapping, m_gpPolicy.fDisableCdm);                                                   
                }
                else
                {
                    pInstance->SetDWORD(m_szDriveMapping, pUser->fDisableCdm);
                } 

                TRC2((TB,"TSClientSetting@LoadPropertyValues: DriveMapping"));
            }
            
            
            if( ulRequiredProperties & BIT_AUDIOMAPPING)
            { 
                RegGetMachinePolicy(&m_gpPolicy);

                if( m_gpPolicy.fPolicyDisableCam != 0 )
                {
                    pInstance->SetDWORD(m_szAudioMapping, m_gpPolicy.fDisableCam);
                }
                else
                {
                    pInstance->SetDWORD(m_szAudioMapping, pUser->fDisableCam);
                }
                
                TRC2((TB,"TSClientSetting@LoadPropertyValues: AudioMapping"));
            }
            
            
            if( ulRequiredProperties & BIT_CLIPBOARDMAPPING)
            {
                RegGetMachinePolicy(&m_gpPolicy);

                if( m_gpPolicy.fPolicyDisableClip != 0 )
                {
                    pInstance->SetDWORD(m_szClipboardMapping, m_gpPolicy.fDisableClip);
                }
                else
                {
                    pInstance->SetDWORD(m_szClipboardMapping, pUser->fDisableClip);
                }
                
                TRC2((TB,"TSClientSetting@LoadPropertyValues ClipboardMapping"));
            }
            
            if( ulRequiredProperties & BIT_COLORDEPTHPOLICY)
            {  
                RegGetMachinePolicy(&m_gpPolicy);

                if( m_gpPolicy.fPolicyColorDepth != 0 )
                {
                    dwData = m_gpPolicy.fPolicyColorDepth;
                }
                else
                {  
                    hr = StackObj.m_pCfgComp->GetColorDepth( pWS->Name, &bData, &dwStatus);
                   
                    dwData = bData;
                }   
                pInstance->SetDWORD(m_szColorDepthPolicy, dwData);    
                
                TRC2((TB,"TSClientSetting@LoadPropertyValues: ColorDepthPolicy" ));
            }

            if( ulRequiredProperties & BIT_COLORDEPTH)
            {  
                RegGetMachinePolicy(&m_gpPolicy);

                if( m_gpPolicy.fPolicyColorDepth != 0 )
                {
                    pInstance->SetDWORD(m_szColorDepth, m_gpPolicy.ColorDepth);
                }
                else
                {  
                    pInstance->SetDWORD(m_szColorDepth, pUser->ColorDepth);
                   
                }       
                
                TRC2((TB,"TSClientSetting@LoadPropertyValues: ColorDepth" ));
            }
            
        }        
    }
    
    if( pUser != NULL )
    {
        CoTaskMemFree(pUser);
    }
	
    return hr;
    
}

//=--------------------
HRESULT CWin32_TSClientSetting::PutInstance ( const CInstance &Instance, long lFlags)
{
	
    HRESULT hr= WBEM_S_NO_ERROR;
    CHString chTermName ;
    DWORD dwData = 0;
    DWORD dwStatus = 0;
    LONG lSize;
    PUSERCONFIGW pUser = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    Instance.GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    
    if( chTermName.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    hr = StackObj.m_pCfgComp->GetUserConfig( (LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE);
    
    do
    {
        if( SUCCEEDED (hr) && pUser != NULL )
        {
            Instance.GetDWORD(m_szConnectionPolicy, dwData);
            
            if( dwData != 0 && dwData != 1 )
            {
                hr = WBEM_E_INVALID_PARAMETER;
                
                break;
            }
            
            pUser->fInheritAutoClient = dwData;                        
            
            hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR)(LPCTSTR) chTermName, lSize, pUser , &dwStatus );    
            
            if( SUCCEEDED( hr ) )
            {
                hr = StackObj.m_pCfgComp->ForceUpdate();
            }
        }
        
        else
        {
            TRC2((TB,"TSClientSetting@PutInstance: ret 0x%x\n" , hr));           
            
            CHString sRelPath;
            
            Instance.GetCHString(L"__RelPath", sRelPath);

            CInstance *pErrorInstance = NULL;            
            
            hr = CWbemProviderGlue::GetInstanceByPath(pErrorClass, &pErrorInstance );
            
            if( SUCCEEDED( hr ) )
            {
                TRC2((TB,"TSClientSetting@PutInstance: ret 0x%x\n" , hr));

                if (pErrorInstance != NULL)
                {                    
                    LoadString( g_hInstance , IDS_ERR_PUTTSCCONFIG, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );

                    pErrorInstance->SetWCHARSplat(L"Description", tchErrorMessage);
                    
                    LoadString( g_hInstance , IDS_ERR_PUTINSTANCE, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );

                    pErrorInstance->SetWCHARSplat(L"Operation", tchErrorMessage);
                    
                    pErrorInstance->SetCHString(L"ParameterInfo", sRelPath);

                    pErrorInstance->SetWCHARSplat(L"ProviderName", PROVIDER_NAME_Win32_WIN32_TSCLIENTSETTING_Prov);

                    pErrorInstance->SetDWORD(L"StatusCode", WBEM_E_INVALID_PARAMETER);
                    
                    IWbemClassObject *pObj = pErrorInstance->GetClassObjectInterface();

                    if (pObj != NULL)
                    {                        
                        MethodContext *pMethodContext = Instance.GetMethodContext();  
                        
                        if (pMethodContext != NULL)
                        {
                            pMethodContext->SetStatusObject(pObj);
                        }
                        
                        pObj->Release();
                    }
                    
                    pErrorInstance->Release();
                }
                
            }           
        }

    }while (0);
    
    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);        
    }
    
    return hr;
}

//=--------------------
HRESULT CWin32_TSClientSetting::ExecMethod ( const CInstance& Inst,
                                                   const BSTR bstrMethodName,
                                                   CInstance *pInParams,
                                                   CInstance *pOutParams,
                                                   long lFlags)
                                                   
{   
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    CHString chTermName;
    PUSERCONFIG pUser = NULL;
    DWORD dwAutoData = 0;
    DWORD dwData = 0;
    DWORD dwStatus = 0;    
    LONG lSize;
    bool fValue;
    CHString chData;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    Inst.GetCHString(m_szTerminalName, chTermName);
    
    if(chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    do
    {        
        
        if( pInParams != NULL )
        {
            // Sets the properties ClientConnectDrivesAtLogon, ConnectPrinterAtLogon 
            // and DefaultPrinterToClient. 
                      
            // uint32 ConnectSettings([In] uint32 ConnectClientDrivesAtLogon, [In] uint32 ConnectPrinterAtLogon, [In] uint32 DefaultToClientPrinter)
        
            if( _wcsicmp( bstrMethodName, m_szConnectionSettings ) == 0 )
            { 
                bool bRet;
            
                hr = StackObj.m_pCfgComp->GetUserConfig((LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE);
                
                if( SUCCEEDED (hr) && pUser != NULL )
                {
                    dwAutoData = pUser->fInheritAutoClient;
                    
                    if( dwAutoData == 0 )
                    {                           
                        bRet = pInParams->GetDWORD(m_szConnectClientDrivesAtLogon, dwData);
                        
                        if ( !bRet || ( dwData != 0 && dwData != 1 ) )
                        {                            
                            hr = WBEM_E_INVALID_PARAMETER;
                            
                            break;
                        }
                        
                        pUser->fAutoClientDrives = dwData;
                        
                        bRet = pInParams->GetDWORD(m_szConnectPrinterAtLogon, dwData);
                        
                        if( !bRet || ( dwData != 0 && dwData != 1 ) )
                        {                            
                            hr = WBEM_E_INVALID_PARAMETER;
                            
                            break;
                        }
                        
                        pUser->fAutoClientLpts = dwData;
                        
                        bRet = pInParams->GetDWORD(m_szDefaultToClientPrinter, dwData);
                        
                        if( !bRet || ( dwData != 0 && dwData != 1 ) )
                        {                            
                            hr = WBEM_E_INVALID_PARAMETER;
                            
                            break;
                        }
                        
                        pUser->fForceClientLptDef = dwData;
                        
                        hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR)(LPCTSTR) chTermName, lSize, pUser , &dwStatus );
                        
                        TRC2((TB,"TSClientSetting@ExecMethod: ConnectSettings: ret 0x%x\n" , hr ));
                        
                        if( pOutParams != NULL )
                        {
                            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);                            
                        } 
                    }
                    else
                    {                        
                        hr = WBEM_E_INVALID_OPERATION;
                        
                        break;                        
                    }                    
                }                                      
            }

            else if( _wcsicmp( bstrMethodName, m_szSetColorDepthPolicy ) == 0 )
            {
                
                dwData = 0;
                dwStatus = 0; 
                bool bRet;
                
                RegGetMachinePolicy(&m_gpPolicy);

                if( m_gpPolicy.fPolicyColorDepth == 0 )
                {  
                    TRC2((TB, "ColorDepth is not enabled by Group Policy."));                        
                      
                    bRet = pInParams->GetDWORD(m_szColorDepthPolicy, dwData);
                    

                    if ( !bRet || (dwData != 0 && dwData != 1 ))
                    {
                        hr = WBEM_E_INVALID_PARAMETER;
                        
                        break;
                    }                                        
                    
                    hr = StackObj.m_pCfgComp->SetColorDepth( (LPTSTR)(LPCTSTR) chTermName, dwData , &dwStatus );
                    
                    if( SUCCEEDED( hr ) && pOutParams != NULL )
                    {
                        hr = StackObj.m_pCfgComp->ForceUpdate();

                        pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                        
                        TRC2((TB,"TSClientSetting@ExecMethod:  ColorDepthPolicy ret 0x%x\n" , hr  ));
                    } 
                    
                }
                else
                {
                    
                    hr = WBEM_E_INVALID_OPERATION;
                    
                    break;
                    
                }
                
            } 
            
            else if( _wcsicmp( bstrMethodName, m_szSetColorDepth ) == 0 )
            {
                
                dwData = 0;
                dwStatus = 0;
                bool bRet;
                BOOL bData = 0;
                
                RegGetMachinePolicy(&m_gpPolicy);

                if( m_gpPolicy.fPolicyColorDepth == 0 )
                {  
                    TRC2((TB, "Condition to update fInheritColorDepth satisfied"));                        
                      
                    hr = StackObj.m_pCfgComp->GetColorDepth( (LPTSTR)(LPCTSTR) chTermName, &bData, &dwStatus);                  
                    

                    if( FAILED( hr ) || bData == 1)
                    {
                        hr = WBEM_E_INVALID_OPERATION;
                        
                        break;
                    }                                        

                    bRet = pInParams->GetDWORD(m_szColorDepth, dwData);
                    
                    if ( !bRet || dwData > 3 )
                    {
                        hr = WBEM_E_INVALID_PARAMETER;
                        
                        break;
                    } 
                  

                    TCHAR tchRegPath[ MAX_PATH ] = WINSTATION_REG_NAME;

                    HKEY hKey = NULL;

                    lstrcat( tchRegPath, L"\\");

                    lstrcat( tchRegPath , chTermName );                
                    
                    hr = RegOpenKeyEx( HKEY_LOCAL_MACHINE ,
                             tchRegPath ,
                             0,
                             KEY_READ | KEY_WRITE,
                             &hKey );

                    if( SUCCEEDED( hr)  && hKey != NULL)
                    {

                        hr = RegSetValueEx( hKey ,
                                        TEXT("ColorDepth"),
                                        0 ,
                                        REG_DWORD,
                                        ( LPBYTE )&dwData ,
                                        sizeof(DWORD) );   
                        
                        RegCloseKey( hKey );
                    }
                    
                    if( SUCCEEDED( hr ) && pOutParams != NULL )
                    {
                        hr = StackObj.m_pCfgComp->ForceUpdate();

                        pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                        
                        TRC2((TB,"TSClientSetting@ExecMethod:  ColorDepth ret 0x%x\n" , hr  ));
                    } 
                    else
                    {
                        hr = WBEM_E_INVALID_METHOD_PARAMETERS;
                    }
                    
                }
                else
                {                    
                    hr = WBEM_E_INVALID_OPERATION;
                    
                    break;                    
                }
                
            }
        
            //  PropertyName is a string enumeration of the properties: 
            //  LPTPortMapping, COMPortMapping, AudioMapping ClipboardMapping and WindowsPrinterMapping.
            //  They are False or True according as if the Value is set to 0 or 1 respectively.
                

            //  uint32 SetClientProperty([In] string PropertyName, [In] boolean Value)
        
            else if( _wcsicmp( bstrMethodName, m_szSetClientProperty) == 0 )
            {
                hr = StackObj.m_pCfgComp->GetUserConfig((LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE);
            
                RegGetMachinePolicy(&m_gpPolicy);
            
                if( SUCCEEDED( hr ) && pUser != NULL && pOutParams != NULL)
                {
                    pInParams->GetCHString(m_szPropertyName, chData);                
                
                    if( chData.CompareNoCase(m_szLPTPortMapping) == 0 )
                    {
                        pInParams->Getbool(m_szValue, fValue);
                    
                        TRC2((TB,"m_gpPolicy.fPolicyDisableLPT ret 0x%x\n", m_gpPolicy.fPolicyDisableLPT ));
                    
                        if( m_gpPolicy.fPolicyDisableLPT == 0 )
                        {   
                            TRC2((TB,"Condition to update fPolicyDisableLPT satisfied" ));
                        
                            if( fValue != 0 && fValue != 1 )
                            {
                                hr = WBEM_E_INVALID_PARAMETER;
                            
                                break;
                            }
                        
                            pUser->fDisableLPT = fValue;
                        
                            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);                        
                        }
                        else
                        {
                            hr = WBEM_E_INVALID_OPERATION;

                            break;
                        }
                    
                    }
                    else if( chData.CompareNoCase(m_szCOMPortMapping) == 0 )
                    {
                        pInParams->Getbool(m_szValue, fValue);
                    
                        TRC2((TB,"m_gpPolicy.fPolicyDisableCcm ret 0x%x\n", m_gpPolicy.fPolicyDisableCcm ));
                    
                        if( (m_gpPolicy.fPolicyDisableCcm) == 0)
                        {
                            TRC2((TB,"Condition to update fPolicyDisableCcm satisfied" ));
                        
                            if( fValue != 0 && fValue != 1 )
                            {
                                hr = WBEM_E_INVALID_PARAMETER;
                            
                                break;
                            }
                        
                            pUser->fDisableCcm = fValue;
                        
                            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                        
                        }
                        else
                        {
                            hr = WBEM_E_INVALID_OPERATION;

                            break;
                        }
                    
                    }
                
                    else if( chData.CompareNoCase(m_szAudioMapping) == 0 )
                    {
                        pInParams->Getbool(m_szValue, fValue);

                        TRC2((TB,"m_gpPolicy.fPolicyDisableCam ret 0x%x\n", m_gpPolicy.fPolicyDisableCam ));                    
                    
                        if( (m_gpPolicy.fPolicyDisableCam) == 0)
                        {                        
                            if(fValue != 0 && fValue != 1 )
                            {
                                hr = WBEM_E_INVALID_PARAMETER;
                            
                                break;
                            }
                        
                            pUser->fDisableCam = fValue;
                        
                            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                        
                        }
                        else
                        {
                            hr = WBEM_E_INVALID_OPERATION;

                            break;
                        }
                    }
                
                    else if( chData.CompareNoCase(m_szClipboardMapping) == 0 )
                    {
                        pInParams->Getbool(m_szValue, fValue);
                    
                        TRC2((TB,"m_gpPolicy.fPolicyDisableClip ret 0x%x\n", m_gpPolicy.fPolicyDisableClip ));                    
                    
                        if( (m_gpPolicy.fPolicyDisableClip) == 0 )
                        {
                            TRC2((TB,"Condition to update fPolicyDisableClip satisfied" ));
                        
                            if( fValue != 0 && fValue != 1 )
                            {
                                hr = WBEM_E_INVALID_PARAMETER;
                            
                                break;
                            }
                        
                            pUser->fDisableClip = fValue;
                        
                            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                        
                        }
                        else
                        {
                            hr = WBEM_E_INVALID_OPERATION;

                            break;
                        }
                    }
                    else if( chData.CompareNoCase(m_szWindowsPrinterMapping) == 0 )
                    {
                        pInParams->Getbool(m_szValue, fValue);
                    
                        TRC2((TB,"m_gpPolicy.fPolicyDisableCpm ret 0x%x\n", m_gpPolicy.fPolicyDisableCpm ));
                    
                        if( (m_gpPolicy.fPolicyDisableCpm) == 0)
                        {
                            TRC2((TB,"Condition to update fPolicyDisableCpm satisfied" ));
                        
                            if( fValue != 0 && fValue != 1 )
                            {
                                hr = WBEM_E_INVALID_PARAMETER;
                            
                                break;
                            }
                        
                            pUser->fDisableCpm = fValue;
                        
                            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                        
                        }
                        else
                        {
                            hr = WBEM_E_INVALID_OPERATION;

                            break;
                        }
                    }
                    else if( chData.CompareNoCase(m_szDriveMapping) == 0 )
                    {
                        pInParams->Getbool(m_szValue, fValue);
                    
                        TRC2((TB,"m_gpPolicy.fPolicyDisableCdm ret 0x%x\n", m_gpPolicy.fPolicyDisableCdm ));
                    
                        if( (m_gpPolicy.fPolicyDisableCdm) == 0)
                        {
                            TRC2((TB,"Condition to update fPolicyDisableCdm satisfied" ));
                        
                            if( fValue != 0 && fValue != 1 )
                            {
                                hr = WBEM_E_INVALID_PARAMETER;
                            
                                break;
                            }
                        
                            pUser->fDisableCdm = fValue;
                        
                            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                        
                        }
                        else
                        {
                            hr = WBEM_E_INVALID_OPERATION;

                            break;
                        }
                    
                    }
                    else
                    {
                        hr = WBEM_E_INVALID_METHOD;
                        break;
                    }
                
                    hr = StackObj.m_pCfgComp->SetUserConfig( (LPTSTR)(LPCTSTR) chTermName, lSize, pUser , &dwStatus );

                    if( SUCCEEDED( hr ))
                    {
                        hr = StackObj.m_pCfgComp->ForceUpdate();
                    }                
                }
            }
        }
        
    }while (0);
    
    if( pUser != NULL )
    {
        CoTaskMemFree( pUser );        
    }

    return hr;   
}

//=-----------------
HRESULT CWin32_TSClientSetting::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    ULONGLONG ulRequiredProperties = 0;
    CHStringArray asNames;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}

    // Method 2
    Query.GetValuesForProp(m_szTerminalName, asNames);
    
    BOOL bGetAllInstances = asNames.GetSize() == 0;
    
    // Method 1
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szAudioMapping))
        ulRequiredProperties |= BIT_AUDIOMAPPING;
    
    if (Query.IsPropertyRequired(m_szClipboardMapping))
        ulRequiredProperties |= BIT_CLIPBOARDMAPPING;
    
    if (Query.IsPropertyRequired(m_szCOMPortMapping))
        ulRequiredProperties |= BIT_COMPORTMAPPING;
    
    if (Query.IsPropertyRequired(m_szConnectClientDrivesAtLogon))
        ulRequiredProperties |= BIT_CONNECTCLIENTDRIVESATLOGON;
    
    if (Query.IsPropertyRequired(m_szConnectionPolicy))
        ulRequiredProperties |= BIT_CONNECTIONPOLICY;
    
    if (Query.IsPropertyRequired(m_szConnectPrinterAtLogon))
        ulRequiredProperties |= BIT_CONNECTPRINTERATLOGON;
    
    if (Query.IsPropertyRequired(m_szDefaultToClientPrinter))
        ulRequiredProperties |= BIT_DEFAULTTOCLIENTPRINTER;
    
    if (Query.IsPropertyRequired(m_szDriveMapping))
        ulRequiredProperties |= BIT_DRIVEMAPPING;
    
    if (Query.IsPropertyRequired(m_szLPTPortMapping))
        ulRequiredProperties |= BIT_LPTPORTMAPPING;
    
    if (Query.IsPropertyRequired(m_szWindowsPrinterMapping))
        ulRequiredProperties |= BIT_WINDOWSPRINTERMAPPING;

    if (Query.IsPropertyRequired(m_szColorDepth))
        ulRequiredProperties |= BIT_COLORDEPTH;

    if (Query.IsPropertyRequired(m_szColorDepthPolicy))
        ulRequiredProperties |= BIT_COLORDEPTHPOLICY;
    
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for( ulNum = 0; ulNum < ulTerminals ; ulNum++)
        {   
            // Method 2 
            if( bGetAllInstances || IsInList(asNames, pWS[ulNum].Name))
            {
                
                CInstance* pInstance = CreateNewInstance(pMethodContext);
                
                if( pInstance == NULL)
                {
                    ERR((TB,"TSClientSetting@ExecQuery: CreateNewInstance failed" ));
                    
                    hr = WBEM_E_OUT_OF_MEMORY;

                    break;
                }
                
                pInstance->SetCHString(m_szTerminalName, CHString(pWS[ulNum].Name));

                hr = LoadPropertyValues( pInstance, ulRequiredProperties, &pWS[ ulNum ] );
                
                if( SUCCEEDED( hr ) )
                {
                    hr = pInstance->Commit();
                }
                
                pInstance->Release();
            }
        }
    }    
    	
    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);        
    }

    return hr;    
}




//=----------------------Win32_TSNetworkAdapterSetting---------------------


CWin32_TSNetworkAdapterSetting::CWin32_TSNetworkAdapterSetting (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
Provider( lpwszName, lpwszNameSpace )
{    
    if( g_hInstance != NULL)
    {
        TRC2((TB, "CWin32_TSNetworkAdapterSetting_ctor"));
        
        _tcscpy(m_szNetworkAdapterID, _T("NetworkAdapterID"));

        _tcscpy(m_szNetworkAdapterName, _T("NetworkAdapterName"));

        _tcscpy(m_szMaximumConnections, _T("MaximumConnections"));

        _tcscpy(m_szSelectNetworkAdapterID, _T("SelectNetworkAdapterID"));

        _tcscpy(m_szSelectAllNetworkAdapters, _T("SelectAllNetworkAdapters"));

        _tcscpy(m_szTerminalName, _T("TerminalName"));


    }
    
    RegGetMachinePolicy(&m_gpPolicy);
}
//=--------------------
CWin32_TSNetworkAdapterSetting::~CWin32_TSNetworkAdapterSetting ()
{
    
}

//=---------------
BOOL CWin32_TSNetworkAdapterSetting::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
    DWORD dwSize = asArray.GetSize();
    
    for (DWORD x=0; x < dwSize; x++)
    {
        if (asArray[x].CompareNoCase(pszString) == 0)
        {
            return TRUE;
        }
    }
    
    return FALSE;
}


//=--------------------
HRESULT CWin32_TSNetworkAdapterSetting::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{ 	
    int i = 0;
    HRESULT hr = WBEM_E_NOT_FOUND;
    DWORD dwData = 0;
    ULONG ulSize = 0;
    ULONG ulNAdapters =0;
    ULONGLONG ulRequiredProperties = 0;
    LONG  lSize ;
    PWS pWS = NULL;
    TCHAR tch = ';';		    
    TCHAR tchGuid[ GUID_LENGTH ];
    CHString chTermName;
    CHString chGuid;
    CHString chAllGuids;
    CHString chName;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}

    if( pInstance == NULL )
    {
        ERR((TB,"TSNetworkAdapterSetting@GetObject: invalid pointer" ));
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    pInstance->GetCHString(m_szTerminalName, chTermName);
    
    if(chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if(chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }

    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szNetworkAdapterID))
        ulRequiredProperties |= BIT_NETWORKADAPTERID;
    
    if (Query.IsPropertyRequired(m_szMaximumConnections))
        ulRequiredProperties |= BIT_MAXIMUMCONNECTIONS;
    
    if ( pInstance != NULL )
    {
        hr = StackObj.m_pCfgComp->GetWSInfo((LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS);
        
        if( SUCCEEDED( hr ) && pWS != NULL )
        {
            hr = LoadPropertyValues(pInstance, ulRequiredProperties, pWS );            
        }

        /*
        hr = pCfgComp->GetWSInfo((LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS);
        
        if ( SUCCEEDED (hr) )
        {
            hr = pCfgComp->GetUserConfig((LPTSTR)(LPCTSTR) chTermName, &lSize, &pUser, TRUE);
            
            if ( SUCCEEDED (hr) && pWS!= NULL && pUser != NULL )
            {            
                
                pInstance->SetDWORD(m_szMaximumConnections, pWS->uMaxInstanceCount);
                
                hr = pCfgComp->GetLanAdapterList2(pWS->pdName, &ulNAdapters , &pGuidtbl );
                
                chAllGuids.Empty();
                chGuid.Empty();
                
                StringFromGUID2 (( pGuidtbl )[ pWS->LanAdapter ].guidNIC, tchGuid, GUID_LENGTH);      
                chGuid.Format (L"%ws", tchGuid);
                
                
                hr = pInstance->SetCHString(m_szNetworkAdapterID, chGuid);     
                
                chAllGuids.Empty();
                chGuid.Empty();
                
                chName = ( pGuidtbl )[ pWS->LanAdapter ].DispName;   
                
                hr = pInstance->SetCHString(m_szNetworkAdapterName, chName); 
                
            }
            else
            {
                hr = WBEM_E_INVALID_OBJECT;
            }
        }
        */
        
    }
    
    /*
    if ( pUser != NULL )
    {
        CoTaskMemFree(pUser);
        
    }
    */

    if ( pWS != NULL )
    {
        CoTaskMemFree(pWS);        
    }

    return hr;
    
}

//=--------------------
/*****************************************************************************
*
*  FUNCTION    :    CWin32_TSNetworkAdapterSetting::EnumerateInstances
*
*  DESCRIPTION :    Returns all the instances of this class.
*
*  INPUTS      :    A pointer to the MethodContext for communication with WinMgmt.
*                   A long that contains the flags described in 
*                   IWbemServices::CreateInstanceEnumAsync.  Note that the following
*                   flags are handled by (and filtered out by) WinMgmt:
*                   WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY, 
*                   WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
*  RETURNS     :    WBEM_S_NO_ERROR if successful
*
*  COMMENTS    :    All instances on the machine are returned here and
*                   all properties that this class knows how to populate must 
*                   be filled in.  If there are no instances, return 
*                   WBEM_S_NO_ERROR.  
*****************************************************************************/

HRESULT CWin32_TSNetworkAdapterSetting::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
    
    HRESULT hr = WBEM_S_NO_ERROR;    
    DWORD dwData = 0;
    ULONG  ulTerminals = 0;
    ULONG  ulSize = 0; 
    LONG  lSize = 0;
    ULONG ulNum = 0;
    PWS  pWS = NULL;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
        
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {   
            CInstance* pInstance = CreateNewInstance(pMethodContext);
            
            if( pInstance == NULL)
            {
                ERR((TB,"TSNetworkAdapterSetting@EnumerateInstances: CreateNewInstance failed" ));               
                
                hr = WBEM_E_OUT_OF_MEMORY;
                
                break;
            }
            TRC2((TB,"TSNetworkAdapterSetting@EnumerateInstances: GetWinstationList ret 0x%x\n" , hr ));

            if( _tcsicmp( pWS[ulNum].pdName, L"Console") != 0 )
            {

                hr = LoadPropertyValues(pInstance, BIT_ALL_PROP, &pWS[ulNum] );
            
                if( SUCCEEDED( hr ) )
                {
                    hr = pInstance->Commit();
                }
                pInstance->Release( );
            }
        }
        
    }

    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }
    
    return hr;
}
//=--------------------

HRESULT CWin32_TSNetworkAdapterSetting::LoadPropertyValues( CInstance *pInstance, ULONGLONG ulRequiredProperties, PWS pWS)
{
    
    HRESULT hr = WBEM_S_NO_ERROR; 
    PUSERCONFIGW pUser = NULL;
    LONG lSize ;
    ULONG ulNAdapters =0;
    DWORD dwData = 0;    
    DWORD dwStatus = 0;
    int i = 0;
    TCHAR tch = ';';		    
    TCHAR tchGuid[ GUID_LENGTH ];
    PGUIDTBL pGuidtbl = NULL;
    CHString chGuid;
    CHString chAllGuids;
    CHString chName;    
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL )
    {
        ERR((TB,"TSNetworkAdapterSetting@LoadPropertyValues: invalid pointer"));
        
        return WBEM_E_ILLEGAL_NULL;       
    }
    
    
    if( pInstance != NULL && pWS != NULL )
    {
        if( ulRequiredProperties & BIT_TERMINALNAME)
        {
            pInstance->SetCharSplat(m_szTerminalName, pWS->Name);        
        }
        
        hr = StackObj.m_pCfgComp->GetUserConfig(pWS->Name, &lSize, &pUser, TRUE);
        
        TRC2((TB,"TSNetworkAdapterSetting@LoadPropertyValues: GetUserConfig ret 0x%x\n" , hr));
        
        if( SUCCEEDED( hr ) && pUser != NULL )
        {            
            if( ulRequiredProperties & BIT_NETWORKADAPTERID)
            {
                
                pInstance->SetDWORD(m_szNetworkAdapterID, pWS->LanAdapter);
                
            }
            TRC2((TB,"TSNetworkAdapterSetting@LoadPropertyValues: NetworkAdapterID"));      
            
            if( ulRequiredProperties & BIT_MAXIMUMCONNECTIONS)
            {
                RegGetMachinePolicy(&m_gpPolicy);

                if( m_gpPolicy.fPolicyMaxInstanceCount != 0 )
                {
                    pInstance->SetDWORD(m_szMaximumConnections, m_gpPolicy.MaxInstanceCount);                   
                }
                else
                {                
                    pInstance->SetDWORD(m_szMaximumConnections, pWS->uMaxInstanceCount);
                  
                }
            }
            TRC2((TB,"TSNetworkAdapterSetting@LoadPropertyValues: MaxConnections")); 
                        
            
            hr = StackObj.m_pCfgComp->GetLanAdapterList2(pWS->pdName, &ulNAdapters , &pGuidtbl ); 
            
            chAllGuids.Empty();
            chGuid.Empty();
            
            if( pWS->LanAdapter != ((ULONG)-1))
            {
                StringFromGUID2 (( pGuidtbl )[ pWS->LanAdapter ].guidNIC, tchGuid, ARRAYSIZE(tchGuid));            

                chGuid.Format (L"%s", tchGuid);
         
                pInstance->SetCharSplat(m_szNetworkAdapterID, tchGuid);     
            
                chName = ( pGuidtbl )[ pWS->LanAdapter ].DispName;                  
            
                pInstance->SetCHString(m_szNetworkAdapterName, chName);
            }            
            else
            {
                pInstance->SetCHString(m_szNetworkAdapterName, L"");
            }                        
        }          
    }
    
    if( pUser != NULL )
    {
        CoTaskMemFree(pUser);
    }

    if( pGuidtbl != NULL )
    {
        CoTaskMemFree(pGuidtbl);
    }
    
    return S_OK;
    
}
//=--------------------

HRESULT CWin32_TSNetworkAdapterSetting::PutInstance ( const CInstance &Instance, long lFlags)
{	
    HRESULT hr= WBEM_S_NO_ERROR;
    CHString chTermName ;
    DWORD dwData = 0;
    LONG lSize;
    DWORD dwStatus = 0;
    PWS  pWS = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}    
    
    Instance.GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    hr = StackObj.m_pCfgComp->GetWSInfo((LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS);
    
    RegGetMachinePolicy( &m_gpPolicy );
    
    do
    {
        if( SUCCEEDED (hr) && pWS != NULL )
        {
            Instance.GetDWORD(m_szMaximumConnections, dwData);

            TRC2((TB,"m_gpPolicy.fPolicyMaxInstanceCount ret 0x%x\n", m_gpPolicy.fPolicyMaxInstanceCount));
            
            if( m_gpPolicy.fPolicyMaxInstanceCount == 0 )
            { 
                TRC2((TB,"m_gpPolicy.fPolicyMaxInstanceCount satisfied"));
                

                pWS->uMaxInstanceCount = dwData;
                
                hr = StackObj.m_pCfgComp->UpDateWS( pWS, BIT_ALL_PROPS , &dwStatus, TRUE ); 
            }
            else
            {
                hr = WBEM_E_INVALID_OPERATION;

                break;
            }          
        }
        
        else
        {
            TRC2((TB,"TSNetworkAdapterSetting@PutInstance ret 0x%x\n" , hr));  
            
            CHString sRelPath;
            
            Instance.GetCHString(L"__RelPath", sRelPath);
            CInstance *pErrorInstance = NULL;
                        
            hr = CWbemProviderGlue::GetInstanceByPath(pErrorClass, &pErrorInstance );
            
            if( SUCCEEDED( hr ) )
            {
                TRC2((TB,"TSNetworkAdapterSetting@PutInstance ret 0x%x\n" , hr));

                if( pErrorInstance != NULL )
                {
                    LoadString( g_hInstance , IDS_ERR_PUTTSNCONFIG, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                    pErrorInstance->SetWCHARSplat(L"Description", tchErrorMessage);
                    
                    LoadString( g_hInstance , IDS_ERR_PUTINSTANCE, tchErrorMessage, SIZE_OF_BUFFER(tchErrorMessage) );
                    pErrorInstance->SetWCHARSplat(L"Operation", tchErrorMessage);
                    
                    pErrorInstance->SetCHString(L"ParameterInfo", sRelPath);
                    pErrorInstance->SetWCHARSplat(L"ProviderName", PROVIDER_NAME_Win32_WIN32_TSNETWORKADAPTERSETTING_Prov);
                    pErrorInstance->SetDWORD(L"StatusCode", WBEM_E_INVALID_PARAMETER);
                    
                    
                    IWbemClassObject *pObj = pErrorInstance->GetClassObjectInterface();
                    if( pObj != NULL )
                    {
                        
                        MethodContext *pMethodContext = Instance.GetMethodContext();  
                        
                        
                        if( pMethodContext != NULL )
                        {
                            pMethodContext->SetStatusObject(pObj);
                        }
                        
                        pObj->Release();
                    }
                    pErrorInstance->Release();
                }
                
            }
        }
    }while (0);

    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
    }

    return hr;
} 

//=--------------------

HRESULT CWin32_TSNetworkAdapterSetting::ExecMethod ( const CInstance& Inst,
                                                           const BSTR bstrMethodName,
                                                           CInstance *pInParams,
                                                           CInstance *pOutParams,
                                                           long lFlags)
                                                           
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    CHString chTermName;
    PWS pWS= NULL;
    PWS pWSList= NULL;
    CRegistry oRegObject;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    Inst.GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
   
    
    // Selects all the LanAdapters on the machine.
                              
    // uint32 SelectAllNetworkAdapters();
    
    do
    {
        if( _wcsicmp(bstrMethodName, m_szSelectAllNetworkAdapters) == 0 )
        {
            
            ULONG ulTerminals = 0;
            ULONG ulNum = 0;
            LONG lNum = 0;
            ULONG ulSize = 0;
            DWORD dwStatus = 0;
            DWORD dwData = 0;
            LONG lSize;
            ULONG ulNumAdapters;
            CHStringArray a_chNetworkAdapterIDs;
            TCHAR tchGuid[ GUID_LENGTH ];
            
            hr = StackObj.m_pCfgComp->GetWSInfo((LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS);
            
            if( SUCCEEDED (hr) )
            {
                
                hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWSList);
                
                if( SUCCEEDED( hr ) && pWSList != NULL )
                {   
                    for( ulNum = 0; ulNum < ulTerminals ; ulNum++ )
                    {  
                        if( pWSList[ulNum].LanAdapter == 0 )
                        {
                            hr = WBEM_E_ALREADY_EXISTS;
                            
                            goto Cleanup;
                        }
                    }  
                    
                    hr = StackObj.m_pCfgComp->GetWSInfo( (LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS );
                    
                    pWS->LanAdapter = 0;
                    
                    hr = StackObj.m_pCfgComp->UpDateWS( pWS, BIT_ALL_PROPS , &dwStatus, TRUE );
                }
                if( pOutParams != NULL && SUCCEEDED( hr ))
                {
                    TRC2((TB,"TSNetworkAdapterSetting@ExecMethod: GetNetworkAdapterIDs ret 0x%x\n" , hr));                    
                    
                    pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                }
            }                
            
            else
            {
                hr = WBEM_E_INVALID_OPERATION;
            }
        }
        
        
        // Specify the NetworkAdapterID to set.

        // uint32 SelectNetworkAdapterID([In] string NetworkAdapterID);
        
        else if( _wcsicmp(bstrMethodName, m_szSelectNetworkAdapterID) == 0 )
        {
            
            DWORD dwStatus = 0;
            DWORD dwData = 0;
            LONG lSize;
            PGUIDTBL pGuidtbl = NULL;
            BOOL bUniq;
            ULONG ulAdapters = 0;
            TCHAR tchRootKey[ MAX_PATH ] = {0};
            TCHAR tchGuid[ GUID_LENGTH ];
            TCHAR tchSelectGuid[ GUID_LENGTH ];
            HKEY hKey;    
            CHString chGuid;
            
            CHString chGUIDName;

            if(pInParams == NULL)
            {
                hr = WBEM_E_INVALID_METHOD_PARAMETERS;

                break;
            }
            
            pInParams->GetCHString(m_szNetworkAdapterID, chGUIDName);
            
            if( chGUIDName.IsEmpty() != 0 )
            {
                hr = WBEM_E_INVALID_METHOD_PARAMETERS;
                
                break;
            }

            if( chGUIDName.GetLength() > GUID_LENGTH )
            {
                hr = WBEM_E_VALUE_OUT_OF_RANGE;
                
                break;
            }
            
            hr = StackObj.m_pCfgComp->GetWSInfo((LPTSTR)(LPCTSTR) chTermName, &lSize, &pWS);
            
            if( SUCCEEDED( hr ) && pWS != NULL)
            {
                hr = StackObj.m_pCfgComp->GetLanAdapterList2(pWS->pdName, &ulAdapters , &pGuidtbl );
                
                if( SUCCEEDED( hr ) && pGuidtbl != NULL)
                {
                    
                    for( int i = 0 ; i < ulAdapters ; i++)
                    {
                        StringFromGUID2( ( pGuidtbl )[ i ].guidNIC , tchGuid , ARRAYSIZE( tchGuid ) );
                        
                        if( lstrcmpi( tchGuid, (LPCTSTR) chGUIDName) != 0 )
                        {
                            continue;  
                        }
                        
                        hr = StackObj.m_pCfgComp->IsNetWorkConnectionUnique(pWS->wdName, pWS->pdName, i, &bUniq);
                        
                        if( SUCCEEDED( hr ) && bUniq == TRUE )
                        {
                            pWS->LanAdapter = i;
                            
                            hr = StackObj.m_pCfgComp->UpDateWS( pWS, BIT_ALL_PROPS , &dwStatus, TRUE );
                            
                            if( SUCCEEDED( hr ))
                            {                                
                                if( SUCCEEDED( hr ) && pOutParams != NULL)
                                {
                                    pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);

                                    TRC2((TB,"TSNetworkAdapterSetting@ExecMethod: SelectNetworkAdapterID ret 0x%x\n" , hr));
                                } 
                                
                            }
                        }
                        else
                        {                           
                            hr = WBEM_E_INVALID_METHOD_PARAMETERS;                                                       
                        }                        
                    }                    
                }
            }
            
            if ( pGuidtbl != NULL )
            {
                CoTaskMemFree(pGuidtbl);
                
            }
            TRC2((TB,"TSNetworkAdapterSetting@ExecMethod: SelectNetworkAdapterID ret 0x%x\n" , hr));
        }
        
        
        else
        {
            hr = WBEM_E_INVALID_METHOD;

            break;
        }
        
    }while (0);
    
Cleanup:
    
    if( pWS != NULL )
    {
        CoTaskMemFree( pWS );        
    }

    if( pWSList != NULL )
    {
        CoTaskMemFree( pWSList );
    }

    return hr;
}

//=--------------------

HRESULT CWin32_TSNetworkAdapterSetting::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    ULONGLONG ulRequiredProperties = 0;
    CHStringArray asNames;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    // Method 2
    Query.GetValuesForProp(m_szTerminalName, asNames);
    
    BOOL bGetAllInstances = asNames.GetSize() == 0;
    
    // Method 1
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szNetworkAdapterID))
        ulRequiredProperties |= BIT_NETWORKADAPTERID;
    
    if (Query.IsPropertyRequired(m_szMaximumConnections))
        ulRequiredProperties |= BIT_MAXIMUMCONNECTIONS;
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++ )
        {    
            // Method 2
            if( bGetAllInstances || IsInList(asNames, pWS[ulNum].Name) )
            {
                CInstancePtr pInstance (NULL);

                pInstance.Attach( CreateNewInstance( pMethodContext ) );
                
                if( pInstance == NULL)
                {
                    ERR((TB,"TSNetworkAdapterSetting@ExecQuery: CreateNewInstance failed"));                    
                    
                    hr = WBEM_E_OUT_OF_MEMORY;
                    
                    break;
                }
                
                pInstance->SetCHString(m_szTerminalName, CHString(pWS[ulNum].Name));

                hr = LoadPropertyValues( pInstance, ulRequiredProperties, &pWS[ ulNum ] );
                
                if( SUCCEEDED( hr ) )
                {
                    hr = pInstance->Commit();
                }                
            }
        }
    }
    
    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }

    return hr;
    
}



//=----------------------Win32_TSPermissionsSettingsConfig---------------------


CWin32_TSPermissionsSetting::CWin32_TSPermissionsSetting (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
Provider( lpwszName, lpwszNameSpace )
{  
    if( g_hInstance != NULL )
    {

        TRC2((TB, "CWin32_TSPermissionsSetting_ctor"));

        _tcscpy(m_szPermissionPreSet, _T("PermissionPreSet"));

        _tcscpy(m_szPermissionMask, _T("PermissionMask"));

        _tcscpy(m_szAccountName, _T("AccountName"));

        _tcscpy(m_szAddAccount, _T("AddAccount"));

        _tcscpy(m_szRestoreDefaults, _T("RestoreDefaults"));

        _tcscpy(m_szTerminalName, _T("TerminalName"));

    }
}
//=--------------------
CWin32_TSPermissionsSetting::~CWin32_TSPermissionsSetting ()
{
    
}


//=---------------

BOOL CWin32_TSPermissionsSetting::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
    DWORD dwSize = asArray.GetSize();
    
    for( DWORD x=0; x < dwSize; x++ )
    {
        if( asArray[x].CompareNoCase(pszString) == 0 )
        {
            return TRUE;
        }
    }
    
    return FALSE;
}
//=---------------------

HRESULT CWin32_TSPermissionsSetting::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;   
    LONG lSize;
    ULONGLONG ulRequiredProperties = 0;
    PWS  pWS = NULL;
    CHString chTermName;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}

    TRC2((TB,"TSCFGWMI!CWin32_TSPermissionsSetting_GetObject"));
    
    if( pInstance == NULL )
    {
        ERR((TB,"TSPermissionsSetting@GetObject: invalid pointer" ));
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    pInstance->GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH)
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;

    hr = StackObj.m_pCfgComp->GetWSInfo( ( LPTSTR )( LPCTSTR )chTermName, &lSize, &pWS);
    
    if( SUCCEEDED (hr) && pWS != NULL )        
    {
        hr = LoadPropertyValues(pInstance, ulRequiredProperties, pWS);        
    }
    else
    {
        hr = WBEM_E_INVALID_OBJECT;
    }
    
    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
    }	

    return hr ;


	/*

    HRESULT hr = WBEM_E_NOT_FOUND;
    
    // get the object for the Win32_Terminal
    CHString chsTerminal;
    CInstancePtr pTerminal(NULL);
    
    if( pInstance != NULL )
    {
        pInstance->GetCHString(L"Element", chsTerminal);

        MethodContext* pMethodContext = pInstance->GetMethodContext();    
        
        hr = CWbemProviderGlue::GetInstanceByPath(chsTerminal, &pTerminal, pMethodContext);
        TRC2((TB,"TSPermissionsSetting@GetObject: GetInstanceByPath ret 0x%x\n" , hr ));       
        
        do
        {
            if( SUCCEEDED( hr ) && pTerminal != NULL)
            {
                // Got the account.  Now, match it to the GUID.
                // first, generate a relpath with which to compare.
                CHString chTSAccountSettingInstance;
                CHString chTermName;
                DWORD dwIndex = 0;
                pTerminal->GetCHString(m_szTerminalName, chTermName); 
               
                // create a relpath for the sid
                CHString chsTSAccountSettingPath;
                chsTSAccountSettingPath.Format(L"\\\\%s\\%s:%s.%s=\"%s\"", (LPCTSTR)GetLocalComputerName(), L"root\\cimv2", L"Win32_TSAccount", m_szTerminalName, (LPCTSTR)chTermName);
        
                // get the SID path from the instance
              //  pInstance->SetCHString(L"Setting", chsTSAccountSettingPath);
                pInstance->SetCHString(L"Setting", chTSAccountSettingInstance);

                pInstance->SetCHString(m_szTerminalName, chTermName);         
            }
        }while (0);
    }
    return(hr);
	*/
       
}
//=--------------------
/*****************************************************************************
*
*  FUNCTION    :    CWin32_TSPermissionsSetting::EnumerateInstances
*
*  DESCRIPTION :    Returns all the instances of this class.
*
*  INPUTS      :    A pointer to the MethodContext for communication with WinMgmt.
*                   A long that contains the flags described in 
*                   IWbemServices::CreateInstanceEnumAsync.  Note that the following
*                   flags are handled by (and filtered out by) WinMgmt:
*                   WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY, 
*                   WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
*  RETURNS     :    WBEM_S_NO_ERROR if successful
*
*  COMMENTS    :    All instances on the machine are returned here and
*                   all properties that this class knows how to populate must 
*                   be filled in.  If there are no instances, return 
*                   WBEM_S_NO_ERROR.  
*****************************************************************************/

HRESULT CWin32_TSPermissionsSetting::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
	
	HRESULT hr = WBEM_S_NO_ERROR;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
   
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    TRC2((TB,"TSPermissionsSetting@EnumerateInstances: GetWinstationList ret 0x%x" , hr )); 
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {   
            CInstance* pInstance = CreateNewInstance(pMethodContext);
            
            if( pInstance == NULL)
            {
                ERR((TB,"TSPermissionsSetting@EnumerateInstances: CreateNewInstance failed"));                
                
                hr = WBEM_E_OUT_OF_MEMORY;
                
                break;
            }              
            
            hr = LoadPropertyValues( pInstance, BIT_ALL_PROPERTIES, &pWS[ ulNum ] );
            
            if (SUCCEEDED( hr ) ) 
            {
                hr = pInstance->Commit();       
            }            
            pInstance->Release( );
        }
    }

    if( pWS != NULL)
    {
        CoTaskMemFree(pWS);
    }

    return hr;
/*
    HRESULT hr = WBEM_E_FAILED;
    
    CInstancePtr pInstance;
    
    // Collections
    TRefPointerCollection<CInstance>	TerminalList;
    
    // Perform queries
    //================
    
    if( SUCCEEDED( hr = CWbemProviderGlue::GetInstancesByQuery(L"select TerminalName from Win32_Terminal",
        &TerminalList, pMethodContext) ) )
    {
        TRC2((TB,"TSPermissionsSetting@GetObject: EnumerateInstances: GetInstancesByQuery ret 0x%x\n" , hr ));
        
        REFPTRCOLLECTION_POSITION	pos;
        
        CInstancePtr pTerminal(NULL);
        
        if( TerminalList.BeginEnum( pos ) )
        {
            
            for( pTerminal.Attach(TerminalList.GetNext( pos ) ) ;
            SUCCEEDED( hr ) && ( pTerminal != NULL ) ;
            pTerminal.Attach(TerminalList.GetNext( pos ) ) )
            {
                
                CHString chTermName;
                pTerminal->GetCHString(m_szTerminalName, chTermName);
                
                // No maximum limit check
                
                if( chTermName.IsEmpty() != 0)
                {
                    return WBEM_E_ILLEGAL_NULL;
                }        
                
                pInstance.Attach( CreateNewInstance(pMethodContext) );
                
                if( NULL != pInstance )
                {
                    // set relpath to Terminal
                    CHString chsTerminalPath;
                    CHString chsFullTerminalPath;
                    pTerminal->GetCHString(L"__RELPATH", chsTerminalPath);
                    chsFullTerminalPath.Format(L"\\\\%s\\%s:%s", (LPCTSTR)GetLocalComputerName(), L"root\\cimv2", (LPCTSTR)chsTerminalPath);
                    pInstance->SetCHString(L"Element", chsFullTerminalPath);
                    pInstance->SetCHString(m_szTerminalName, chTermName);
                    
                    // create a relpath for the TSPermissionsSetting
                    CHString chsTSAccountSettingPath;
                    chsTSAccountSettingPath.Format(L"\\\\%s\\%s:%s.%s=\"%s\"", (LPCTSTR)GetLocalComputerName(), L"root\\cimv2", L"Win32_TSAccount", m_szTerminalName, (LPCTSTR)chTermName);
                    
                    // and set the reference in the association
                    pInstance->SetCHString(L"Setting", chsTSAccountSettingPath);
                    // to that relpath.                                       
                    
                    hr = pInstance->Commit();
                }	// end if
                
            } // pTerminal not null        
            TerminalList.EndEnum();        
        }	// IF BeginEnum        
    }
    return( hr );
    */
}
//=--------------------



HRESULT CWin32_TSPermissionsSetting::LoadPropertyValues( CInstance *pInstance, ULONGLONG ulRequiredProperties, PWS pWS)
{	
    
    if( pInstance == NULL )
    {   
        ERR((TB,"TSPermissionsSetting@LoadPropertyValues: invalid pointer" ));
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    if( ulRequiredProperties & BIT_TERMINALNAME )
    {                
        pInstance->SetCharSplat(m_szTerminalName, pWS->Name);
        
    } 
	
    return S_OK;
}

//=--------------------

HRESULT CWin32_TSPermissionsSetting::PutInstance ( const CInstance &Instance, long lFlags)
{
    return WBEM_E_PROVIDER_NOT_CAPABLE;
    
} 

//=--------------------


HRESULT CWin32_TSPermissionsSetting::ExecMethod ( const CInstance& Inst,
                                                        const BSTR bstrMethodName,
                                                        CInstance *pInParams,
                                                        CInstance *pOutParams,
                                                        long lFlags)
                                                        
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    CHString chTermName;
    CHString chAccountName;
    DWORD dwPermissionPreSet = 0;
    DWORD dwMask = 0;
    DWORD dwPermissionDenyMask = 0;
    BOOL fAudit = FALSE;
    DWORD dwStatus = 0;	
    IUserSecurity *pUserSecurity = NULL;

	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}        
    
    Inst.GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    hr = StackObj.m_pCfgComp->QueryInterface( IID_IUserSecurity , ( LPVOID * )&pUserSecurity );
    
    if( SUCCEEDED( hr ) && pUserSecurity != NULL )
    {       
        // Adds a new user or group to the existing set with 
        // the set of permissions defined.
        // uint32 Add([In] string AccountName, [In] uint32 PermissionPreSet)
        
        do
        {            
            if( _wcsicmp( bstrMethodName, m_szAddAccount ) == 0 )
            {
                if(pInParams == NULL)
                {
                    hr = WBEM_E_INVALID_METHOD_PARAMETERS;

                    break;
                }

                bool bRet;

                chAccountName.Empty();
                
                pInParams->GetCHString(m_szAccountName, chAccountName);
                                
                if( chAccountName.GetLength() > NASIUSERNAME_LENGTH )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
                    
                    break;
                }
                
                if( chAccountName.IsEmpty() != 0)
                {
                    hr = WBEM_E_ILLEGAL_NULL;
                    
                    break;
                }
                
                bRet = pInParams->GetDWORD(m_szPermissionPreSet, dwPermissionPreSet);
                
                
                if( !bRet || dwPermissionPreSet > 3 )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
                    
                    break;
                }
                
                if( dwPermissionPreSet == 0 )
                {
                    dwMask = WINSTATION_GUEST_ACCESS;
                }
                
                else if( dwPermissionPreSet == 1 )
                {
                    dwMask = WINSTATION_USER_ACCESS;
                }
                
                else if( dwPermissionPreSet == 2 )
                {
                    dwMask = WINSTATION_ALL_ACCESS;
                }
                
                hr  = pUserSecurity->ModifyUserAccess( (LPTSTR) (LPCTSTR)chTermName,  // winsta to modify security
                    (LPTSTR) (LPCTSTR) chAccountName,         // group or user
                    dwMask,         // winsta permission
                    FALSE ,
                    TRUE  ,              // t - allow permission f - deny perm 
                    FALSE ,              // t - new object f - donot change previous permission                                
                    FALSE ,           // t - enable auditing f - no auditing
                    &dwStatus ); 
                
                TRC2((TB,"TSPermissionsSetting@ExecMethod: Add ret 0x%x\n" , dwStatus ));                
                
                if( SUCCEEDED (dwStatus) && pOutParams != NULL )
                {
                    pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                    
                } 
                
                else
                {
                    hr = WBEM_E_INVALID_METHOD_PARAMETERS;
                    
                    TRC2((TB,"TSPermissionsSetting@ExecMethod: Modify ret 0x%x\n" , hr));
                    
                    break;
                }
                
            }

            
            
            // Deletes the permission from the specified user or group.
            // uint32 RestoreDefaults();
            
                
            else if( _wcsicmp(bstrMethodName, m_szRestoreDefaults) == 0 )
            {
    
                dwStatus = 0;
                DWORD dwData = 0;
                LONG lSize;
                ULONG ulOffset = 0;
                DWORD cbItems = 0;
    //            PUSERPERMLIST pUserList = NULL;
                PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
              
                hr = StackObj.m_pCfgComp->GetDefaultSecurityDescriptor( &lSize, &pSecurityDescriptor  );
    
                if( SUCCEEDED( hr ) && pSecurityDescriptor != NULL)
                {
        
                    hr = StackObj.m_pCfgComp->SetSecurityDescriptor((LPTSTR) (LPCTSTR)chTermName, (DWORD) lSize, pSecurityDescriptor);
        
                    if( SUCCEEDED( hr ))
                    {
                        hr = StackObj.m_pCfgComp->ForceUpdate();
            
                        if( SUCCEEDED( hr ) && pOutParams != NULL)
                        {   
                            pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                
                            TRC2((TB,"TSPermissionsSetting@ExecMethod: RestoreDefaults ret 0x%x\n" , hr));                   
                        }
                    }
                }                
                else
                {
                    hr = WBEM_E_INVALID_METHOD_PARAMETERS;
          
                }

                if( pSecurityDescriptor != NULL )
                {
                    CoTaskMemFree( pSecurityDescriptor );
                }
            }                        
            
            else
            {
                hr = WBEM_E_INVALID_METHOD;

                break;
            }
            
            
        }while(0);
    }

    if( pUserSecurity != NULL)
    {
        pUserSecurity->Release();
    }

    return hr;
    
}

//=-----------------

HRESULT CWin32_TSPermissionsSetting::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{	
    HRESULT hr = WBEM_E_NOT_FOUND;
    ULONGLONG ulRequiredProperties = 0;
    CHStringArray asNames;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    PWS pWS = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}

    // Method 2
    Query.GetValuesForProp(m_szTerminalName, asNames);
    
    BOOL bGetAllInstances = asNames.GetSize() == 0;
    
    // Method 1
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for ( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {  
            
            // Method 2 - Check if the query CAN be processed by 'name'. If yes, return only those names.
            
            if (bGetAllInstances || IsInList(asNames, pWS[ulNum].Name))
            {
                CInstance* pInstance = CreateNewInstance( pMethodContext );
                
                if( pInstance == NULL)
                {
                    TRC2((TB,"TSPermissionsSetting@ExecQuery: CreateNewInstance failed"));
                    
                    hr = WBEM_E_OUT_OF_MEMORY;
                    
                    break;
                }
                
                pInstance->SetCHString(m_szTerminalName, CHString(pWS[ulNum].Name));

                hr = LoadPropertyValues( pInstance, ulRequiredProperties, &pWS[ ulNum ] );
                
                if( SUCCEEDED( hr ) )
                {
                    hr = pInstance->Commit();
                }
                
                pInstance->Release();
            }
        }
    }

    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
    }

    return hr;
    
}

//=------------------------------

/*
CWin32_TSNetworkAdapterListSetting::CWin32_TSNetworkAdapterListSetting ( const CHString& setName, LPCTSTR pszNameSpace  )
: Provider (setName,pszNameSpace)
{
    

    if ( g_hInstance != NULL)
    {

        TRC2((TB, "CWin32_TSNetworkAdapterListSetting_ctor"));

        LoadString( g_hInstance , IDS_DEVICEID, m_szDeviceID, SIZE_OF_BUFFER(m_szDeviceID)-1 );   

        LoadString( g_hInstance , IDS_INDEX, m_szIndex, SIZE_OF_BUFFER(m_szIndex)-1 );

        LoadString( g_hInstance , IDS_DESCRIPTION, m_szDescription, SIZE_OF_BUFFER(m_szDescription)-1 );
        
        LoadString( g_hInstance , IDS_NETWORKADAPTERID, m_szNetworkAdapterID, SIZE_OF_BUFFER(m_szNetworkAdapterID)-1 );
        
        LoadString( g_hInstance , IDS_TERMINALNAME, m_szTerminalName, SIZE_OF_BUFFER(m_szTerminalName)-1 );

    }
}

CWin32_TSNetworkAdapterListSetting::~CWin32_TSNetworkAdapterListSetting ()
{
}



HRESULT CWin32_TSNetworkAdapterListSetting::EnumerateInstances (MethodContext*  pMethodContext, long lFlags)
{
    
    HRESULT hr = WBEM_E_FAILED;
    
    CInstancePtr pInstance;
    
    // Collections
    TRefPointerCollection<CInstance>	AdapterList;
    
    // Perform queries
    //================
    
    if (SUCCEEDED(hr = CWbemProviderGlue::GetInstancesByQuery(L"select DeviceID, Description, Index from Win32_NetworkAdapter",
        &AdapterList, pMethodContext)))
    {
        TRC2((TB,"TSNetworkAdapterListSetting@EnumerateInstances: GetInstancesByQuery ret 0x%x\n" , hr));
        
        REFPTRCOLLECTION_POSITION	pos;
        
        CInstancePtr	pAdapter(NULL);
        
        if( AdapterList.BeginEnum( pos ) )
        {
            
            for (pAdapter.Attach(AdapterList.GetNext( pos ) ) ;
            SUCCEEDED(hr) && ( pAdapter != NULL ) ;
            pAdapter.Attach(AdapterList.GetNext( pos ) ) )
            {
                
                CHString chTermName;
                CHString chDeviceID;
                CHString chDescription;
                DWORD dwIndex = 0;
                pAdapter->GetCHString(m_szDeviceID, chDeviceID);
                pAdapter->GetCHString(m_szDescription, chDescription);
                pAdapter->GetDWORD(m_szIndex, dwIndex);
                
                // No maximum limit check
                
                if( chDeviceID.IsEmpty() != 0)
                {
                    return WBEM_E_ILLEGAL_NULL;
                }        
                
                pInstance.Attach(CreateNewInstance(pMethodContext));
                
                if( NULL != pInstance )
                {
                    // set relpath to Adapter
                    CHString chsAdapterPath;
                    CHString chsFullAdapterPath;
                    pAdapter->GetCHString(L"__RELPATH", chsAdapterPath);
                    chsFullAdapterPath.Format(L"\\\\%s\\%s:%s", (LPCTSTR)GetLocalComputerName(), L"root\\cimv2", (LPCTSTR)chsAdapterPath);
                    pInstance->SetCHString(L"Element", chsFullAdapterPath);
                    pInstance->SetCHString(m_szDescription, chDescription);
                    pInstance->SetCHString(m_szDeviceID, chDeviceID);
                    pInstance->SetCHString(m_szNetworkAdapterID, chDeviceID);
                    pInstance->SetDWORD(m_szIndex, dwIndex);
                    
                    // create a relpath for the NetworkAdapterSettingsConfig
                    CHString chsNetworkAdapterSettingPath;
                    chsNetworkAdapterSettingPath.Format(L"\\\\%s\\%s:%s.%s=\"%s\"", (LPCTSTR)GetLocalComputerName(), L"root\\cimv2", L"Win32_TSNetworkAdapterSetting", m_szNetworkAdapterID, (LPCTSTR)chDeviceID);
                    
                    // and set the reference in the association
                    pInstance->SetCHString(L"Setting", chsNetworkAdapterSettingPath);
                    // to that relpath.
                    
                    CInstancePtr pNewInstance(NULL);
                    
                    if( SUCCEEDED(hr = CWbemProviderGlue::GetInstanceKeysByPath(chsNetworkAdapterSettingPath, &pNewInstance, pMethodContext)) )
                    {
                        pNewInstance->GetCHString(m_szTerminalName, chTermName);
                        pInstance->SetCHString(m_szTerminalName, chTermName);
                    }
                    TRC2((TB,"TSNetworkAdapterListSetting@EnumerateInstances: GetInstanceKeysByPath ret 0x%x\n" , hr));                    
                    
                    hr = pInstance->Commit();
                }	// end if
                
            } // pAdapter not null        
            AdapterList.EndEnum();        
        }	// IF BeginEnum        
    }
    return(hr);
    
}




HRESULT CWin32_TSNetworkAdapterListSetting::GetObject ( CInstance* pInstance, long lFlags)
{
    HRESULT hr = WBEM_E_NOT_FOUND;
    
    // get the object for the Win32_Terminal
    CHString chsAdapter;
    CInstancePtr pAdapter(NULL);
    
    if( pInstance != NULL )
    {
        pInstance->GetCHString(L"Element", chsAdapter);
        MethodContext* pMethodContext = pInstance->GetMethodContext();    
        
        hr = CWbemProviderGlue::GetInstanceByPath(chsAdapter, &pAdapter, pMethodContext);
        TRC2((TB,"TSNetworkAdapterListSetting@GetObject: GetInstanceByPath ret 0x%x\n" , hr));
        
        do
        {
            if( SUCCEEDED( hr ) && pAdapter != NULL )
            {
                // Got the account.  Now, match it to the GUID.
                // first, generate a relpath with which to compare.
                CHString chDeviceID;
                CHString chNetworkAdapterSettingInstance;
                CHString chDescription;
                DWORD dwIndex = 0;
                pAdapter->GetCHString(m_szDeviceID, chDeviceID); 
                pAdapter->GetCHString(m_szDescription, chDescription);
                pAdapter->GetDWORD(m_szIndex, dwIndex);
                
                // create a relpath for the sid
                CHString chsNetworkAdapterSettingPath;
                chsNetworkAdapterSettingPath.Format(L"\\\\%s\\%s:%s.%s=\"%s\"", (LPCTSTR)GetLocalComputerName(), L"root\\cimv2", L"Win32_TSNetworkAdapterSetting", m_szNetworkAdapterID, (LPCTSTR)chDeviceID);
                
                // get the SID path from the instance
                pInstance->GetCHString(L"Setting", chNetworkAdapterSettingInstance);
                
                // compare it to our generated relpath
                if( 0 != chNetworkAdapterSettingInstance.CompareNoCase(chsNetworkAdapterSettingPath) )
                {
                    hr = WBEM_E_NOT_FOUND;

                    TRC2((TB,"TSNetworkAdapterListSetting@GetObject: CompareNoCase for relpath ret 0x%x\n" , hr));
                    
                    break;
                }
                pInstance->SetCHString(m_szDescription, chDescription);
                pInstance->SetCHString(m_szDeviceID, chDeviceID);
                pInstance->SetCHString(m_szNetworkAdapterID, chDeviceID);
                pInstance->SetDWORD(m_szIndex, dwIndex);
                
            }
        }while (0);
    }
    return(hr);
}
*/



CWin32_TSNetworkAdapterListSetting::CWin32_TSNetworkAdapterListSetting ( const CHString& setName, LPCTSTR pszNameSpace  )
: Provider (setName,pszNameSpace)
{
    

    if ( g_hInstance != NULL)
    {        

        TRC2((TB, "CWin32_TSNetworkAdapterListSetting_ctor"));
       
        _tcscpy(m_szTerminalProtocol, _T("TerminalProtocol"));

        _tcscpy(m_szTransport, _T("Transport"));

        _tcscpy(m_szDescription, _T("Description"));

        _tcscpy(m_szNetworkAdapterID, _T("NetworkAdapterID"));
                
    }
}

CWin32_TSNetworkAdapterListSetting::~CWin32_TSNetworkAdapterListSetting ()
{
}


/*****************************************************************************
*
*  FUNCTION    :    CWin32_TSNetworkAdapterListSetting::EnumerateInstances
*
*  DESCRIPTION :    Returns all the instances of this class.
*
*  INPUTS      :    A pointer to the MethodContext for communication with WinMgmt.
*                   A long that contains the flags described in 
*                   IWbemServices::CreateInstanceEnumAsync.  Note that the following
*                   flags are handled by (and filtered out by) WinMgmt:
*                   WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY, 
*                   WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
*  RETURNS     :    WBEM_S_NO_ERROR if successful
*
*  COMMENTS    :    All instances on the machine are returned here and
*                   all properties that this class knows how to populate must 
*                   be filled in.  If there are no instances, return 
*                   WBEM_S_NO_ERROR.  
*****************************************************************************/

HRESULT CWin32_TSNetworkAdapterListSetting::EnumerateInstances (MethodContext*  pMethodContext, long lFlags)
{
	
    HRESULT hr = WBEM_S_NO_ERROR;    
    DWORD dwData = 0;
    ULONG  ulTerminals = 0;
    ULONG  ulSize = 0; 
    ULONG ulNum = 0;
    ULONG ulNumAdapters = 0;
    ULONG ulNAdapters = 0;
    ULONG ulItems = 0;
    DWORD dwSdclass = 0;
    PGUIDTBL pGuidTbl = NULL;
    PWS  pWS = NULL;
    CHString chGuid;
    LPBYTE pBuffer = NULL;
    chGuid.Empty();
    TCHAR tchGuid[ GUID_LENGTH ];
    TCHAR tchDeviceName[MAX_PATH];
    PPDPARAMS pPdParams = NULL;
    ULONG idx = NULL;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}

    if( SUCCEEDED( hr ))
    {
        hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);       
    }
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for( ulNum = 0; ulNum < ulTerminals ; ++ulNum)
        { 
            if( lstrcmpi( pWS[ulNum].pdName, L"Console") == 0)
            {
                continue;
            }

            hr = StackObj.m_pCfgComp->GetTransportType( pWS[ulNum].wdName , pWS[ulNum].pdName ,  &dwSdclass );

            TRC2((TB,"TSNetworkAdapterListSetting@EnumerateInstances: GetTransportType ret 0x%x\n" , hr )); 
            
            if( SUCCEEDED( hr ) )
            {
                TRC2((TB,"TSNetworkAdapterListSetting@EnumerateInstances: dwSdclass is 0x%x\n", dwSdclass  ));

                if( dwSdclass == SdAsync)
                {
                    TRC2((TB,"TSNetworkAdapterListSetting@EnumerateInstances: SdAsync"  ));

                    hr = StackObj.m_pCfgComp->GetDeviceList( pWS[ulNum].pdName, WsName, &ulItems, &pBuffer );

                    TRC2((TB,"TSNetworkAdapterListSetting@EnumerateInstances: GetDeviceList ret 0x%x\n" , hr ));

                    if( SUCCEEDED(  hr ) )
                    {
		                DBGMSG( L"TSCC : GetDeviceList returned %d devices that are available\n" , ulItems );

                        for( idx = 0 , pPdParams = ( PPDPARAMS )pBuffer; idx < ulItems ; idx++, pPdParams++ )
                        {                         

                            if ( *(pPdParams->Async.ModemName) )
                                wsprintf( tchDeviceName, TEXT("%s - %s"),
                                          pPdParams->Async.DeviceName,
                                          pPdParams->Async.ModemName );
                            else
                            {
                                if( lstrlen(pPdParams->Async.DeviceName) < MAX_PATH)
                                {
                                    lstrcpy( tchDeviceName,
                                             pPdParams->Async.DeviceName );
                                }
                            }

                             CInstance* pInstance = CreateNewInstance(pMethodContext);
        
                             if( pInstance == NULL)
                             {
                                 ERR((TB,"TSNetworkAdapterListSetting@EnumerateInstances: CreateNewInstance failed" ));               
            
                                 hr = WBEM_E_OUT_OF_MEMORY;
            
                                 break;
                             }    
                             pInstance->SetCharSplat(m_szTerminalProtocol, pWS[ulNum].pdName);

                             pInstance->SetCharSplat(m_szTransport, pWS[ulNum].wdName);

                             pInstance->SetCHString(m_szNetworkAdapterID, L"Not Applicable");

                             if( BIT_ALL_PROP & BIT_COMMENT )
                             {
                                  if( StackObj.m_pCfgComp->IsAsyncDeviceAvailable( pPdParams->Async.DeviceName ) )
                                  {
                                        pInstance->SetCharSplat(m_szDescription, tchDeviceName);
                                  }  
                             }
                     
                             hr = pInstance->Commit();
                     
                         pInstance->Release( );

                        }
                    }                    
                }   
                
                else if( dwSdclass == SdNetwork)
                {

                    hr = StackObj.m_pCfgComp->GetLanAdapterList2( pWS[ulNum].pdName, &ulNumAdapters, &pGuidTbl );

                    TRC2((TB,"TSNetworkAdapterListSetting@EnumerateInstances: GetLanAdapterList2 ret 0x%x\n" , hr ));
                
                    if( SUCCEEDED( hr )  && pGuidTbl != NULL )
                    {
                        for ( ulNAdapters = 0; ulNAdapters < ulNumAdapters ; ulNAdapters++ )
                        {
                            CInstance* pInstance = CreateNewInstance(pMethodContext);
            
                            if( pInstance == NULL)
                            {
                                ERR((TB,"TSNetworkAdapterListSetting@EnumerateInstances: CreateNewInstance failed" ));               
                
                                hr = WBEM_E_OUT_OF_MEMORY;
                
                                break;
                            }                        

                            StringFromGUID2( ( pGuidTbl )[ ulNAdapters ].guidNIC , tchGuid , ARRAYSIZE( tchGuid ) );
                        
                            chGuid.Format(L"%s", tchGuid);                   

                            pInstance->SetCharSplat(m_szTerminalProtocol, pWS[ulNum].pdName);

                            pInstance->SetCharSplat(m_szTransport, pWS[ulNum].wdName);

                            pInstance->SetCHString(m_szNetworkAdapterID, chGuid);                        

                            if( BIT_ALL_PROP & BIT_COMMENT )
                            {                        
                                pInstance->SetCharSplat(m_szDescription, pGuidTbl[ulNAdapters].DispName);                                       
                            }        
            
                            if( SUCCEEDED( hr ) )
                            {
                                hr = pInstance->Commit();
                            }
                            pInstance->Release( );
                        }
                    }
                }
            }
        }
        
    }

    if( pPdParams != NULL)
    {
        LocalFree( pPdParams);
    }    

    if( pBuffer != NULL )
    {
        LocalFree( pBuffer );
    }
    
    if( pWS != NULL ) 
    {
        CoTaskMemFree(pWS);
        
    }

    if( pGuidTbl != NULL )
    {
        CoTaskMemFree( pGuidTbl );
    }    

    return hr;

}



HRESULT CWin32_TSNetworkAdapterListSetting::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query)
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    CHString chTerminalProtocol;
    CHString chTransport;
    CHString chGuid;
    ULONG ulNAdapters = 0;
    ULONG ulNumAdapters = 0;
    DWORD dwSdclass = 0;
    ULONGLONG ulRequiredProperties = 0;
    PGUIDTBL pGuidTbl = NULL;
	
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}

    if( pInstance == NULL )
    {
        ERR((TB,"TSNetworkAdapterListSetting@GetObject: invalid pointer"));
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    pInstance->GetCHString(m_szTerminalProtocol, chTerminalProtocol);
    
    if( chTerminalProtocol.GetLength() > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTerminalProtocol.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }

    pInstance->GetCHString(m_szTransport, chTransport);
    
    if( chTransport.GetLength() > NASIUSERNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTransport.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }

    chGuid.Empty();           
 
    pInstance->GetCHString(m_szNetworkAdapterID, chGuid);

    if( chGuid.GetLength() > GUID_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chGuid.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }   

    hr = StackObj.m_pCfgComp->GetTransportType( (LPTSTR)(LPCTSTR) chTransport , (LPTSTR)(LPCTSTR) chTerminalProtocol , &dwSdclass );

    TRC2((TB,"TSNetworkAdapterListSetting@GetObject: GetTransportType ret 0x%x\n" , hr )); 

    if( SUCCEEDED( hr ) )
    {        
        if( dwSdclass != SdNetwork )
        {
            return WBEM_E_INVALID_OPERATION;
        }     
          
        hr = StackObj.m_pCfgComp->GetLanAdapterList2( (LPTSTR)(LPCTSTR) chTerminalProtocol, &ulNumAdapters, &pGuidTbl );  

        TRC2((TB,"TSNetworkAdapterListSetting@GetObject: GetLanAdapterList2 ret 0x%x\n" , hr )); 

        if( SUCCEEDED( hr ) && pGuidTbl != NULL )
        {      
            for( ulNAdapters = 0; ulNAdapters < ulNumAdapters ; ulNAdapters++ )
            {
              //  hr = LoadPropertyValues(pInstance, ulRequiredProperties, (LPTSTR)(LPCTSTR) chTerminalProtocol, (LPTSTR) (LPCTSTR) chTransport, (LPTSTR) (LPCTSTR) chGuid, pGuidTbl[ulNAdapters].DispName );
                if( ulRequiredProperties & BIT_COMMENT )
                {                        
                    pInstance->SetCharSplat(m_szDescription, pGuidTbl[ulNAdapters].DispName);                                       
                }     
            }
        }
    }

    if( pGuidTbl != NULL )
    {
        CoTaskMemFree( pGuidTbl );
    }

    return hr;
}


/*
HRESULT CWin32_TSNetworkAdapterListSetting::LoadPropertyValues( CInstance *pInstance, ULONGLONG ulRequiredProperties, PTCHAR pdName, PTCHAR wdName, PTCHAR pGuid, PTCHAR DisplayName)
{

    DWORD dwData = 0 ;
    DWORD cbItems = 0;
    ULONG ulAdapters = 0;
    CHString chGuid;
    chGuid.Empty();
    chGuid.Format (L"%s", pGuid);
    CHString chGUIDName;
    HRESULT hr = WBEM_S_NO_ERROR;

    TCHAR tchGuid[ GUID_LENGTH ];        
    

    if( pCfgComp == NULL )
    {
        ERR((TB,"TSNetworkAdapterListSetting@LoadPropertyValues: invalid interface"));
        
        return WBEM_E_INITIALIZATION_FAILURE;        
    }
    
    if( pInstance == NULL )
    {
        return WBEM_E_INVALID_PARAMETER;       
    }   
              
    pInstance->SetCharSplat(m_szTerminalProtocol, pdName);

    pInstance->SetCharSplat(m_szTransport, wdName);

    pInstance->SetCharSplat(m_szNetworkAdapterID, pGuid);

    if( chGuid.IsEmpty() != 0 )
    {         
        pInstance->SetCharSplat(m_szNetworkAdapterID, pGuid);
    }
    else
    {
        pInstance->SetCHString(m_szNetworkAdapterID, chGuid );
    }

    if( ulRequiredProperties & BIT_COMMENT )
    {                        
        pInstance->SetCharSplat(m_szDescription, DisplayName);                                       
    }                                   
    
    return S_OK;
}
*/

//=-------------------------------


CWin32_TSAccount::CWin32_TSAccount (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) :
Provider( lpwszName, lpwszNameSpace )
{
    
    if ( g_hInstance != NULL)
    {

        TRC2((TB, "CWin32_TSAccount_ctor"));

        _tcscpy(m_szPermissionPreSet, _T("PermissionPreSet"));

        _tcscpy(m_szPermissionMask, _T("PermissionMask"));

        _tcscpy(m_szPermissionsAllowed, _T("PermissionsAllowed"));

        _tcscpy(m_szPermissionsDenied, _T("PermissionsDenied"));

        _tcscpy(m_szAuditSuccess, _T("AuditSuccess"));

        _tcscpy(m_szAuditFail, _T("AuditFail"));

        _tcscpy(m_szAllow, _T("Allow"));

        _tcscpy(m_szSuccess, _T("Success"));

        _tcscpy(m_szSID, _T("SID"));

        _tcscpy(m_szDelete, _T("Delete"));

        _tcscpy(m_szModifyPermissions, _T("ModifyPermissions"));

        _tcscpy(m_szModifyAuditPermissions, _T("ModifyAuditPermissions"));

        _tcscpy(m_szTerminalName, _T("TerminalName"));

        _tcscpy(m_szAccountName, _T("AccountName"));        

    }

}
//=--------------------
CWin32_TSAccount::~CWin32_TSAccount ()
{    
}


//=--------------------
/*****************************************************************************
*
*  FUNCTION    :    CWin32_TSAccount::EnumerateInstances
*
*  DESCRIPTION :    Returns all the instances of this class.
*
*  INPUTS      :    A pointer to the MethodContext for communication with WinMgmt.
*                   A long that contains the flags described in 
*                   IWbemServices::CreateInstanceEnumAsync.  Note that the following
*                   flags are handled by (and filtered out by) WinMgmt:
*                   WBEM_FLAG_DEEP, WBEM_FLAG_SHALLOW, WBEM_FLAG_RETURN_IMMEDIATELY, 
*                   WBEM_FLAG_FORWARD_ONLY, WBEM_FLAG_BIDIRECTIONAL
*
*  RETURNS     :    WBEM_S_NO_ERROR if successful
*
*  COMMENTS    :    All instances on the machine are returned here and
*                   all properties that this class knows how to populate must 
*                   be filled in.  If there are no instances, return 
*                   WBEM_S_NO_ERROR.  
*****************************************************************************/


HRESULT CWin32_TSAccount::EnumerateInstances (MethodContext* pMethodContext, long lFlags )
{
	
    HRESULT hr = WBEM_S_NO_ERROR;
    DWORD dwData = 0;
    ULONG  ulTerminals = 0;
    ULONG  ulSize = 0; 
    LONG  lSize = 0;
    ULONG ulNum = 0;
    ULONG ulAuditNum = 0;
    bool bFound = 0;
    DWORD cbItems = 0;
    DWORD cbAuditItems = 0;
    PWS  pWS = NULL;
    PUSERPERMLIST pUserList = NULL;
    PUSERPERMLIST pUserAuditList = NULL;
    IUserSecurity *pUserSecurity = NULL;
    
	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}    
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++ )
        {   
            hr = StackObj.m_pCfgComp->QueryInterface( IID_IUserSecurity , ( LPVOID * )&pUserSecurity );
            
            if( SUCCEEDED (hr) && pUserSecurity != NULL )
            {                
                
                hr = pUserSecurity->GetUserPermList( pWS[ulNum].Name , &cbItems , &pUserList, 0  );

                hr = pUserSecurity->GetUserPermList( pWS[ulNum].Name , &cbAuditItems , &pUserAuditList, 1  );                
                
                for( DWORD i = 0; i < cbItems && SUCCEEDED( hr ) ; ++i )
                {

                    for( DWORD j = 0;j < cbAuditItems ; j ++ )
                    {
                        bFound = 0;

                        if( lstrcmpi (pUserAuditList[j].Name, pUserList[i].Name) == 0 )
                        {
                            bFound = 1;

                            ulAuditNum = j;

                            break;
                        }
                    }

                    
                    CInstance* pInstance = CreateNewInstance(pMethodContext);
                    
                    if( pInstance == NULL)
                    {
                        ERR((TB,"TSAccount@EnumerateInstances: CreateNewInstance failed"));
                        
                        hr = WBEM_E_OUT_OF_MEMORY;

                        break;                                               
                    }
                    TRC2((TB,"TSAccount@EnumerateInstances: GetWinstationList ret 0x%x\n" , hr));

                    if( bFound == 1 )
                    {
                        hr = LoadPropertyValues(pInstance, BIT_ALL_PROP, &pWS[ulNum], &pUserList[i], &pUserAuditList[ulAuditNum]);
                    }
                    else
                    {
                        hr = LoadPropertyValues(pInstance, BIT_ALL_PROP, &pWS[ulNum], &pUserList[i], NULL);
                    }
                    
                    if( SUCCEEDED( hr ) )
                    {                        
                        hr = pInstance->Commit();                                                                                                
                    }

                    pInstance->Release( );
                }
            }
        }
        
    }

    if( pUserList != NULL )
    {
        CoTaskMemFree( pUserList );
    }

    if( pUserAuditList != NULL )
    {
        CoTaskMemFree( pUserAuditList );
    }    
    
    if( pWS != NULL )
    {
        CoTaskMemFree( pWS );
    }

    if (pUserSecurity != NULL)
    {
        pUserSecurity->Release();
    }

    return hr;
    
}
//=--------------------


HRESULT CWin32_TSAccount::ExecMethod ( const CInstance& Inst,
                                                        const BSTR bstrMethodName,
                                                        CInstance *pInParams,
                                                        CInstance *pOutParams,
                                                        long lFlags)
                                                        
{
	
    HRESULT hr = WBEM_E_NOT_FOUND;
    CHString chTermName;
    CHString chAccountName;
    DWORD dwPermissionPreSet = 0;
    DWORD dwMask = 0;
    DWORD dwPermissionDenyMask = 0;
    BOOL fAudit = FALSE;
    DWORD dwStatus = 0;
    IUserSecurity *pUserSecurity = NULL;
    
    CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    Inst.GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0)
    {
        return WBEM_E_ILLEGAL_NULL;
    }
            
    hr = StackObj.m_pCfgComp->QueryInterface( IID_IUserSecurity , ( LPVOID * )&pUserSecurity );
    
    if( SUCCEEDED( hr ) && pUserSecurity != NULL  )
    {        
        do
        {
            
            // Deletes the permission from the specified user or group.
            // uint32 Delete();

            if( _wcsicmp(bstrMethodName, m_szDelete) == 0 )
            {
                
                dwStatus = 0;
                DWORD dwData = 0;
                LONG lSize;
                
                RegGetMachinePolicy( &m_gpPolicy );                    
                  
                Inst.GetCHString(m_szAccountName, chAccountName);
                
                
                if( chAccountName.GetLength() > NASIUSERNAME_LENGTH )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
                    
                    break;
                }
                
                if( chAccountName.IsEmpty() != 0)
                {
                    hr = WBEM_E_ILLEGAL_NULL;
                    
                    break;
                }
                
                if ( m_gpPolicy.fPolicyWritableTSCCPermissionsTAB == 0)
                {                    
                    hr = pUserSecurity->ModifyUserAccess( (LPTSTR) (LPCTSTR)chTermName,  // winsta to modify security
                        (LPTSTR) (LPCTSTR) chAccountName,         // group or user
                        0,         // winsta permission
                        TRUE ,
                        FALSE  ,              // t - allow permission f - deny perm 
                        FALSE ,              // t - new object f - donot change previous permission                                
                        FALSE ,           // t - enable auditing f - no auditing
                        &dwStatus );
                
                    TRC2((TB,"TSAccount@ExecMethod: Delete with Deny=True and Audit=False ret 0x%x\n", dwStatus));
                
                    hr = pUserSecurity->ModifyUserAccess( (LPTSTR) (LPCTSTR)chTermName,  // winsta to modify security
                        (LPTSTR) (LPCTSTR) chAccountName,         // group or user
                        0,         // winsta permission
                        TRUE ,
                        FALSE  ,              // t - allow permission f - deny perm 
                        FALSE ,              // t - new object f - donot change previous permission                                
                        TRUE ,           // t - enable auditing f - no auditing
                        &dwStatus );
                
                    TRC2((TB,"TSAccount@ExecMethod: Delete with Deny=True and Audit=True ret 0x%x\n", dwStatus));
                                    
                    if (pOutParams != NULL && SUCCEEDED( hr ) && SUCCEEDED( dwStatus ))
                    {
                        pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                    }                      
                    else
                    {
                        hr = WBEM_E_INVALID_METHOD_PARAMETERS;  
                        
                        break;
                    }
                }
                else
                {
                    hr = WBEM_E_INVALID_OPERATION;
                    
                    break;
                }                                                   
                
            }
            
            // Restores the default permissions to default set of users and groups.
            // uint32 ModifyPermissions([In] uint32 PermissionMask, [In] boolean Allow)

            else if( _wcsicmp(bstrMethodName, m_szModifyPermissions) == 0 )
            {                                
                dwStatus = 0;
                DWORD dwData = 0;
                LONG lSize;
                ULONG ulOffset = 0;
                DWORD cbItems = 0;
                ULONG ulPermissionMask = 0;
                bool fAllow;
                bool bRet;

                RegGetMachinePolicy(&m_gpPolicy);
                                           
                Inst.GetCHString(m_szAccountName, chAccountName);
            
            
                if( chAccountName.GetLength() > NASIUSERNAME_LENGTH )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
                
                    break;
                }
            
                if( chAccountName.IsEmpty() != 0 )
                {
                    hr = WBEM_E_ILLEGAL_NULL;
                
                    break;
                }

                if(pInParams == NULL)
                {
                    hr = WBEM_E_INVALID_METHOD_PARAMETERS;

                    break;
                }

                bRet = pInParams->GetDWORD(m_szPermissionMask, ulPermissionMask);
        
        
                if( !bRet || ulPermissionMask > 9 )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
            
                    break;
                }               
                
                if(ulPermissionMask == 3)      // WINSTATION_VIRTUAL | STANDARD_RIGHTS_REQUIRED                                          
                {
                    dwMask = 0xF0008;
                }
                else
                {        
                   
                    ULONG ulBase = 1;

                    for (ULONG ulIndex = 1; ulIndex <= ulPermissionMask; ulIndex++)
                    {
                        ulBase *= 2;
        
                    }

                    dwMask = ulBase;   
                }
                
                
                RegGetMachinePolicy(&m_gpPolicy);
        
                pInParams->Getbool(m_szAllow, fAllow);
        
                if( fAllow != 0 && fAllow != 1 )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
            
                    break;
                }
        
        /*
        
                if( fAudit != 0 && fAudit != 1 )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
            
                    break;
                }
        */

                if( m_gpPolicy.fPolicyWritableTSCCPermissionsTAB == 0 )
                {

                    pUserSecurity->ModifyUserAccess( (LPTSTR) (LPCTSTR)chTermName,  // winsta to modify security
                        (LPTSTR) (LPCTSTR) chAccountName,         // group or user
                        dwMask,         // winsta permission
                        FALSE ,
                        fAllow  ,              // t - allow permission f - deny perm 
                        FALSE ,              // t - new object f - donot change previous permission                                
                        FALSE ,           // t - enable auditing f - no auditing
                        &dwStatus ); 
                
                    TRC2((TB,"TSAccount@ExecMethod: Modify with Audit=0 ret 0x%x\n", dwStatus));
        
                    if( SUCCEEDED (dwStatus) && pOutParams != NULL )
                    {

                        pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
            
                    } 
        
                    else
                    {
                        hr = WBEM_E_INVALID_METHOD_PARAMETERS;

                        ERR((TB,"TSAccount@ExecMethod: Modify ret 0x%x\n", hr));
            
                        break;
                    }
                }
                else
                {
                    hr = WBEM_E_INVALID_OPERATION;

                    break;
                }
            
                           
            }
            
            // Modifies Audit permissions of users and groups.
            // uint32 ModifyAuditPermissions([In] uint32 PermissionMask, [In] boolean Allow)

            else if( _wcsicmp(bstrMethodName, m_szModifyAuditPermissions) == 0 )
            {
                
                dwStatus = 0;
                DWORD dwData = 0;
                LONG lSize;
                ULONG ulOffset = 0;
                DWORD cbItems = 0;
                ULONG ulPermissionMask = 0;
                bool fSuccess;
                bool bRet;
                
                RegGetMachinePolicy( &m_gpPolicy );
                
                Inst.GetCHString(m_szAccountName, chAccountName);
                
                
                if( chAccountName.GetLength() > NASIUSERNAME_LENGTH )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
                    
                    break;
                }
                
                if( chAccountName.IsEmpty() != 0)
                {
                    hr = WBEM_E_ILLEGAL_NULL;
                    
                    break;
                }

                if(pInParams == NULL)
                {
                    hr = WBEM_E_INVALID_METHOD_PARAMETERS;

                    break;
                }
               
                bRet = pInParams->GetDWORD(m_szPermissionMask, ulPermissionMask);
                        
                if( !bRet || ulPermissionMask > 9 )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
                
                    break;
                } 

                if(ulPermissionMask == 3) // WINSTATION_VIRTUAL is defined as 0x00000008 but                                          
                {                         // GetExplicitEntriesFromAcl is returning 983048
                    dwMask = 0xF0008;
                }
                else
                {                                
                    ULONG ulBase = 1;

                    for( ULONG ulIndex = 1; ulIndex <= ulPermissionMask; ulIndex++ )
                    {
                        ulBase *= 2;
            
                    }

                    dwMask = ulBase;
                }            
            
                pInParams->Getbool(m_szSuccess, fSuccess);
            
            
                if( fSuccess != 0 && fSuccess != 1 )
                {
                    hr = WBEM_E_VALUE_OUT_OF_RANGE;
                
                    break;
                }
            
                if( m_gpPolicy.fPolicyWritableTSCCPermissionsTAB == 0 )
                {
            
                    pUserSecurity->ModifyUserAccess( (LPTSTR) (LPCTSTR)chTermName,  // winsta to modify security
                        (LPTSTR) (LPCTSTR) chAccountName,         // group or user
                        dwMask,         // winsta permission
                        FALSE ,
                        fSuccess  ,              // t - allow permission f - deny perm 
                        FALSE ,              // t - new object f - donot change previous permission                                
                        TRUE ,           // t - enable auditing f - no auditing
                        &dwStatus ); 

                    TRC2((TB,"TSAccount@ExecMethod: ModifyAuditPermissions ret 0x%x\n", dwStatus));                                               
            
                    if( SUCCEEDED (dwStatus) && pOutParams != NULL )
                    {
                        pOutParams->SetDWORD(L"ReturnValue", WBEM_S_NO_ERROR);
                
                    } 
                    else
                    {
                        hr = WBEM_E_INVALID_METHOD_PARAMETERS;

                        TRC2((TB,"TSAccount@ExecMethod: Modify ret 0x%x\n", hr));
                
                        break;
                    }
                }
                else
                {
                    hr = WBEM_E_INVALID_OPERATION;

                    break;
                }            
            }
            
            else
            {
                hr = WBEM_E_INVALID_METHOD;

                break;
            }
            
        }while(0);
    } 

    if( pUserSecurity != NULL)
    {
        pUserSecurity->Release();
    }

    return hr;
    
}

//=--------------------

HRESULT CWin32_TSAccount::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags)
{	
    HRESULT hr = WBEM_E_NOT_FOUND;
    ULONGLONG ulRequiredProperties = 0;
    CHStringArray asNames;
    ULONG ulNum = 0;
    ULONG ulSize = 0;
    ULONG ulTerminals = 0;
    ULONG ulAuditNum = 0;
    PWS pWS = NULL;
    PUSERPERMLIST pUserList = NULL;
    PUSERPERMLIST pUserAuditList = NULL;
    DWORD cbItems = 0;
    DWORD cbAuditItems = 0;
    bool bFound = 0;
    IUserSecurity *pUserSecurity = NULL;

	CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    // Method 2
    Query.GetValuesForProp(m_szTerminalName, asNames);
    
    BOOL bGetAllInstances = asNames.GetSize() == 0;
    
    // Method 1
    if (Query.IsPropertyRequired(m_szTerminalName))
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if (Query.IsPropertyRequired(m_szSID))
        ulRequiredProperties |= BIT_SID;
    
    if (Query.IsPropertyRequired(m_szAccountName))
        ulRequiredProperties |= BIT_ACCOUNTNAME;

    if (Query.IsPropertyRequired(m_szAuditSuccess))
        ulRequiredProperties |= BIT_AUDITSUCCESS;

    if (Query.IsPropertyRequired(m_szAuditFail))
        ulRequiredProperties |= BIT_AUDITFAIL;
    
    if (Query.IsPropertyRequired(m_szPermissionsAllowed))
        ulRequiredProperties |= BIT_PERMISSIONSALLOWED;
    
    if (Query.IsPropertyRequired(m_szPermissionsDenied))
        ulRequiredProperties |= BIT_PERMISSIONSDENIED;
   
    
    hr = StackObj.m_pCfgComp->GetWinstationList(&ulTerminals, &ulSize, &pWS);        
    
    if( SUCCEEDED( hr ) && pWS != NULL )
    {   
        for( ulNum = 0; ulNum < ulTerminals && SUCCEEDED( hr ) ; ulNum++)
        {  
            
            // Method 2 
            if (bGetAllInstances || IsInList(asNames, pWS[ulNum].Name))
            {
                
                hr = StackObj.m_pCfgComp->QueryInterface( IID_IUserSecurity , ( LPVOID * )&pUserSecurity );
                
                if (SUCCEEDED ( hr ) && pUserSecurity != NULL)
                {                   
                    
                    hr = pUserSecurity->GetUserPermList( pWS[ulNum].Name , &cbItems , &pUserList, 0  );

                    hr = pUserSecurity->GetUserPermList( pWS[ulNum].Name , &cbAuditItems , &pUserAuditList, 1  );
                    
                    for( DWORD i = 0; i < cbItems && SUCCEEDED( hr ) ; ++i )
                    {
                        for( DWORD j = 0;j < cbAuditItems ; j ++ )
                        {
                            bFound = 0;

                            if( lstrcmpi (pUserAuditList[j].Name, pUserList[i].Name) == 0 )
                            {
                                bFound = 1;

                                ulAuditNum = j;

                                break;
                            }
                        }
                        
                        CInstance* pInstance = CreateNewInstance(pMethodContext);
                        
                        if( pInstance == NULL )
                        {
                            ERR((TB,"TSAccount@ExecQuery: CreateNewInstance failed"));
                                                        
                            hr = WBEM_E_OUT_OF_MEMORY;

                            break;                                                       
                        }                        
                        
                        if( bFound == 1 )
                        {
                            hr = LoadPropertyValues(pInstance, ulRequiredProperties, &pWS[ulNum], &pUserList[i], &pUserAuditList[ulAuditNum]);
                        }
                        else
                        {
                            hr = LoadPropertyValues(pInstance, ulRequiredProperties, &pWS[ulNum], &pUserList[i], NULL);
                        }


                        if( SUCCEEDED( hr ) )
                        {
                            hr = pInstance->Commit();
                        }
                        
                        pInstance->Release();
                    }
                }
            }
        }
    }

    if( pUserList != NULL )
    {
        CoTaskMemFree( pUserList );
    }

    if( pUserAuditList != NULL )
    {
        CoTaskMemFree( pUserAuditList );
    }    
    
    if( pWS != NULL )
    {
        CoTaskMemFree(pWS);
        
    }

    if( pUserSecurity != NULL )
    {
        pUserSecurity->Release();
    }

    return hr;
}

//=------------------------------

HRESULT CWin32_TSAccount::GetObject ( CInstance* pInstance, long lFlags, CFrameworkQuery &Query )
{	
    HRESULT hr = WBEM_E_NOT_FOUND;
    DWORD dwData = 0;
    CHString chTermName;
    CHString chAccountName;
    DWORD cbItems = 0;
    DWORD cbAuditItems = 0;
    ULONG ulSize = 0;
    ULONGLONG ulRequiredProperties = 0;
    LONG  lSize = 0;
    bool bFound = 0;
    PWS pWS = NULL;
    PUSERPERMLIST pUserList = NULL;
    PUSERPERMLIST pUserAuditList = NULL;
    ULONG ulNum = 0;
    ULONG ulAuditNum = 0;
    IUserSecurity *pUserSecurity = NULL;
    
    CStackClass StackObj;

	if( StackObj.m_pCfgComp == NULL)
	{
		return WBEM_E_ILLEGAL_NULL;
	}
    
    if( pInstance == NULL )
    {
        ERR((TB,"TSAccount@GetObject: invalid pointer"));
        
        return WBEM_E_ILLEGAL_NULL;
    }
    
    pInstance->GetCHString(m_szTerminalName, chTermName);
    
    if( chTermName.GetLength() > WINSTATIONNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chTermName.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }

    pInstance->GetCHString(m_szAccountName, chAccountName);
    
    if( chAccountName.GetLength() > NASIUSERNAME_LENGTH )
    {
        return WBEM_E_VALUE_OUT_OF_RANGE;
    }
    
    if( chAccountName.IsEmpty() != 0 )
    {
        return WBEM_E_ILLEGAL_NULL;
    }
    
    if( Query.IsPropertyRequired(m_szTerminalName) )
        ulRequiredProperties |= BIT_TERMINALNAME;
    
    if( Query.IsPropertyRequired(m_szSID) )
        ulRequiredProperties |= BIT_SID;
    
    if( Query.IsPropertyRequired(m_szAccountName) )
        ulRequiredProperties |= BIT_ACCOUNTNAME;

    if( Query.IsPropertyRequired(m_szAuditSuccess) )
        ulRequiredProperties |= BIT_AUDITSUCCESS;

    if( Query.IsPropertyRequired(m_szAuditFail) )
        ulRequiredProperties |= BIT_AUDITFAIL;
    
    if( Query.IsPropertyRequired(m_szPermissionsAllowed) )
        ulRequiredProperties |= BIT_PERMISSIONSALLOWED;
    
    if( Query.IsPropertyRequired(m_szPermissionsDenied) )
        ulRequiredProperties |= BIT_PERMISSIONSDENIED;
    
    hr = StackObj.m_pCfgComp->GetWSInfo( ( LPTSTR )( LPCTSTR )chTermName, &lSize, &pWS);
    
    hr = StackObj.m_pCfgComp->QueryInterface( IID_IUserSecurity , ( LPVOID * )&pUserSecurity );

    if( pUserSecurity != NULL && pWS != NULL && SUCCEEDED( hr ))
    {    
        do
        {                    

            hr = pUserSecurity->GetUserPermList( ( LPTSTR )( LPCTSTR ) chTermName , &cbAuditItems , &pUserAuditList, 1 );

            if( SUCCEEDED( hr ) && pUserAuditList != NULL)
            {

                for( ulAuditNum = 0; ulAuditNum < cbAuditItems ; ulAuditNum ++ )
                {
                    bFound = 0;

                    if( lstrcmpi (pUserAuditList[ulAuditNum].Name, (LPCTSTR) chAccountName) == 0 )
                    {
                        bFound = 1;

                        break;
                    }
                }
            }
            
            hr = pUserSecurity->GetUserPermList( ( LPTSTR )( LPCTSTR ) chTermName , &cbItems , &pUserList, 0 );

            if( SUCCEEDED (hr) && pUserList != NULL )
            {                                                    
                for( ulNum = 0; ulNum < cbItems ; ulNum ++  )
                {
                    if( lstrcmpi (pUserList[ulNum].Name, (LPCTSTR) chAccountName) != 0 )
                
                        continue;

                
                    if( bFound == 1 )
                    {
                        hr = LoadPropertyValues(pInstance, ulRequiredProperties, pWS, &pUserList[ulNum], &pUserAuditList[ulAuditNum]);
                    }
                    else
                    {
                        hr = LoadPropertyValues(pInstance, ulRequiredProperties, pWS, &pUserList[ulNum], NULL);
                    }
            
                    if( !(SUCCEEDED ( hr ) ))
                    {                                         
                        hr = WBEM_E_INVALID_OBJECT;

                        break;
                    }                                           
                }
            }
        
        }while(0);
    }

    if( pUserList != NULL )
    {
        CoTaskMemFree( pUserList );
    }

    if( pUserAuditList != NULL )
    {
        CoTaskMemFree( pUserAuditList );
    }
       
    if( pWS != NULL )
    {
        CoTaskMemFree (pWS);
    }

    if( pUserSecurity != NULL )
    {
        pUserSecurity->Release();
    }
    
    return hr;
    
}
//=--------------------

BOOL CWin32_TSAccount::IsInList(const CHStringArray &asArray, LPCWSTR pszString)
{
    DWORD dwSize = asArray.GetSize();
    
    for( DWORD x=0; x < dwSize; x++ )
    {
        if( asArray[x].CompareNoCase(pszString) == 0 )
        {
            return TRUE;
        }
    }
    
    return FALSE;
}

//=-----------------

HRESULT CWin32_TSAccount::LoadPropertyValues( CInstance *pInstance, ULONGLONG ulRequiredProperties, PWS pWS, PUSERPERMLIST pUserList, PUSERPERMLIST pUserAuditList)
{	
    HRESULT hr = S_OK;
    LONG lSize ;
    DWORD dwData = 0 ;
    DWORD cbItems = 0;
   
    if( pInstance == NULL )
    {
        return WBEM_E_INVALID_PARAMETER;       
    }   
    
    if( pWS != NULL && pUserList != NULL )
    {
        if( ulRequiredProperties & BIT_TERMINALNAME )
        {
            pInstance->SetCharSplat(m_szTerminalName, pWS->Name);
        }
       
        if( ulRequiredProperties & BIT_SID )
        {      
            pInstance->SetWCHARSplat(m_szSID, pUserList->Sid);
        }
        
        if( ulRequiredProperties & BIT_ACCOUNTNAME )
        {   
            pInstance->SetCharSplat(m_szAccountName, pUserList->Name);
        }
        
        if( ulRequiredProperties & BIT_PERMISSIONSALLOWED )
        {   
            if( pUserList->Type == 1 )
            {                  
                pInstance->SetDWORD(m_szPermissionsAllowed, pUserList->Mask);                
            }
            else
            {
                pInstance->SetDWORD(m_szPermissionsAllowed, 0);
            }
        }
        if( ulRequiredProperties & BIT_PERMISSIONSDENIED )
        {
            if( pUserList->Type == 3 )
            {              
                pInstance->SetDWORD(m_szPermissionsDenied, pUserList->Mask);                
            }
            else
            {
                pInstance->SetDWORD(m_szPermissionsDenied, 0);
            }
        }
        
        if( ulRequiredProperties & BIT_AUDITSUCCESS )
        { 
            if( pUserAuditList != NULL && pUserAuditList->Type == 5 )
            {                
                pInstance->SetDWORD(m_szAuditSuccess, pUserAuditList->Mask); 
            }
                
            else
            {
                pInstance->SetDWORD(m_szAuditSuccess, 0);
            }
        }
        if( ulRequiredProperties & BIT_AUDITFAIL )
        {
            if( pUserAuditList != NULL && pUserAuditList->Type == 6 )
            {
                pInstance->SetDWORD(m_szAuditFail, pUserAuditList->Mask);                        
            }
            else
            {
                pInstance->SetDWORD(m_szAuditFail, 0);
            }
        }                   
    } 


    return S_OK;
}
