/*
******************************************************************************
******************************************************************************
*
*
*              INTEL CORPORATION PROPRIETARY INFORMATION
* This software is supplied under the terms of a license agreement or
* nondisclosure agreement with Intel Corporation and may not be copied or
* disclosed except in accordance with the terms of that agreement.
*
*        Copyright (c) 1997, 1998 Intel Corporation  All Rights Reserved
******************************************************************************
******************************************************************************
*
* 
*
* 
*
*/



#include "dmipch.h"	// precompiled header for dmi provider

#include "WbemDmiP.h"

#include "DmiData.h"

#include "DmiInterface.h"

#include "Exception.h"

#include "strings.h"

#include "Trace.h"


#define WMU_GETCOMPONENT	WM_USER+1000
#define WMU_GETCOMPONENTS	WMU_GETCOMPONENT + 1
#define WMU_GETROW			WMU_GETCOMPONENTS + 1
#define WMU_GETNODE			WMU_GETROW + 1
#define WMU_ADDCOMPONENT	WMU_GETNODE + 1
#define WMU_DELETECOMPONENT	WMU_ADDCOMPONENT + 1
#define WMU_ADDGROUP		WMU_DELETECOMPONENT + 1
#define WMU_GETGROUPS		WMU_ADDGROUP + 1
#define WMU_GETGROUP		WMU_GETGROUPS + 1
#define WMU_DELETEGROUP		WMU_GETGROUP + 1
#define WMU_ADDLANGUAGE		WMU_DELETEGROUP + 1
#define WMU_DELETELANGUAGE	WMU_ADDLANGUAGE + 1
#define WMU_GETENUM			WMU_DELETELANGUAGE + 1
#define WMU_SETLANG			WMU_GETENUM + 1
#define WMU_GETLANGUAGES	WMU_SETLANG + 1
#define WMU_GETROWS			WMU_GETLANGUAGES + 1
#define WMU_ENABLEEVENTS	WMU_GETROWS + 1
#define WMU_DELETEROW		WMU_ENABLEEVENTS  + 1
#define WMU_UPDATEROW		WMU_DELETEROW + 1
#define WMU_ADDROW			WMU_UPDATEROW + 1
#define WMU_SHUTDOWN		WMU_ADDROW  + 1



class CDmiInterfaceJobContext
{
public:

					CDmiInterfaceJobContext();

	LPWSTR			pNWA;
	LONG			lComponent;
	LONG			lGroup;
	LONG			lAttribute;
	CNode*			pNode;
	CComponents*	pComponents;
	CComponent*		pComponent;
	CGroups*		pGroups;
	CGroup*			pGroup;
	CRows*			pRows;
	CRow*			pRow;
	CAttributes*	pKeys;
	CAttributes*	pAttributes;
	CLanguages*		pLanguages;
	CEnum*			pEnum;
	LPWSTR			pszData;
	CDmiError*		pError;	
	IWbemObjectSink*	pIClientSink;
};


CDmiInterfaceJobContext::CDmiInterfaceJobContext()
{
	pNWA = NULL ;
	lComponent = 0 ;
	lGroup = 0 ;
	lAttribute = 0 ;
	pNode = NULL ;
	pComponents = NULL ;
	pComponent = NULL ;
	pGroups = NULL ;
	pGroup = NULL ;
	pRows = NULL ;
	pRow = NULL ;
	pAttributes = NULL ;
	pEnum = NULL;
	pError = NULL ;
	pszData = NULL;
	pLanguages = NULL;

}

//////////////////////////////////////////////////////////////////

CDmiInterfaceThreadContext::CDmiInterfaceThreadContext()
{
	m_hStopThread = CreateEvent(NULL, FALSE, FALSE, NULL );
	m_hComplete = CreateEvent(NULL, FALSE, FALSE, NULL );

	// Create this as a manual reset event.  This event will be signaled in 
	// the Run() function to make sure that the Run() function is called
	// to create the thread's message loop before the SendThreadMessage() is called.
	// In SendThreadMessage() we will wait for this handle to be signaled before we
	// send any message to the threads.
	m_Started = CreateEvent(NULL, TRUE, FALSE, NULL );
	m_bRunning = FALSE;
}

void CDmiInterfaceThreadContext::StartThread ()
{
	_beginthread ( ApartmentThread , 0 , (void *)this );

	m_bRunning = TRUE;
}


CDmiInterfaceThreadContext::~CDmiInterfaceThreadContext()
{
	KillThread ( );

	CloseHandle ( m_hStopThread );

	CloseHandle ( m_hComplete );
	CloseHandle ( m_Started );
}

void CDmiInterfaceThreadContext::KillThread()
{
	if ( !m_bRunning )
		return;

	SetEvent ( m_hStopThread );	
	
	PostThreadMessage ( m_dwThreadId , WM_QUIT , 0 , 0 );

	WaitForSingleObject ( m_hComplete , INFINITE );

	m_bRunning = FALSE;
}


//////////////////////////////////////////////////////////////////

class CDmiInterfaceThread 
{
public:
				CDmiInterfaceThread();
				~CDmiInterfaceThread();

	void		Run ( CDmiInterfaceThreadContext* pTC );

private:
	//void		MakeConnectString( LPWSTR, CString& );
	BOOL		m_bRun;

	void		HandleWMU( MSG& msg );
	void		MessageLoop ( );



	friend void dmiReadNode ( LPWSTR , CNode* , CDmiError* );

	friend void dmiReadComponents ( LPWSTR pNWA , 
		CComponents* pNewComponents , CDmiError* );

	friend void dmiReadComponent ( LPWSTR pNWA , LONG lComponent , 
		CComponent* pNewComponent  , CDmiError* );

	friend void dmiReadGroups ( LPWSTR pNWA , LONG lComponent , 
		CGroups* pNewGroups  , CDmiError* );

	friend void dmiReadGroup ( LPWSTR pNWA , LONG lComponent , LONG lGroup , 
		CGroup* pNewGroup  , CDmiError* );

	friend void dmiReadRows ( LPWSTR wszNWA , LONG lComponent , LONG lGroup ,
		CRows* pNewRows  , CDmiError* );

	friend void dmiReadRow ( LPWSTR wszNWA , LONG lComponent , LONG lGroup ,
		CAttributes* pKeys , CRow* pNewRow  , CDmiError* );

	friend void dmiReadEnum ( LPWSTR pNWA , LONG lComponent , LONG lGroup ,
		LONG lAttribute , CEnum* pNewEnum  , CDmiError* );

	friend void dmiReadLanguages ( LPWSTR pNWA , LONG lComponent , 
		CLanguages* pNewLanguages  , CDmiError* );

	friend void dmiAddComponent ( LPWSTR wszNWA , LPWSTR pMifFile , 
		CDmiError* );
	
	friend void dmiDeleteComponent ( LPWSTR wszNWA , LONG  , CDmiError* );

	friend void dmiAddLanguage ( LPWSTR pNWA , LONG lComponent , 
		LPWSTR pMifFile  , CDmiError* );

	friend void dmiDeleteLanguage ( LPWSTR pNWA , LONG lComponent , 
		LPWSTR pszLanguage  , CDmiError* );

	friend void dmiAddGroup ( LPWSTR wszNWA , LONG lComponent , 
		LPWSTR wszMifFile , CDmiError* );

	friend void dmiDeleteGroup ( LPWSTR , LONG , LONG , CDmiError* );

	friend void dmiAddRow ( LPWSTR , LONG lComponent , LONG lGroup , CRow* ,
		CDmiError* );

	friend void dmiModifyRow ( LPWSTR , LONG lComponent , LONG lGroup , 
		CAttributes* pKeys , CRow* , CDmiError* );

	friend void dmiDeleteRow ( LPWSTR , LONG lComponent , LONG lGroup , 
		CAttributes* pKeys , CDmiError* );

	friend void dmiSetDefaultLanguage ( LPWSTR , LPWSTR , CDmiError* );

	friend void dmiEnableEvents ( LPWSTR , IWbemObjectSink* );

	
};


//////////////////////////////////////////////////////////////////

void ApartmentThread ( void* pTC)
{
	CDmiInterfaceThread DDT;

	DDT.Run ( (CDmiInterfaceThreadContext* ) pTC );	

	_endthread ( );

	return;

}

CDmiInterfaceThread::CDmiInterfaceThread()
{
	m_bRun = TRUE;
}


CDmiInterfaceThread::~CDmiInterfaceThread()
{
	m_bRun = FALSE;	
}


void CDmiInterfaceThread::Run ( CDmiInterfaceThreadContext* pTC )
{		
	MSG	msg;

	pTC->m_dwThreadId = GetCurrentThreadId ( );

	// force the creation of the message loop 
	PeekMessage( &msg, NULL, WM_USER, WM_USER, PM_NOREMOVE );	

	// Signal that we have a valid thread ID and the thread message loop has 
	// been created.  It is now safe to call PostThreadMessage() to send 
	// messages to the threads.
	SetEvent ( pTC->m_Started ) ;

	// Initialize this thread as an apartment thread
	CoInitialize ( NULL );

	// run the message loop
	while ( m_bRun )
	{
		DWORD t_Event = MsgWaitForMultipleObjects ( 1, &((pTC)->m_hStopThread) , FALSE ,
			10000 , QS_ALLINPUT ) ;
	switch ( t_Event ) 
		{
			
		case WAIT_OBJECT_0:
			{
				m_bRun = FALSE;

				break;
			}
		case WAIT_OBJECT_0 + 1:
			{
				MessageLoop ( );

				break;
			}
		case WAIT_TIMEOUT:
			{
				m_bRun = TRUE;

				break;
			}
		default:
			{
				break;
			}
		}
	};

	SetEvent ( pTC->m_hComplete );

	CoUninitialize ( );
}


void CDmiInterfaceThread::MessageLoop ( )
{
	MSG msg;
	while ( PeekMessage ( &msg , NULL , 0 , 0 , PM_REMOVE ) )
	{
		HandleWMU ( msg );
	}
}



void CDmiInterfaceThread::HandleWMU( MSG& msg )
{

// Dump the messages that we've received for the thread.  The output will go
// to \\wbem\logs\messages.log
#if defined(TRACE_MESSAGES)
#if 0
	STAT_MESSAGE ( L"Called HandleWMU( m_dwThreadId = %lX, msg.message = %lX, \
msg.wParam = %lX, msg.lParam = %lX )\n\n", GetCurrentThreadId (),msg.message, msg.wParam, \
msg.lParam);
#else
		STAT_MESSAGE ( L"Receive ( msg = %lX, \
wParam = %lX, lParam = %lX )", msg.message, msg.wParam, \
msg.lParam);
#endif

#endif // TRACE_MESSAGES

	CDmiInterfaceJobContext* pJob = ( CDmiInterfaceJobContext*) msg.wParam;	

	try 
	{
		switch ( msg.message )
		{
		case WMU_GETCOMPONENT:
			{	
				dmiReadComponent ( pJob->pNWA , pJob->lComponent , pJob->pComponent ,
					pJob->pError );

				pJob->pComponent->SetNWA ( pJob->pNWA );				

				break;
			}
		case WMU_GETCOMPONENTS:
			{
				dmiReadComponents ( pJob->pNWA , pJob->pComponents , pJob->pError );

				pJob->pComponents->SetNWA ( pJob->pNWA );

				break;
			}							
		case WMU_GETROW:
			{
				dmiReadRow ( pJob->pNWA , pJob->lComponent , pJob->lGroup , 
 					pJob->pKeys , pJob->pRow , pJob->pError);

				pJob->pRow->SetData ( pJob->pNWA , pJob->lComponent , 
					pJob->lGroup );				

				break;
			}
		case WMU_GETNODE:
			{
				dmiReadNode ( pJob->pNWA , pJob->pNode , pJob->pError);

				pJob->pNode->SetNWA ( pJob->pNWA );

				break;
			}
			
		case WMU_ADDCOMPONENT:
			{
				dmiAddComponent ( pJob->pNWA , pJob->pszData , pJob->pError );

				break;
			}

		case WMU_DELETECOMPONENT:
			{
				dmiDeleteComponent ( pJob->pNWA , pJob->lComponent , pJob->pError);

				break;
			}

		case WMU_ADDGROUP:
			{
				dmiAddGroup ( pJob->pNWA , pJob->lComponent , pJob->pszData ,
					pJob->pError );				

				break;
			}
		case WMU_GETGROUPS:
			{
				dmiReadGroups ( pJob->pNWA , pJob->lComponent , pJob->pGroups ,
					pJob->pError );				

				pJob->pGroups->SetNWA ( pJob->pNWA );
				pJob->pGroups->SetComponent ( pJob->lComponent );

				break;
			}

		case WMU_GETGROUP:
			{
				dmiReadGroup ( pJob->pNWA , pJob->lComponent , pJob->lGroup ,
					pJob->pGroup , pJob->pError);				

				pJob->pGroup->SetNWA ( pJob->pNWA );
				pJob->pGroup->SetComponent ( pJob->lComponent );

				break;
			}

		case WMU_DELETEGROUP:
			{
				dmiDeleteGroup ( pJob->pNWA , pJob->lComponent , pJob->lGroup , 
					pJob->pError);

				break;
			}

		case WMU_ADDLANGUAGE:
			{
				dmiAddLanguage ( pJob->pNWA , pJob->lComponent , pJob->pszData , 
					pJob->pError);

				break;

			}

		case WMU_DELETELANGUAGE:
			{
				dmiDeleteLanguage ( pJob->pNWA , pJob->lComponent , pJob->pszData , 
					pJob->pError);

				break;
			}

		case WMU_GETENUM:
			{
				dmiReadEnum ( pJob->pNWA , pJob->lComponent , pJob->lGroup , 
					pJob->lAttribute , pJob->pEnum , pJob->pError);				

				pJob->pEnum->SetNWA ( pJob->pNWA );
				pJob->pEnum->SetComponent ( pJob->lComponent);
				pJob->pEnum->SetGroup ( pJob->lGroup );
				pJob->pEnum->SetAttrib ( pJob->lAttribute );

				break;
			}
		case WMU_SETLANG:
			{
				dmiSetDefaultLanguage ( pJob->pNWA , pJob->pszData , pJob->pError);

				break;
			}
		case WMU_GETLANGUAGES:
			{
				dmiGetLanguages ( pJob->pNWA , pJob->lComponent , pJob->pLanguages , 
					pJob->pError);

				break;
			}

		case WMU_GETROWS:
			{
				dmiReadRows ( pJob->pNWA , pJob->lComponent , pJob->lGroup , 
					pJob->pRows , pJob->pError);

				pJob->pRows->SetData ( pJob->pNWA , pJob->lComponent , 
					pJob->lGroup );

				break;
			}
		case WMU_ENABLEEVENTS:
			{
				dmiEnableEvents ( pJob->pNWA , pJob->pIClientSink );

				break;
			}	

		case WMU_DELETEROW:
			{
				dmiDeleteRow ( pJob->pNWA , pJob->lComponent , pJob->lGroup , 
					pJob->pKeys , pJob->pError);

				break;

			}
		case WMU_UPDATEROW:
			{
				dmiModifyRow ( pJob->pNWA , pJob->lComponent , pJob->lGroup , 
					pJob->pKeys , pJob->pRow , pJob->pError);

				break;
			}

		case WMU_ADDROW:
			{
				dmiAddRow ( pJob->pNWA , pJob->lComponent , pJob->lGroup , 
					pJob->pRow , pJob->pError );

				break;
			}

		default:

			{
			DispatchMessage ( &msg );

			break;
			}
		}
	}  // end try
	catch ( CException& e )
	{
		pJob->pError->SetWbemError ( e.WbemError () );
		pJob->pError->SetDescription ( e.DescriptionId () );
		pJob->pError->SetOperation ( e.OperationId () );
	}

	SetEvent ( ( HANDLE ) msg.lParam );
}

//////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////

CDmiInterface::CDmiInterface()
{
	m_bInit = FALSE;

	m_TC.StartThread ( );
}


CDmiInterface::~CDmiInterface()
{

}

void CDmiInterface::ShutDown ()
{
	m_TC.KillThread ();
}

void CDmiInterface::SendThreadMessage ( UINT msg , WPARAM wparam )
{
	LPARAM		lparam;
	CDmiError	Error;


	((CDmiInterfaceJobContext*)wparam)->pError = &Error;

	lparam = ( LONG ) CreateEvent ( NULL , FALSE , FALSE , NULL );

	// Wait to make sure that the we have a valid m_dwThreadID obtained in 
	// the Run() method before we attempt sending messages to the threads.
	if ( ! ( WaitForSingleObject ( m_TC.m_Started , INFINITE ) == WAIT_OBJECT_0 ) ) 
	{
		throw CException ( Error.WbemError() , Error.Description () , 
			Error.Reason () );
	}

// Dump the messages that we are going to send to the thread.  The output
// will go to \\wbem\logs\messages.log
#if defined(TRACE_MESSAGES)
#if 0
	STAT_MESSAGE ( L"Called SendThreadMessage( m_dwThreadId = %lX, \
msg = %lX, wParam = %lX, lparam = %lX )\n\n", m_TC.m_dwThreadId, msg, wparam, lparam );
#else
	STAT_MESSAGE ( L"Sending ( msg = %lX, wParam = %lX, lparam = %lX )", msg, wparam, lparam );
#endif

#endif // TRACE_MESSAGES

	
	BOOL t_PostStatus = PostThreadMessage ( m_TC.m_dwThreadId , msg , wparam , lparam);
	if ( ! t_PostStatus ) 
	{
		DWORD t_GetLastError = GetLastError () ;
		throw CException ( Error.WbemError() , Error.Description () , 
			Error.Reason () );
	}

	WaitForSingleObject ( ( HANDLE ) lparam , INFINITE );

	CloseHandle ( ( HANDLE ) lparam );

	if ( Error.HaveError () )
	{
		throw CException ( Error.WbemError() , Error.Description () , 
			Error.Reason () );
	}
}


void CDmiInterface::GetComponent ( LPWSTR pNWA  , LONG lComponent , 
								  CComponent* pComponent )
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.pComponent = pComponent;

	SendThreadMessage ( WMU_GETCOMPONENT , ( WPARAM ) &DmiC );
}


void CDmiInterface::GetComponents ( LPWSTR pNWA , 
								   CComponents* pNewComponents )
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.pComponents = pNewComponents;

	SendThreadMessage ( WMU_GETCOMPONENTS , ( WPARAM ) &DmiC );

}


void CDmiInterface::AddComponent ( LPWSTR pNWA  , CVariant& cvMifFile )
{	
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.pszData = cvMifFile.GetBstr();

	SendThreadMessage ( WMU_ADDCOMPONENT , ( WPARAM ) &DmiC );

}


void CDmiInterface::DeleteComponent ( LPWSTR pNWA  , LONG lComponent )
{		
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	SendThreadMessage ( WMU_DELETECOMPONENT , ( WPARAM ) &DmiC );

}


void CDmiInterface::AddGroup ( LPWSTR pNWA  , LONG lComponent , 
							  CVariant& cvMifFile )
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.pszData = cvMifFile.GetBstr();

	SendThreadMessage ( WMU_ADDGROUP , ( WPARAM ) &DmiC );

}


void CDmiInterface::AddLanguage ( LPWSTR pNWA , LONG lComponent , 
							  CVariant& cvMifFile )
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.pszData = cvMifFile.GetBstr();

	SendThreadMessage ( WMU_ADDLANGUAGE , ( WPARAM ) &DmiC );

}



void CDmiInterface::DeleteLanguage ( LPWSTR pNWA , LONG lComponent , 
							  CVariant& cvLanguage )
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.pszData = cvLanguage.GetBstr();

	SendThreadMessage ( WMU_DELETELANGUAGE , ( WPARAM ) &DmiC );

}


void CDmiInterface::GetEnum ( LPWSTR pNWA  , LONG lComponent , LONG lGroup ,
				LONG lAttribute , CEnum* pNewEnum )		
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.lGroup = lGroup;

	DmiC.lAttribute = lAttribute;

	DmiC.pEnum = pNewEnum;

	SendThreadMessage ( WMU_GETENUM , ( WPARAM ) &DmiC );
}



void CDmiInterface::DeleteRow ( LPWSTR pNWA  , LONG lComponent , LONG lGroup ,
				CAttributes& Keys )		
{

	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.lGroup = lGroup;

	DmiC.pKeys = &Keys;

	SendThreadMessage ( WMU_DELETEROW , ( WPARAM ) &DmiC );
}


void CDmiInterface::UpdateRow ( LPWSTR pNWA  , LONG lComponent , LONG lGroup ,
				CAttributes& Keys , CRow* pNewRowValues )		
{

	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.lGroup = lGroup;

	DmiC.pKeys = &Keys;

	DmiC.pRow = pNewRowValues;

	SendThreadMessage ( WMU_UPDATEROW , ( WPARAM ) &DmiC );

	


}

void CDmiInterface::GetRows ( LPWSTR pNWA  , LONG lComponent , LONG lGroup ,
				CRows* pNewRows )		 
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.lGroup = lGroup;

	DmiC.pRows = pNewRows;

	SendThreadMessage ( WMU_GETROWS , ( WPARAM ) &DmiC );

}

void CDmiInterface::GetRow ( LPWSTR pNWA  , LONG lComponent , LONG lGroup ,
				CAttributes& Keys , CRow* pNewRow )		
{
	
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.lGroup = lGroup;

	DmiC.pKeys = &Keys;

	DmiC.pRow = pNewRow;

	SendThreadMessage ( WMU_GETROW , ( WPARAM ) &DmiC );

}



void CDmiInterface::DeleteGroup ( LPWSTR pNWA , LONG lComponent , 
				LONG lGroup )
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.lGroup = lGroup;

	SendThreadMessage ( WMU_DELETEGROUP , ( WPARAM ) &DmiC );
}



void CDmiInterface::AddRow ( LPWSTR pNWA  , LONG lComponent , LONG lGroup , 
				CRow& Row)
{

	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.lGroup = lGroup;

	DmiC.pRow = &Row;

	SendThreadMessage ( WMU_ADDROW , ( WPARAM ) &DmiC );



}



void CDmiInterface::GetGroup ( LPWSTR pNWA , LONG lComponent , LONG lGroup ,
				CGroup* pNewGroup )
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.lGroup = lGroup;

	DmiC.pGroup = pNewGroup;

	SendThreadMessage ( WMU_GETGROUP , ( WPARAM ) &DmiC );

}


void CDmiInterface::GetGroups ( LPWSTR pNWA , LONG lComponent , CGroups* pNewGroups )
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.pGroups = pNewGroups;

	SendThreadMessage ( WMU_GETGROUPS , ( WPARAM ) &DmiC );
}


void CDmiInterface::GetNode ( LPWSTR pNWA  , CNode* pNewNode )
{	
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.pNode = pNewNode;

	SendThreadMessage ( WMU_GETNODE , ( WPARAM ) &DmiC );

}



void CDmiInterface::SetDefLanguage ( LPWSTR pNWA  , CVariant& cvLanguage )
{
	
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.pszData = cvLanguage.GetBstr();

	SendThreadMessage ( WMU_SETLANG , ( WPARAM ) &DmiC );
}


void CDmiInterface::GetLanguages ( LPWSTR pNWA , LONG lComponent , 
								  CLanguages* pNewLanguage )
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;

	DmiC.lComponent = lComponent;

	DmiC.pLanguages = pNewLanguage;

	SendThreadMessage ( WMU_GETLANGUAGES , ( WPARAM ) &DmiC );
}			

void CDmiInterface::EnableEvents ( LPWSTR pNWA , IWbemObjectSink*	pIClientSink )
{
	CDmiInterfaceJobContext		DmiC;

	DmiC.pNWA = pNWA;
	DmiC.pIClientSink = pIClientSink;

	SendThreadMessage ( WMU_ENABLEEVENTS , ( WPARAM ) &DmiC );
}