The WinTECH Software Rapid Development DLL for OPC Servers, (WTOPCSvr), provides an easy to use API for integrating custom data with OPC. All the details of COM and OPC are handled by the DLL, which allows an application to present data points to OPC at a high-level, without having to be concerned with the actual implementation of the underlying interfaces. The DLL may be easily integrated with existing applications, or new ones. All required OPC Interfaces are supported for both OPC 1.0 and OPC 2.0 Data Access Standards as well as the Browse Interface.
WTOPCSvr basically operates as a data librarian. The controlling application creates Process Tags by passing a name and value to the DLL. The DLL records the data point and makes it available to any OPC Client application by name. The controlling application may change the value of the data at any time, and all attached clients would be automatically notified. Callback notification is provided for any Process Tag that is modified by an OPC Client connection. (The application has control over which tags are OPC_WRITEABLE.)
WTOPCSvr now supports dynamic creation of OPC Tags. A callback function is supplied which returns control to the application if a client requests a tag that has not been previously defined. The application may in turn create the tag using the requested path and name combination or ignore the request.
Creating a Custom OPC Server using WTOPCSvr.DLL
Installing the OPC Proxy DLL’s
The first step in creating an OPC Server is to obtain and install the OPC Proxy/Stub DLL’s from OPCFoundation (http://www.opcfoundation.org)
Download and upzip the proxy/stub files.
Copy opccomn_ps.dll, opcproxy.dll, opcae_ps.dll, opchda_ps.dll to the SYSTEM32 Directory. *Be sure not to overwrite any newer versions*
Type REGSVR32 opccomn_ps.dll
Type REGSVR32 opcproxy.dll
Type REGSVR32 opc_aeps.dll
Type REGSVR32 opchda_ps.dll
You will also need to download and install the OPC Server Browser Object supplied by the OPC Foundation. The OPC Foundation also advises that you verify that your system contains the actxprxy.dll and if not, install the ActiveX Redistributable Installation Kit from Microsoft. The aprxdist.zip file containing the Microsoft software is also available from the OPC Foundation Web-Site.
Link WTOPCSvr.lib with the Application
WTOPCSvr.lib contains the export definitions for the DLL’s API. Include this file with the project files for the custom application and include WTOPCSvrAPI.h with those modules which will be making calls into the DLL.
Generate a new CLSID
Each OPC Server is identified by a unique CLSID. The GUIDGen.exe utility supplied by Microsoft may be used to generate a unique identifier for the new server application. Run GUIDGen.exe, (located in the Visual C++\Bin directory). Generate a new CLSID and copy to the clipboard to be pasted in to your server application as described below.
Registry Entries
The WTOPCSvr.DLL exports two API functions that make modifications to the Windows Registry for installation of the custom server.
UpdateRegistry (BYTE *pCLSID_Svr, LPCSTR Name, LPCSTR Descr, LPCSTR ExePath);
UnregisterServer (BYTE *pCLSID_Svr, LPCSTR Name);
These functions take as arguments the CLSID generated above, (as well as text strings to identify and describe the new server). While the UpdateRegistry and UnregisterServer functions may be called from the controlling application at any time, it is generally preferred to implement the registry functions based on command-line entries during start-up of the application. A self-registering server would process the \RegServer and \UnregServer command line options similar to the code below, (extracted from OPCSimSvr Application):
const GUID
CLSID_OPCSimSvr = {0x99b8f471, 0xc027, 0x11d2, {0x80, 0xb8, 0x0, 0x60, 0x97, 0x58, 0x58, 0xbe}};
BOOL COPCSimSvrApp::InitInstance()
{
TCHAR szTokens[] = _T("-/ ");
CString HelpPath;
CString SvrName, SvrDescrip;
int i;
HelpPath = AfxGetApp()->m_pszHelpFilePath;
i = HelpPath.ReverseFind('\\');
HelpPath = HelpPath.Left(i+1);
HelpPath += "OPCSIMSVR.EXE";
//
// Self-Registration code
// (look for cmdline options to register & unregister server)
//
SvrName = "WinTECH.OPCServer";
SvrDescrip = "WinTECH Software OPC Server Simulator";
CString tempCmdLine(m_lpCmdLine);
LPTSTR lpszToken = _tcstok(tempCmdLine.GetBuffer(1), szTokens);
while (lpszToken != NULL)
{
if (_tcsicmp(lpszToken, _T("UnregServer"))==0)
{
UnregisterServer ((BYTE *)&CLSID_OPCSimSvr, SvrName);
return (FALSE);
}
else if (_tcsicmp(lpszToken, _T("RegServer"))==0)
{
UpdateRegistry ((BYTE *)&CLSID_OPCSimSvr,
SvrName,
SvrDescrip,
HelpPath);
return (FALSE);
}
lpszToken = _tcstok(NULL, szTokens);
}
Initialization of WTOPCSvr.DLL
The Windows Registration functions described above may be called prior to the initialization of the WTOPCSvr.DLL. During the self-registration process, the focus is on making the necessary changes to the Registry and then exiting the application. There is no need at this point to go through the effort of initializing DCOM and loading up the OPC Server support. The exported function:
InitWTOPCsvr (BYTE *pCLSID_Svr, UINT ServerRate);
does just that. When this function is executed, the DLL performs all necessary initialization of COM/DCOM and creates the OPCServer Interface object to be used for client connections. The specified ServerRate defines how fast the OPC Client data connections are refreshed.
Creating Process Tags
After initialization, the WTOPCSvr.DLL is now ready to accept data points from the custom application. Three exported functions are provided:
CreateTag (LPCSTR Name, VARIANT Value, WORD InitialQuality, BOOL IsWriteable);
UpdateTag (HANDLE TagHandle, VARIANT Value, WORD Quality);
UpdateTagByName (LPCSTR Name, VARIANT Value, WORD Quality);
SetWtOPCsvrQualifier (char Delimiter);
As each process tag is created, the DLL returns a HANDLE to identify the point for future references, (updates), from the application. The naming convention used by WTOPCSvr.DLL for browsing operations, (OPC_NS_FLAT or OPC_NS_HIERARCHIAL), is a function of how the names are assigned by the controlling application. If segmented names are used to create the tags, (strings containing the delimiter ‘.’,
such as “PLANT A.PROCESS1.TAG17”), WTOPCsvr.DLL will automatically configure the name space as hierarchial, otherwise a flat name space is used. If you want to use a delimiting character other than ‘.’, you can select it using SetWtOPCsvrQualifier().
Dynamic Tag Creation
If the design warrants, WTOPCSvr.DLL may be used to provide for dynamic creation of OPC Tags as requested by attached clients. Rather than create all the OPC Tags up-front, the application may choose to have the DLL issue a callback function whenever an OPC Client requests a tag name that is not already listed.
EnableUnknownItemNotification (UNKNOWNITEMPROC lpCallback);
If enabled, the callback function will receive control anytime a client requests a tag that has not been previously defined. The requested tag name and path may then be used as arguments to CreateTagA() to dynamically create the tag before returning from the callback and giving control back to the client. If the application chooses to ignore the request, the client will receive a OPC_E_UNKNOWNITEMID response from the DLL.
WTOPCSvr.DLL also supports a user callback function that indicates when the last client reference to a tag has been removed. This may be used by the server application to delete the tag when it is no longer needed. The following exported function enables this functionality:
EnableItemRemovalNotification (ITEMREMOVEDPROC lpCallback);
The callback will receive the handle to the removed item, as well as the path and item names.
Write Callback Notification
If process tags are created as OPC_WRITEABLE, attached client applications may change the value of data points contained within WTOPCSvr.DLL. WTOPCSvr.DLL provides the ability for the controlling application to define a callback routine for notification of client writes. This would be required in most situations to allow the server application to accept the new value and perform the write to the actual device.
EnableWriteNotification (WRITENOTIFYPROC lpCallback);
If enabled, the callback function will receive the HANDLE of any data point written by an attached OPC Client, as well as the value to be written and a pointer to an error DWORD to allow feedback to the client if the write operation fails
Clean-up Functions
The only remaining functions exported from WTOPCSvr.DLL provide the mechanism for gracefully closing the custom server.
int NumbrClientConnections ();
void RequestDisconnect ();
RemoveTag (HANDLE TagHandle);
UninitWTOPCsvr();
Generally, the server logic should check to see if any OPC Clients are connected before allowing the application to close. OPC 2.0 clients may be requested to disconnect. Any tags created by the application should be removed using the defined function. The UnintWTOPCsvr() function calls CoUnitialize and should be placed in the ExitInstance procedure of the application.
Performance Related Functions
Beginning with version 4.0 of the WtOPCsvr.dll, there have been several extended API functions added to support more efficient updating for large item counts. The dll now supports an option to use hashing for storage and lookup of text strings representing item names. Significant performance gains are provided in the areas of intensive string manipulation such as the item browsing functions. A second series of API functions improves upon the data update cycle by updating multiple items with a single command rather than one at a time. The WtSvrTst2 example application that is packaged with the WtOPCsvr.dll may be used to generate performance numbers using various tag counts and various combinations of these two options. Refer to the API descriptions below for detailed information relative to the use of these functions.
OPC Alarms & Events
The WtOPCsvr.dll provides basic support for the Alarms & Events standard by providing level checking for each process tag. The dll will automatically create an OPC A&E Server using the same CLSID as the Data Access Server. As each tag is created, the controlling application may specify two levels of high and low alarm limits surrounding it’s value. As a tag’s value is updated, either by the controlling application or by an attached client, the dll will check its value against these limits and generate the appropriate A&E messages if exceeded. These messages are accessible from any standard OPC A&E client application. WtOPCsvr.dll also exports functions that allow the controlling application to generate textual events to any interested client. Finally, if greater control over A&E Server operation is desired, the application may disable the internal limit checking and process all the A&E Interface calls from a client directly. A simple callback object is provided that may be overridden by the application to process the individual A&E Interfaces as required.
NT Security Additions
To accommodate OPC Server designs where it is desired to control access to certain tags based on the identity of the connected user, WtOPCsvr.dll supports api functions that allow a security mask to be applied for both read and write access to individual tags. The user may then define a list of user names with specific rights. When the security option is enabled, WtOPCsvr.dll will verify the access rights of the client against the sever defined user list and allow or deny access accordingly. Additionally, an extended write callback is provided that contains the user name of the client making a write requiest for a tag. This information may then be used to maintain an audit trail of users who have updated a particular tag.
WTOPCSvr.DLL Exported functions
Initialization and Registry Functions
BOOL InitWTOPCsvr (BYTE *pCLSID_Svr, UINT ServerRate);
Use this function to initialize DCOM and create the OPC Server.
CLSID_Svr defines the CLSID which OPC Clients will use to connect to this server.
ServerRate is expressed in msecs and defines the rate at which client connections are updated.
The return value will be TRUE if the function succeeds, otherwise FALSE.
BOOL UpdateRegistry (BYTE *pCLSID_Svr, LPCSTR Name, LPCSTR Descr, LPCSTR ExePath);
This function makes modifications to the Windows Registry to allow other applications to find and execute the server.
CLSID_Svr defines the CLSID which OPC Clients will use to connect to this server,
(this is a BYTE Pointer to the C-style GUID structure).
Name defines the Server Name
Descr may be anything to describe the server, and will usually contain the vendor name.
ExePath defines the full Windows Directory path to the executable (i.e. c:\OPC\test\mysvr.exe).
The return value will be TRUE if the function succeeds, otherwise FALSE.
BOOL AddLocalServiceKeysToRegistry (LPCSTR Name);
This function makes additional modifications to the Windows Registry to allow the server to run as an NT Service.
Name defines the Server Name
BOOL UnregisterServer (BYTE *pCLSID_Svr, LPCSTR Name);
This function removes entries from the Windows Registry.
CLSID_Svr defines the CLSID which OPC Clients will use to connect to this server.
Name defines the Server Name
The return value will be TRUE if the function succeeds, otherwise FALSE.
Tag Creation & Update Functions
HANDLE CreateTag (LPCSTR Name, VARIANT Value, WORD InitialQuality, BOOL IsWriteable);
This function creates a process tag within WTOPCSvr.DLL.
Name defines the identifier that OPC Clients will use to access the tag. This name may be any string of text as required by the server. Segmented names, (those containing the delimiter character ‘.’), are valid and will cause WTOPCSvr.DLL to structure the OPC name space as hierarchial, for browsing operations.
Value defines the initial data to be associated with the tag
InitialQuality defines the OPC Quality flags associated with the tag.
IsWriteable determines whether or not the tag may be written from an OPC Client
The return value will be a HANDLE to the created point or INVALID_HANDLE_VALUE if the tag could not be created.
BOOL SetTagProperties (HANDLE TagHandle, DWORD PropertyID, LPCSTR Description,
VARIANT Value);
Any number of OPC Item properties may be set for a defined tag with this function. The DLL maintains a list of all defined properties and their current value for access by an OPC Client.
The return value will be TRUE if the function succeeds, otherwise FALSE.
BOOL UpdateTag (HANDLE TagHandle, VARIANT Value, WORD Quality);
BOOL UpdateTagWithTimeStamp (HANDLE TagHandle, VARIANT Value, WORD Quality, FILETIME timestamp);
This function allows the controlling application to change the value, quality flag, and timetstammp of a defined process tag. If the timestamp is not supplied by the application, the dll will use the current PC time setting.
TagHandle defines the point.
Value defines the new data.
Quality defines the new Quality condition
The return value will be TRUE if the function succeeds, otherwise FALSE.
BOOL UpdateTagByName (LPCSTR Name, VARIANT Value, WORD Quality);
This function also allows the controlling application to change the value and quality flags of a defined process tag.
Name defines the point.
Value defines the new data.
Quality defines the new Quality condition
The return value will be TRUE if the function succeeds, otherwise FALSE.
unsigned long SetHashing (unsigned long HashSize);
Enables hashing and sets the suggested hash table size.
BOOL StartUpdateTags();
BOOL WINAPI UpdateTagToList (HANDLE TagHandle, VARIANT Value, WORD Quality);
BOOL WINAPI EndUpdateTags ();
These three functions must be used together, and provide a more efficient means of updating multiple tags. UpdateTagToList replaces UpdateTag call, requires prior StartUpdateTags else fails and EndUpdateTags after all tags are updated.
BOOL SuspendTagUpdates (HANDLE TagHandle, BOOL OnOff);
This function may be used in conjunction with the Unknown Item callback to allow the server application to know when a particular tag is being subscribed to by a client. In most cases, the server application will continuously update the tags as their respective values change. The dll will then handle all client subscriptions, notifications and updates. In certain situations, it’s desirable for the server to only update the OPC Tag database whenever a client is actively subscribing to an item. By suspending updates, the dll will issue the UNKNOWNITEM callback whenever a client attempts to subscribe to the item. The server may then resume updates and wait for the ITEMREMOVED callback to again suspend updates.
TagHandle defines the item to be suspended.
OnOff suspends or resumes updates. (The application should call SuspendTagUpdates (.., TRUE)
After the first UNKNOWNITEM notification to prevent additional callbacks if another client subscribes to the same data point).
The return value will be TRUE if the function succeeds, otherwise FALSE.
BOOL ReadTag (HANDLE TagHandle, VARIANT *pValue);
BOOL ReadTagWithTimestamp (HANDLE TagHandle, VARIANT *pValue, WORD *pQuality,
FILETIME *pTimestamp);
This function allows the application to obtain the current value of a defined tag contained within WTOPCSvr.DLL.
TagHandle defines the point.
pValue points to the buffer to receive the data.
pQuality points to a value to receive the OPC Quality indication.
pTimeStamp receives the current timestamp for the tag.
The return value will be TRUE if the function succeeds, otherwise FALSE.
BOOL RemoveTag (HANDLE TagHandle);
This function removes a process tag from the WTOPCSvr.DLL. If client connections are accessing the point when it is removed, the connection will remain valid, but no new data will be presented to the client.
TagHandle defines the point.
The return value will be TRUE if the function succeeds, otherwise FALSE.
Callback Notification Functions
BOOL EnableUnknownItemNotification (UNKNOWNITEMPROC lpCallback);
This function defines the callback routine that receives control from the WTOPCSvr.DLL whenever a client requests an OPC Tag that has not been previously defined.
lpCallback points to a routine defined such as the following:
void CALLBACK EXPORT UnknownTagProc (LPSTR Path, LPSTR Name)
Path defines the requested path name.
Name defines the requested tag name.
BOOL EnableItemRemovalNotification (ITEMREMOVEDPROC lpCallback);
This function defines the callback routine that receives control from the WTOPCSvr.DLL whenever the last client reference to a defined tag is removed.
lpCallback points to a routine defined such as the following:
void CALLBACK EXPORT RemoveTagProc (HANDLE hTag, LPSTR Path, LPSTR Name)
hTag specifies the handle of the tag that has been removed.
Path defines the requested path name.
Name defines the requested tag name.
BOOL EnableWriteNotification (WRITENOTIFYPROC lpCallback, BOOL ConvertToNativeType);
This function defines the callback routine which receives control from the WTOPCSvr.DLL whenever an OPC Client application writes to a defined process tag. Normally, the dll would be configured to convert values to the item’s native variant type, but in some cases it may be desirable for the application itself to perform special conversion processing.
lpCallback points to a routine defined such as the following:
void CALLBACK EXPORT NotificationHandler (HANDLE handle,
VARIANT *pNewValue, DWORD *pDeviceError)
handle defines the handle of the process tag which was written.
pNewValue defines the value to be written. The application needs to write the new value to the actual device and call UpdateTag to update the new value to the DLL cache.
pDeviceError allows the application to flag an error back to the client if the data value cannoty be written.
BOOL EnableDisconnectNotification (DISCONNECTPROC lpCallback);
This function defines the callback routine which receives control from the WTOPCSvr.DLL whenever an OPC Client application disconnects.
lpCallback points to a routine defined such as the following:
void CALLBACK EXPORT DisconnectHandler (DWORD Numbr)
Numbr defines the the number of client connections remaining.
BOOL EnableEventMsgs (EVENTMSGPROC lpCallback);
This function allows the server application to receive event messages from the WtOPCsvr.dll during normal operation of the OPC Server Interfaces. Event messages are available as a debugging tool to trace execution of the logic through the various Interface procedures.
lpCallback points to a routine defined such as the following:
void CALLBACK EXPORT EventHandler (LPCSTR Msg)
Msg is a byte string describing the event.
BOOL EnableRateNotification (RATECHANGEPROC lpCallback);
This function defines a callback procedure that receives control whenever the minimum request update rate for an item changes. Various clients may request an item from the server at different rates. This callback allows the server application to optimize it’s data acquisition logic to obtain the data for an item at the most efficient rate.
lpCallback points to a routine defined such as the following:
void CALLBACK EXPORT RateChangeHandler (HANDLE hItem, DWORD Rate)
hItem defines the item.
Rate is the newly requested update rate.
BOOL EnableDeviceRead (DEVICEREADPROC lpCallback);
This function allows the application to supply a callback procedure to service DEVICE_READ requests from a client. The callback, if defined, will be called whenever a client requests a SyncIO::Read with dwSource set to OPC_DS_DEVICE. If the callback is not defined, WtOPCsvr.dll will treat OPC_DS_DEVICE as OPC_DS_CACHE
lpCallback points to a routine defined such as the following:
void CALLBACK EXPORT DeviceReadHandler (HANDLE hItem, VARIANT *pValue,
WORD *pQuality, FILETIME *pTimestamp)
hItem defines the item.
*pValue, *pQuality, and *pTimestamp are to be supplied by the application to represent the current value of the defined item.
Miscellaneous Functions
char SetWtOPCsvrQualifier (char qualifier);
This function sets the delimiting character used by the dll to segment the node names of a hiearchial namespace. The default delimiter is the ‘.’ character.
int NumbrClientConnections ();
This function returns the number of OPC Clients currently connected to WTOPCSvr.DLL
void RequestDisconnect ();
This function requests that all OPC Clients disconnect from the server. This function does not guarantee that the request will be honored, or that the clients will actually disconnect. The ability for an OPC Server to request a client disconnect only applies to those clients connected according to the OPC 2.0 specification.
BOOL RefreshAllClients ();
This function may be used by the server application to initiate a refresh operation to all attached OPC Clients. Normally, client applications are refreshed based on an asynchronous clock tick within the WTOPCSvr.DLL. This function may be used to force the server to update all client data.
The return value will be TRUE if the function succeeds, otherwise FALSE.
BOOL ResetServerRate (UINT ServerRate);
This function may be used by the server application to change the current setting for the rate at which data is refreshed by the server.
The return value will be TRUE if the function succeeds, otherwise FALSE.
BOOL SetVendorInfo (LPCSTR VendorInfoString);
The application may set the vendor information description that is returned by the server in response to a client request for Server Information..
The return value will be TRUE if the function succeeds, otherwise FALSE.
void SetServerState (OPCSERVERSTATE SvrState);
This function allows the application to set the state of the server as accessed by a client. Useful during design and commissioning to display internal diagnostics related to server operation.
Alarms & Events Functions
BOOL SetItemLevelAlarm (HANDLE TagHandle, int LevelID, float Limit, DWORD Severity,
BOOL Enabled);
Multiple levels of alarms may be configured for each defined Tag. If enabled, WtOPCsvr will check the alarm limits and notify any attached OPC Alarms & Events Client of level changes as an item is updated. LevelID refers to the following literal definitions:
#define ID_LOLO_LIMIT 1
#define ID_LO_LIMIT 2
#define ID_HI_LIMIT 3
#define ID_HIHI_LIMIT 4
BOOL GetItemLevelAlarm (HANDLE TagHandle, int LevelID, float *pLimit, DWORD *pSeverity,
BOOL *pEnabled);
This function allows the application to retrieve the associated alarm limits for a given Tag
BOOL UserAEMessage (LPCSTR Msg, DWORD Severity);
BOOL UserAEMessageEx (ONEVENTSTRUCT Msg);
BOOL UserAEMessageEx2 (DWORD hEventSubscription, ONEVENTSTRUCT Msg, BOOL bRefresh, BOOL bLastRefresh);
These functions send a user-defined event message to all connected OPC Alarm & Event Clients.
CwtAExCallback Functions
The application can use the CWtAExCallback object definition described below to generate overloaded functions to change the default behavior of the WtOPCsvr.dll with regard to Alarms & Events.
Basic support for Alarms & Events is supplied by the dll in the form of High & Low level alarms surrounding each defined OPC Item. As the data values change, these level limits are compared and event messages generated as appropriate. The default behavior of the WtOPCsvr.dll does not provide for acknowledgements from an OPC Client or any filtering to be applied to the event subscription.
By basing a C++ object on the CWtAExCallback object and overloading any of the virtual functions the application can expand upon or replace the basic A&E functionality of the dll as required.
virtual HRESULT GetStatus (OPCEVENTSERVERSTATUS** ppEventServerStatus,
FILETIME LastUpdateTime);
This function is called by the dll based upon CIOPCEventServer::GetStatus(...).
The dll supplies the Last Update Time parameter to match the requesting subscriber. The default implementation of this function returns valid parameters to the client. Only overload this function if you have specific information to add to the status structure
virtual HRESULT QueryAvailableFilters (DWORD *pdwFilterMask);
This function is called from CIOPCEventServer::QueryAvailableFilters(...)
The default implementation of this function returns zero for the FilterMask and
S_OK, (i.e. Filters not supported!)
virtual HRESULT QueryEventCategories (DWORD dwEventType,
DWORD *pdwCount,
DWORD **ppdwEventCategories,
LPWSTR **ppszEventCategoryDescs);
This function is called from CIOPCEventServer::QueryEventCategories (...).
The default implementation of this function supports two categories
OPC_SIMPLE_EVENT -- OPC_MSG_CAT:System Message
OPC_CONDITION_EVENT -- OPC_LEVEL_CAT:Level
-- OPC_DISCRETE_CAT:Discrete
virtual HRESULT QueryConditionNames ( DWORD dwEventCategory,
DWORD *pdwCount,
LPWSTR **ppszConditionNames);
This function is called from CIOPCEventServer::QueryConditionNames (...)
The default implementation of this function returns the following condition names
OPC_MSG_CAT -- "Informational Text"
OPC_LEVEL_CAT -- "Level Alarm"
OPC_DISCRETE_CAT -- "Discrete Alarm"
virtual HRESULT QuerySubConditionNames ( LPWSTR szConditionName,
DWORD *pdwCount,
LPWSTR **ppszSubConditionNames);
This function is called from CIOPCEventServer::QuerySubConditionNames(...)
The default implementation of this function returns four subCondition Names for the "Level Alarm" condition:
"Lo"
"Lo Lo"
"Hi"
"Hi Hi"
virtual HRESULT QuerySourceConditions ( LPWSTR szSource,
DWORD *pdwCount,
LPWSTR **ppszConditionNames);
This function is called from CIOPCEventServer::QuerySourceConditions(...)
The default implementation of this function returns E_NOTIMPL.
virtual HRESULT QueryEventAttributes ( DWORD dwEventCategory,
DWORD *pdwCount,
DWORD **ppdwAttrIDs,
LPWSTR **ppszAttrDescs,
VARTYPE **ppvtAttrTypes);
This function is called from CIOPCEventServer::QueryEventAttributes(...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT TranslateToItemIDs ( LPWSTR szSource,
DWORD dwEventCategory,
LPWSTR szConditionName,
LPWSTR szSubconditionName,
DWORD dwCount,
DWORD *pdwAssocAttrIDs,
LPWSTR **ppszAttrItemIDs,
LPWSTR **ppszNodeNames,
CLSID **ppCLSIDs);
This function is called from CIOPCEventServer::TranslateToItemIDs(...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT GetConditionState ( LPWSTR szSource,
LPWSTR szConditionName,
DWORD dwNumEventAttrs,
DWORD *pdwAttributeIDs,
OPCCONDITIONSTATE **ppConditionState);
This function is called from CIOPCEventServer::GetConditionState(...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT EnableConditionByArea ( DWORD dwNumAreas,
LPWSTR *pszAreas);
This function is called from CIOPCEventServer::EnableConditionByArea(...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT EnableConditionBySource ( DWORD dwNumSources,
LPWSTR *pszSources);
This function is called from CIOPCEventServer::EnableConditionBySource(...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT DisableConditionByArea ( DWORD dwNumAreas,
LPWSTR *pszAreas);
This function is called from CIOPCEventServer::DisableConditionByArea(...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT DisableConditionBySource ( DWORD dwNumSources,
LPWSTR *pszSources);
This function is called from CIOPCEventServer::DisableConditionBySource(...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT AckCondition ( DWORD dwCount,
LPWSTR szAcknowledgerID,
LPWSTR szComment,
LPWSTR *pszSource,
LPWSTR *pszConditionName,
FILETIME *pftActiveTime,
DWORD *pdwCookie,
HRESULT **ppErrors);
This function is called from CIOPCEventServer::AckCondition(...)
The default implementation of this function returns S_FALSE
virtual HRESULT CreateAreaBrowser ( REFIID riid,
LPUNKNOWN *ppUnk);
This function is called from CIOPCEventServer::CreateAreaBrowser(...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT CreateEventSubscription (DWORD hEventSubscription,
DWORD dwBufferTime,
DWORD dwMaxSize,
OPCHANDLE hClientSubscription);
virtual HRESULT RemoveEventSubscription (DWORD hEventSubscription);
WtOPCsvr.dll will execute these funtions in the application callback object whenevr a client subcribes and unsubscribes to the event server. This allows the application to implement filters on an individual subscription basis by calling UserAEMessageEx2.
virtual HRESULT SetEventSubscriptionFilter ( DWORD hEventSubscription,
DWORD dwEventType,
DWORD dwNumCategories,
DWORD *pdwEventCategories,
DWORD dwLowSeverity,
DWORD dwHighSeverity,
DWORD dwNumAreas,
LPWSTR *pszAreaList,
DWORD dwNumSources,
LPWSTR *pszSourceList);
This function is called from CIOPCEventSubscriptionMgt::SetFilter (...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT GetEventSubscriptionFilter ( DWORD hEventSubscription,
DWORD *pdwEventType,
DWORD *pdwNumCategories,
DWORD **ppdwEventCategories,
DWORD *pdwLowSeverity,
DWORD *pdwHighSeverity,
DWORD *pdwNumAreas,
LPWSTR **ppszAreaList,
DWORD *pdwNumSources,
LPWSTR **ppszSourceList);
This function is called from CIOPCEventSubscriptionMgt::GetFilter (...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT SelectEventSubscriptionReturnedAttributes ( DWORD hEventSubscription,
DWORD dwEventCategory,
DWORD dwCount,
DWORD *dwAttributeIDs);
This function is called from CIOPCEventSubscriptionMgt::SelectReturnedAttributes (...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT GetEventSubscriptionReturnedAttributes ( DWORD hEventSubscription,
DWORD dwEventCategory,
DWORD *pdwCount,
DWORD **ppdwAttributeIDs);
This function is called from CIOPCEventSubscriptionMgt::GetReturnedAttributes (...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT RefreshEventSubscription ( DWORD hEventSubscription,
DWORD dwConnection);
This function is called from CIOPCEventSubscriptionMgt::Refresh (...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT CancelEventSubscriptionRefresh ( DWORD hEventSubscription,
DWORD dwConnection);
This function is called from CIOPCEventSubscriptionMgt::CancelRefresh (...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT GetEventSubscriptionState ( DWORD hEventSubscription,
BOOL *pbActive,
DWORD *pdwBufferTime,
DWORD *pdwMaxSize,
OPCHANDLE *phClientSubscription);
This function is called from CIOPCEventSubscriptionMgt::GetState (...)
The default implementation of this function returns E_NOTIMPL
virtual HRESULT SetEventSubscriptionState ( DWORD hEventSubscription,
BOOL *pbActive,
DWORD *pdwBufferTime,
DWORD *pdwMaxSize,
OPCHANDLE hClientSubscription,
DWORD *pdwRevisedBufferTime,
DWORD *pdwRevisedMaxSize);
This function is called from CIOPCEventSubscriptionMgt::SetState (...)
The default implementation of this function returns E_NOTIMPL
Security Functions
BOOL EnableNTSecurity (BOOL EnableSecurity, DWORD MinImpersonationLevel);
Call this function to enable security checking for each tag. The MinImpersonationLevel is used to define the minimum requirements for a client connection.
HRESULT DefineNTUser (LPCSTR GroupName, LPCSTR UserName, DWORD AccessLevel);
This function defines the name of a particular user and the access rights to be assigned for access to server tags. Access rights may be any combination of the following:
ACCESSLEVELNONE 0x00000000
ACCESSLEVEL1 0x00010000
ACCESSLEVEL2 0x00020000
ACCESSLEVEL3 0x00040000
ACCESSLEVEL4 0x00080000
ACCESSLEVEL5 0x00100000
ACCESSLEVEL6 0x00200000
ACCESSLEVEL7 0x00400000
ACCESSLEVEL8 0x00800000
ACCESSLEVEL9 0x01000000
ACCESSLEVEL10 0x02000000
ACCESSLEVEL11 0x04000000
ACCESSLEVEL12 0x08000000
ACCESSLEVEL13 0x10000000
ACCESSLEVEL14 0x20000000
ACCESSLEVEL15 0x40000000
ACCESSLEVEL16 0x80000000
HANDLE CreateSecureTag (LPCSTR Name, VARIANT Value, WORD InitialQuality, DWORD ReadAccessLevel, DWORD WriteAccessLevel);
When a tag is created, the access level required for both read and write access must be specified.
If NT Security is enabled, the WtOPCsvr.dll will compare the access level required to read and/or write a tag with the access rights that have been assigned to the user definition. If the connected user does not have the proper access rights, the dll will deny access and return an error to the client.
BOOL EnableWriteNotification2 (WRITENOTIFYPROC2 lpCallback, BOOL ConvertToNativeType);
This function defines the callback routine that receives control from the WTOPCSvr.DLL whenever an OPC Client application writes to a defined process tag.
lpCallback points to a routine defined such as the following:
void CALLBACK EXPORT NotificationHandler (HANDLE handle,
VARIANT *pNewValue, DWORD *pDeviceError, char *pUser)
This callback is identical to the standard write notification callback with an extra parameter on the end that describes the name of the user requesting the write.
The WTSvrTest application was designed to demonstrate how an OPC Server may be assembled using the WTOPCSvr dll. WTSvrTest was built using MSDEV Version 6.0. All project and resource files are contained in the distribution file WtSvrTest.zip.
This simple application uses the standard MFC framework, (Application/Document/View), architecture generated by the Microsoft development platform for a single-document interface. All custom logic to interface with the WTOPCsvr dll has been added to WTSvrTestView.cpp. For demonstration purposes, menu options are included which Register and Unregister the server, instead of the preferred method of processing command line options during self-registration.
Menu options are available to add tags to the server and update their value. An option is also available to enable write notification back from the WTOPCsvr dll if an attached OPC Client writes a tag or requests an undefined tag. The menu options closely match the actual calls that would be made to the server dll for creating and updating tags for an actual OPC Server application.
The WTSvrTst2 application was designed to demonstrate different techniques for writing an OPC Server with large tag counts. It too was written using MSDEV 6.0 and is designed around the standard MFC framework. The WtSvrTst2 application uses a single form view that displays a tree control depicting the server tag list and an event window that displays DCOM Interface calls processed by the server. Menu commands allow you to Register and Unregister the server and to create a list of tags up to 20,000 in size. The tag list may be created using any combination of options for updating the values, (Hashing/No-Hashing, single Updates/UpdateByList). Text messages are displayed that show the times involved with creation of the tag list and the update times.