www.pudn.com > Ge_opc_Server_v1.rar > I_IM.CPP
// i_im.cpp
//
// This file contains the implementation of
// the IOPCItemMgt interface for groups in the LHEpipeview server.
//
//
// (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)
// Also fix some error handlers
//
//
#define WIN32_LEAN_AND_MEAN
#include "OPCLHEpipeview.h"
#include "OPCerror.h"
extern CRITICAL_SECTION CritSec;
/////////////////////////////////////////////////////////////////////////////
// Constructor /Destructor functions
//
///////////////////////////////////////
// ILHEpipeviewIM()
// Constructor for this Interface
//
///////////////////////////////////////
ILHEpipeviewIM::ILHEpipeviewIM( LPUNKNOWN parent )
{
m_Parent = (LHEpipeviewGroup *)parent;
}
///////////////////////////////////////
// ~ILHEpipeviewIM()
// Destructor for this Interface
//
///////////////////////////////////////
ILHEpipeviewIM::~ILHEpipeviewIM( void)
{
m_Parent->m_pILHEpipeviewIM = 0;
}
/////////////////////////////////////////////////////////////////////////////
// IUnknown functions Delegate to Parent
//
STDMETHODIMP_(ULONG) ILHEpipeviewIM::AddRef( void)
{
return m_Parent->AddRef();
}
STDMETHODIMP_(ULONG) ILHEpipeviewIM::Release( void)
{
return m_Parent->Release();
}
STDMETHODIMP ILHEpipeviewIM::QueryInterface( REFIID iid, LPVOID* ppInterface)
{
return m_Parent->QueryInterface(iid, ppInterface);
}
/////////////////////////////////////////////////////////////////////////////
// ILHEpipeviewIM (IOPCItemMgt) interface functions
//
///////////////////////////////////////
// AddItems
///////////////////////////////////////
STDMETHODIMP ILHEpipeviewIM::AddItems(
DWORD dwNumItems,
OPCITEMDEF * pItemArray,
OPCITEMRESULT ** ppAddResults,
HRESULT ** ppErrors
)
{
LHEpipeviewGroup &g = *m_Parent;
unsigned int i;
OPCHANDLE j;
OPCITEMRESULT *ir;
HRESULT *hr;
BOOL ok = TRUE;
LHEpipeviewItem *newitem;
// Defaults in case of error
//
*ppAddResults = ir = NULL; //acc001
*ppErrors = hr = NULL; //acc001
// First - allocate memory for the result array(s)
//
*ppAddResults = ir = (OPCITEMRESULT*)pIMalloc->Alloc(sizeof(OPCITEMRESULT) * dwNumItems); //acc001
if(ir == NULL) goto add_error;
*ppErrors = hr = (HRESULT*) pIMalloc->Alloc(sizeof(HRESULT) *dwNumItems); //acc001
if(hr == NULL) goto add_error;
// Now for each item...
//
for(i= 0; iInit(j, &pItemArray[i], &ir[i]);
if(FAILED(hr[i]))
{
delete newitem;
ok = FALSE;
continue;
}
g.ItemSet(j, newitem);
newitem->AddRef(); // Record the fact the the group has a pointer to it
}
if(ok) return S_OK;
return S_FALSE;
add_error:
if(hr) pIMalloc->Free(hr); //acc001
if(ir) pIMalloc->Free(ir); //acc001
*ppErrors = NULL;
*ppAddResults = NULL;
return E_OUTOFMEMORY;
}
///////////////////////////////////////
// ValidateItems
// Note this sample server accepts any item definition
// So any input will be validated as 'OK'
///////////////////////////////////////
STDMETHODIMP ILHEpipeviewIM::ValidateItems(
DWORD dwNumItems,
OPCITEMDEF * pItemArray,
BOOL bBlobUpdate,
OPCITEMRESULT ** ppValidationResults,
HRESULT ** ppErrors
)
{
unsigned int i;
OPCITEMRESULT *ir;
HRESULT *hr;
// Defaults in case of error
//
*ppValidationResults = ir = NULL; //acc001
*ppErrors = hr = NULL; //acc001
// First - allocate memory for the result array(s)
//
*ppValidationResults = ir = (OPCITEMRESULT*) pIMalloc->Alloc(sizeof(OPCITEMRESULT) * dwNumItems); //acc001
if(ir == NULL) goto val_error;
*ppErrors = hr = (HRESULT*) pIMalloc->Alloc(sizeof(HRESULT) *dwNumItems); //acc001
if(hr == NULL) goto val_error;
// Now for each item...
//
for(i= 0; iFree(hr); //acc001
if(ir) pIMalloc->Free(ir); //acc001
*ppErrors = NULL;
*ppValidationResults = NULL;
return E_OUTOFMEMORY;
}
///////////////////////////////////////
// RemoveItems
///////////////////////////////////////
STDMETHODIMP ILHEpipeviewIM::RemoveItems(
DWORD dwNumItems,
OPCHANDLE * phServer,
HRESULT ** ppErrors
)
{
LHEpipeviewGroup &g = *m_Parent;
unsigned int i;
OPCHANDLE j;
HRESULT *hr, r1;
BOOL ok = TRUE;
// First - allocate memory for the result array(s)
//
*ppErrors = hr = (HRESULT*) pIMalloc->Alloc(sizeof(HRESULT) *dwNumItems); //acc001
if(hr == NULL) return E_OUTOFMEMORY;
// Enter critical section whenever deleting anything
//
EnterCriticalSection(&CritSec);
// Now for each item handle...
//
for(i= 0; iRelease();
g.ItemFree(j);
hr[i] = S_OK;
}
if(ok) r1 = S_OK;
else r1 = S_FALSE;
LeaveCriticalSection(&CritSec);
return r1;
}
///////////////////////////////////////
// SetActiveState
///////////////////////////////////////
STDMETHODIMP ILHEpipeviewIM::SetActiveState(
DWORD dwNumItems,
OPCHANDLE * phServer,
BOOL bActive,
HRESULT ** ppErrors
)
{
LHEpipeviewGroup &g = *m_Parent;
unsigned int i;
OPCHANDLE j;
HRESULT *hr;
BOOL ok = TRUE;
// First - allocate memory for the result array(s)
//
*ppErrors = hr = (HRESULT*) pIMalloc->Alloc(sizeof(HRESULT) *dwNumItems); //acc001
if(hr == NULL) return E_OUTOFMEMORY;
// Now for each item handle...
//
for(i= 0; iSetActive(bActive);
hr[i] = S_OK;
}
if(ok) return S_OK;
return S_FALSE;
}
///////////////////////////////////////
// SetClientHandles
///////////////////////////////////////
STDMETHODIMP ILHEpipeviewIM::SetClientHandles(
DWORD dwNumItems,
OPCHANDLE * phServer,
OPCHANDLE * phClient,
HRESULT ** ppErrors
)
{
LHEpipeviewGroup &g = *m_Parent;
unsigned int i;
OPCHANDLE j;
HRESULT *hr;
BOOL ok = TRUE;
// First - allocate memory for the result array(s)
//
*ppErrors = hr = (HRESULT*) pIMalloc->Alloc(sizeof(HRESULT) *dwNumItems); //acc001
if(hr == NULL) return E_OUTOFMEMORY;
// Now for each item handle...
//
for(i= 0; iSetHandle(phClient[i]);
hr[i] = S_OK;
}
if(ok) return S_OK;
return S_FALSE;
}
///////////////////////////////////////
// SetDataTypes
///////////////////////////////////////
STDMETHODIMP ILHEpipeviewIM::SetDatatypes(
DWORD dwNumItems,
OPCHANDLE * phServer,
VARTYPE * pRequestedDatatypes,
HRESULT ** ppErrors
)
{
LHEpipeviewGroup &g = *m_Parent;
unsigned int i;
OPCHANDLE j;
HRESULT *hr;
BOOL ok = TRUE;
// First - allocate memory for the result array(s)
//
*ppErrors = hr = (HRESULT*) pIMalloc->Alloc(sizeof(HRESULT) *dwNumItems); //acc001
if(hr == NULL) return E_OUTOFMEMORY;
// Now for each item handle...
//
for(i= 0; iSetDatatype(pRequestedDatatypes[i]);
if(FAILED(hr[i]))
{
ok = FALSE;
continue;
}
}
if(ok) return S_OK;
return S_FALSE;
}
///////////////////////////////////////
// CreateEnumerator
///////////////////////////////////////
STDMETHODIMP ILHEpipeviewIM::CreateEnumerator(
REFIID riid,
LPUNKNOWN * ppUnk
)
{
// default in case of error
//
*ppUnk = NULL; //acc001
if ( riid == IID_IEnumOPCItemAttributes)
{
ILHEpipeviewEnumIA *temp;
OPCITEMATTRIBUTES* AttrList;
int ItemCount;
HRESULT hr;
// Get a 'local' snapshot of the item list
//
m_Parent->GetItemList( &AttrList, &ItemCount);
// Create the Enumerator which will contain a copy of the snapshot
// Note that the enumerator is not affected by
// subsequent changes to the item list.
// The group will get an 'addref' via m_Parent below and will thus
// stay around until the enumerator is released
// (although this is probably unnecessary)
//
temp = new ILHEpipeviewEnumIA(m_Parent, ItemCount, AttrList, pIMalloc);
m_Parent->FreeItemList( AttrList, ItemCount); //acc001
// 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( riid, (LPVOID*)ppUnk);
if ( FAILED( hr))
{
delete temp;
return hr;
}
return S_OK;
}
return E_INVALIDARG;
}