www.pudn.com > Ge_opc_Server_v1.rar > SERVER.CPP


// Server.cpp 
// 
//  This file contains the implementation of 
//  the LHEpipeview Server Object for the OPC server. 
// 
// This implementation uses 'tear off' interfaces 
// (I.e. the interfaces are separate from the object 
//  which supports only IUnknown) 
// 
// 
//	(c) COPYRIGHT 1996,1997 INTELLUTION INC. 
// ALL RIGHTS RESERVED 
// 
// Original Author: Al Chisholm 
// 
// Modification Log: 
// Vers    Date   By    Notes 
// ----  -------- ---   ----- 
// 0.00  11/18/96 ACC 
// 0.01  02/05/97 acc   Fix memory leaks (see acc001) 
// 0.90  04/08/97 ACC   add async logic/UpdateData 
// 
// 
 
#define WIN32_LEAN_AND_MEAN 
 
#include "OPCLHEpipeview.h" 
#include "OPCTHRD.h" 
 
extern CRITICAL_SECTION	CritSec; 
 
///////////////////////////////////////////////////////////////////////////// 
// Constructor /Destructor functions 
// 
 
/////////////////////////////////////// 
// OPCServer() 
//   Constructor for the OPC Server. 
// 
/////////////////////////////////////// 
LHEpipeviewServer::LHEpipeviewServer( LPUNKNOWN pOuter, void (*pfn)(void)) 
{ 
	int	j; 
	SYSTEMTIME SystemTime; 
 
	mRefCount = 0; 
 
	// Clear out 'tear-off' interface ptrs 
	// The interfaces will be created as needed in QueryInterface 
	// 
	m_pIServer = 0; 
	m_pISPG = 0; 
	m_pIBSAS = 0; 
	m_pIPF = 0; 
 
	GetSystemTime(&SystemTime);		// Get current UTC Time 
	SystemTimeToFileTime(&SystemTime, &mLastUpdate); // and store it 
 
	m_pfnDestroy = pfn; 
 
	m_tid = 0; 
 
	// Clear out the 'Groups' 
	// This simple example only holds 10 groups 
	// A real implementation would use some sort 
	// of container or linked list 
	// 
	for (j=0; jRelease(); 
		} 
	} 
 
	// Then delete any tear off interfaces 
	// 
	if(m_pIServer) delete m_pIServer; 
//	if(m_pISPG) delete m_pISPG; 
//	if(m_pIBSAS) delete m_pIBSAS; 
	if(m_pIPF) delete m_pIPF;		//acc001 
 
	LeaveCriticalSection(&CritSec); 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// IUnknown functions 
// 
 
/////////////////////////////////////// 
// IUnknown::AddRef() 
//   Standard IUnknown implementation 
// 
/////////////////////////////////////// 
STDMETHODIMP_(ULONG) LHEpipeviewServer::AddRef( void) 
{ 
	return ++mRefCount; 
} 
 
 
 
/////////////////////////////////////// 
// IUnknown::Release() 
//   Standard IUnknown implementation 
// 
/////////////////////////////////////// 
STDMETHODIMP_(ULONG) LHEpipeviewServer::Release( void) 
{ 
	ULONG currentCount = --mRefCount; 
 
	// If no references left for this server 
	if ( currentCount == 0) 
	{ 
		// Then delete this server. 
		// 
		if(m_pfnDestroy) (*m_pfnDestroy)();	// DLL or EXE can unload if last one 
		delete this; 
	} 
	return currentCount; 
} 
 
 
/////////////////////////////////////// 
// IUnknown::QueryInterface() 
//   Standard IUnknown implementation using 
//   'tear off' interfaces 
// 
/////////////////////////////////////// 
STDMETHODIMP LHEpipeviewServer::QueryInterface( REFIID iid, LPVOID* ppInterface) 
{ 
	// check valid pointer 
	// 
	if ( ppInterface == NULL) 
		return E_INVALIDARG; 
 
	// default return is NULL in case of error 
	// 
	*ppInterface = NULL; 
 
	if ( iid == IID_IUnknown ) 
	{ 
		*ppInterface = (IUnknown*) this; 
	} 
 
	else if ( iid == IID_IOPCServer) 
	{ 
		if(m_pIServer == 0) m_pIServer = new ILHEpipeviewServer(this); 
		*ppInterface = m_pIServer; 
	} 
//	else if (iid == IID_IOPCServerPublicGroups) 
//	{ 
//		if(m_pISPG == 0) m_pISPG = new ILHEpipeviewOPCServerPublicGroups(this); 
//		*ppInterface = m_pISPG; 
//	} 
//	else if (iid == IID_IOPCBrowseServerAddressSpace) 
//	{ 
//		if(m_pIBSAS == 0) m_pIBSAS = new ILHEpipeviewOPCBrowserServerAddressSpace(this); 
//		*ppInterface = m_pIBSAS; 
//	} 
	else if ((iid == IID_IPersistFile) || (iid == IID_IPersist)) 
	{ 
		if(m_pIPF == 0) m_pIPF = new ILHEpipeviewPF(this); 
		*ppInterface = m_pIPF; 
	} 
	else if ( iid == IID_IEnumUnknown) 
	{ 
		// Note enumerators are special in that they are independent objects 
		// They are not just interfaces on an existing object 
		// 
		HRESULT hr; 
		ILHEpipeviewEnumUnknown *temp; 
		LPUNKNOWN * GroupList; 
		int	GroupCount; 
 
		// Get a snapshot of the group list 
		// (Note this does NOT do AddRefs to the groups - but see ILHEpipeviewEnum below) 
		// 
		GetUnkList(OPC_ENUM_ALL_CONNECTIONS, &GroupList, &GroupCount); 
 
		// Create the Enumerator using the snapshot (which might be empty) 
		// Note that the enumerator constructor will AddRef 
		// all of the groups. 
		// 
		temp = new ILHEpipeviewEnumUnknown(this, GroupCount, GroupList, pIMalloc); 
		delete [] GroupList; 
 
		if ( temp == NULL) 
			return E_OUTOFMEMORY; 
 
		// Then QI for the interface ('temp') actually is the interface 
		// but QI is the 'proper' way to get it. 
		// Note QI will do an AddRef of the Enum which will also do 
		// an AddRef of the 'parent' - i.e. the 'this' pointer passed above. 
		// 
		hr = temp->QueryInterface( iid, ppInterface); 
		if ( FAILED( hr)) 
		{ 
			delete temp; 
			return hr; 
		} 
 
		// If all OK - return here 
		// Unlike most interfaces this one does NOT directly addref the server 
		// (since we created a new and independent object) 
		// 
		return S_OK; 
	} 
 
 
	if ( *ppInterface == NULL) 
		return E_NOINTERFACE; 
 
	AddRef(); 
	return S_OK; 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Private (non-OPC) Utility Functions 
// 
 
 
/////////////////////////////////////// 
// LHEpipeviewServer::GetNameList() 
// Create a list of all the group names 
// 
void LHEpipeviewServer::GetNameList( OPCENUMSCOPE scope, LPOLESTR**GroupList, int *GroupCount) 
{ 
	int	j, count = 0; 
	LPOLESTR *mylist; 
 
	// Defaults... 
	*GroupList = NULL; 
	*GroupCount = 0; 
 
	// First pass - count private groups in use 
	// 
	for (j=0; jm_szName, NULL); 
				(*GroupCount)++; 
			} 
		} 
		break; 
 
	case OPC_ENUM_PUBLIC: 
	case OPC_ENUM_PUBLIC_CONNECTIONS: 
	default: 
		break; 
	} 
} 
 
/////////////////////////////////////// 
// LHEpipeviewServer::FreeNameList() 
// Free a list of group names 
// 
void LHEpipeviewServer::FreeNameList( LPOLESTR*GroupList, int count) 
{ 
	int j; 
 
	if(!count) return; 
 
	for(j=0; jAsyncHelper(tics); 
		} 
	} 
 
	LeaveCriticalSection(&CritSec); 
} 
 
 
/////////////////////////////////////// 
// LHEpipeviewServer::GenerateTransactionID 
// 
void LHEpipeviewServer::GenerateTransaction(DWORD *pTID) 
{ 
	m_tid++; 
	if(m_tid == 0) m_tid++;	// 0 is not a legal TID 
	*pTID = m_tid; 
}