Appendix B - Data Access IDL Specification

The current files require MIDL compiler 3.00.15 or later and the WIN NT 4.0 release SDK.

Use the command line MIDL //Oicf opcda.idl.

The resulting OPCDA.H file should be included in all clients and servers.

The resulting OPCDA_I.C file defines the interface IDs and should be linked into all clients and servers.

NOTE: This IDL file and the Proxy/Stub generated from it should NEVER be modified in any way. If you add vendor specific interfaces to your server (which is allowed) you must generate a SEPARATE vendor specific IDL file to describe only those interfaces and a separate vendor specific ProxyStub DLL to marshall only those interfaces.

Note: See the OPC Overview document (OPCOVW.DOC) for a listing and disucssion of OPCCOMN.IDL.

// OPCDA.IDL

// REVISION: 6/17/98 04:00 PM (EST)

// VERSIONINFO 2.0.0.0

// 12/05/97 acc fixed UNCERTAIN bits, add AsyncIO2, OPCDataCallback,

// OPCItemProperties, BROWSE_TO

// 06/19/98 acc change V2 uuids prior to final release

// to avoid conflict with 'old' OPCDA Automation uuids

// Change name of 3 methods on AsyncIO2 to

// Cancel2,SetEnable,GetEnable to eliminate conflicts

//

import "oaidl.idl" ;

typedef enum tagOPCDATASOURCE {

OPC_DS_CACHE = 1,

OPC_DS_DEVICE } OPCDATASOURCE ;

typedef enum tagOPCBROWSETYPE {

OPC_BRANCH = 1,

OPC_LEAF,

OPC_FLAT} OPCBROWSETYPE;

typedef enum tagOPCNAMESPACETYPE {

OPC_NS_HIERARCHIAL = 1,

OPC_NS_FLAT} OPCNAMESPACETYPE;

typedef enum tagOPCBROWSEDIRECTION {

OPC_BROWSE_UP = 1,

OPC_BROWSE_DOWN, OPC_BROWSE_TO} OPCBROWSEDIRECTION;

// **NOTE** the 1.0 IDL contained an error for ACCESSRIGHTS.

// They should not have been an ENUM.

// They should have been two mask bits as noted here.

cpp_quote("#define OPC_READABLE 1")

cpp_quote("#define OPC_WRITEABLE 2")

typedef enum tagOPCEUTYPE {

OPC_NOENUM = 0,

OPC_ANALOG,

OPC_ENUMERATED } OPCEUTYPE;

typedef enum tagOPCSERVERSTATE {

OPC_STATUS_RUNNING = 1,

OPC_STATUS_FAILED,

OPC_STATUS_NOCONFIG,

OPC_STATUS_SUSPENDED,

OPC_STATUS_TEST } OPCSERVERSTATE;

typedef enum tagOPCENUMSCOPE { OPC_ENUM_PRIVATE_CONNECTIONS = 1,

OPC_ENUM_PUBLIC_CONNECTIONS,

OPC_ENUM_ALL_CONNECTIONS,

OPC_ENUM_PRIVATE,

OPC_ENUM_PUBLIC,

OPC_ENUM_ALL } OPCENUMSCOPE;

typedef DWORD OPCHANDLE;

typedef struct tagOPCGROUPHEADER {

DWORD dwSize;

DWORD dwItemCount;

OPCHANDLE hClientGroup;

DWORD dwTransactionID;

HRESULT hrStatus;

} OPCGROUPHEADER;

typedef struct tagOPCITEMHEADER1 {

OPCHANDLE hClient;

DWORD dwValueOffset;

WORD wQuality;

WORD wReserved;

FILETIME ftTimeStampItem;

} OPCITEMHEADER1;

typedef struct tagOPCITEMHEADER2 {

OPCHANDLE hClient;

DWORD dwValueOffset;

WORD wQuality;

WORD wReserved;

} OPCITEMHEADER2;

typedef struct tagOPCGROUPHEADERWRITE {

DWORD dwItemCount;

OPCHANDLE hClientGroup;

DWORD dwTransactionID;

HRESULT hrStatus;

} OPCGROUPHEADERWRITE;

typedef struct tagOPCITEMHEADERWRITE {

OPCHANDLE hClient;

HRESULT dwError;

} OPCITEMHEADERWRITE;

typedef struct tagOPCITEMSTATE{

OPCHANDLE hClient;

FILETIME ftTimeStamp;

WORD wQuality;

WORD wReserved;

VARIANT vDataValue;

} OPCITEMSTATE;

typedef struct tagOPCSERVERSTATUS {

FILETIME ftStartTime;

FILETIME ftCurrentTime;

FILETIME ftLastUpdateTime;

OPCSERVERSTATE dwServerState;

DWORD dwGroupCount;

DWORD dwBandWidth;

WORD wMajorVersion;

WORD wMinorVersion;

WORD wBuildNumber;

WORD wReserved;

[string] LPWSTR szVendorInfo;

} OPCSERVERSTATUS;

typedef struct tagOPCITEMDEF {

[string] LPWSTR szAccessPath;

[string] LPWSTR szItemID;

BOOL bActive ;

OPCHANDLE hClient;

DWORD dwBlobSize;

[size_is(dwBlobSize)] BYTE * pBlob;

VARTYPE vtRequestedDataType;

WORD wReserved;

} OPCITEMDEF;

typedef struct tagOPCITEMATTRIBUTES {

[string] LPWSTR szAccessPath;

[string] LPWSTR szItemID;

BOOL bActive;

OPCHANDLE hClient;

OPCHANDLE hServer;

DWORD dwAccessRights;

DWORD dwBlobSize;

[size_is(dwBlobSize)] BYTE * pBlob;

VARTYPE vtRequestedDataType;

VARTYPE vtCanonicalDataType;

OPCEUTYPE dwEUType;

VARIANT vEUInfo;

} OPCITEMATTRIBUTES;

typedef struct tagOPCITEMRESULT {

OPCHANDLE hServer;

VARTYPE vtCanonicalDataType;

WORD wReserved;

DWORD dwAccessRights;

DWORD dwBlobSize;

[size_is(dwBlobSize)] BYTE * pBlob;

} OPCITEMRESULT;
 
 

//****************************************************

// OPC Quality flags

//

// Masks for extracting quality subfields

// (note 'status' mask also includes 'Quality' bits)

//

cpp_quote("#define OPC_QUALITY_MASK 0xC0")

cpp_quote("#define OPC_STATUS_MASK 0xFC")

cpp_quote("#define OPC_LIMIT_MASK 0x03")

// Values for QUALITY_MASK bit field

//

cpp_quote("#define OPC_QUALITY_BAD 0x00")

cpp_quote("#define OPC_QUALITY_UNCERTAIN 0x40")

cpp_quote("#define OPC_QUALITY_GOOD 0xC0")

// STATUS_MASK Values for Quality = BAD

//

cpp_quote("#define OPC_QUALITY_CONFIG_ERROR 0x04")

cpp_quote("#define OPC_QUALITY_NOT_CONNECTED 0x08")

cpp_quote("#define OPC_QUALITY_DEVICE_FAILURE 0x0c")

cpp_quote("#define OPC_QUALITY_SENSOR_FAILURE 0x10")

cpp_quote("#define OPC_QUALITY_LAST_KNOWN 0x14")

cpp_quote("#define OPC_QUALITY_COMM_FAILURE 0x18")

cpp_quote("#define OPC_QUALITY_OUT_OF_SERVICE 0x1C")

// STATUS_MASK Values for Quality = UNCERTAIN

//

cpp_quote("#define OPC_QUALITY_LAST_USABLE 0x44")

cpp_quote("#define OPC_QUALITY_SENSOR_CAL 0x50")

cpp_quote("#define OPC_QUALITY_EGU_EXCEEDED 0x54")

cpp_quote("#define OPC_QUALITY_SUB_NORMAL 0x58")

// STATUS_MASK Values for Quality = GOOD

//

cpp_quote("#define OPC_QUALITY_LOCAL_OVERRIDE 0xD8")
 
 

// Values for Limit Bitfield

//

cpp_quote("#define OPC_LIMIT_OK 0x00")

cpp_quote("#define OPC_LIMIT_LOW 0x01")

cpp_quote("#define OPC_LIMIT_HIGH 0x02")

cpp_quote("#define OPC_LIMIT_CONST 0x03")

//****************************************************

//Interface Definitions

//

//****************************************************

[

object,

uuid(39c13a4d-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IOPCServer : IUnknown

{

HRESULT AddGroup(

[in, string] LPCWSTR szName,

[in] BOOL bActive,

[in] DWORD dwRequestedUpdateRate,

[in] OPCHANDLE hClientGroup,

[unique, in] LONG * pTimeBias,

[unique, in] FLOAT * pPercentDeadband,

[in] DWORD dwLCID,

[out] OPCHANDLE * phServerGroup,

[out] DWORD * pRevisedUpdateRate,

[in] REFIID riid,

[out, iid_is(riid)] LPUNKNOWN * ppUnk

);

HRESULT GetErrorString(

[in] HRESULT dwError,

[in] LCID dwLocale,

[out, string] LPWSTR * ppString

);

HRESULT GetGroupByName(

[in, string] LPCWSTR szName,

[in] REFIID riid,

[out, iid_is(riid)] LPUNKNOWN * ppUnk

);

HRESULT GetStatus(

[out] OPCSERVERSTATUS ** ppServerStatus

);

HRESULT RemoveGroup(

[in] OPCHANDLE hServerGroup,

[in] BOOL bForce

);

HRESULT CreateGroupEnumerator(

[in] OPCENUMSCOPE dwScope,

[in] REFIID riid,

[out, iid_is(riid)] LPUNKNOWN* ppUnk

);

}

//****************************************************

[

object,

uuid(39c13a4e-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IOPCServerPublicGroups : IUnknown

{

HRESULT GetPublicGroupByName(

[in, string] LPCWSTR szName,

[in] REFIID riid,

[out, iid_is(riid)] LPUNKNOWN * ppUnk

);

HRESULT RemovePublicGroup(

[in] OPCHANDLE hServerGroup,

[in] BOOL bForce

);

}
 
 

//****************************************************

[

object,

uuid(39c13a4f-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IOPCBrowseServerAddressSpace: IUnknown

{

HRESULT QueryOrganization(

[out] OPCNAMESPACETYPE * pNameSpaceType

);

HRESULT ChangeBrowsePosition(

[in] OPCBROWSEDIRECTION dwBrowseDirection,

[in, string] LPCWSTR szString

);

HRESULT BrowseOPCItemIDs(

[in] OPCBROWSETYPE dwBrowseFilterType,

[in, string] LPCWSTR szFilterCriteria,

[in] VARTYPE vtDataTypeFilter,

[in] DWORD dwAccessRightsFilter,

[out] LPENUMSTRING * ppIEnumString

);

HRESULT GetItemID(

[in] LPWSTR szItemDataID,

[out, string] LPWSTR * szItemID

);

HRESULT BrowseAccessPaths(

[in, string] LPCWSTR szItemID,

[out] LPENUMSTRING * ppIEnumString

);

}
 
 
 
 

//****************************************************

[

object,

uuid(39c13a50-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IOPCGroupStateMgt : IUnknown

{

HRESULT GetState(

[out] DWORD * pUpdateRate,

[out] BOOL * pActive,

[out, string] LPWSTR * ppName,

[out] LONG * pTimeBias,

[out] FLOAT * pPercentDeadband,

[out] DWORD * pLCID,

[out] OPCHANDLE * phClientGroup,

[out] OPCHANDLE * phServerGroup

);

HRESULT SetState(

[unique, in] DWORD * pRequestedUpdateRate,

[out] DWORD * pRevisedUpdateRate,

[unique, in] BOOL * pActive,

[unique, in] LONG * pTimeBias,

[unique, in] FLOAT * pPercentDeadband,

[unique, in] DWORD * pLCID,

[unique, in] OPCHANDLE * phClientGroup

);

HRESULT SetName(

[in, string] LPCWSTR szName

);

HRESULT CloneGroup(

[in, string] LPCWSTR szName,

[in] REFIID riid,

[out, iid_is(riid)] LPUNKNOWN * ppUnk

);

}
 
 
 
 

//****************************************************

[

object,

uuid(39c13a51-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IOPCPublicGroupStateMgt : IUnknown

{

HRESULT GetState(

[out] BOOL * pPublic

);

HRESULT MoveToPublic(

void

);

}
 
 
 
 

//****************************************************

[

object,

uuid(39c13a52-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IOPCSyncIO : IUnknown

{

HRESULT Read(

[in] OPCDATASOURCE dwSource,

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phServer,

[out, size_is(,dwCount)] OPCITEMSTATE ** ppItemValues,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

HRESULT Write(

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phServer,

[in, size_is(dwCount)] VARIANT * pItemValues,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

}

//****************************************************

[

object,

uuid(39c13a53-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IOPCAsyncIO : IUnknown

{

HRESULT Read(

[in] DWORD dwConnection,

[in] OPCDATASOURCE dwSource,

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phServer,

[out] DWORD * pTransactionID,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

HRESULT Write(

[in] DWORD dwConnection,

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phServer,

[in, size_is(dwCount)] VARIANT * pItemValues,

[out] DWORD * pTransactionID,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);
 
 

HRESULT Refresh(

[in] DWORD dwConnection,

[in] OPCDATASOURCE dwSource,

[out] DWORD * pTransactionID

);

HRESULT Cancel(

[in] DWORD dwTransactionID

);

}
 
 

//****************************************************

[

object,

uuid(39c13a54-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IOPCItemMgt: IUnknown

{

HRESULT AddItems(

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCITEMDEF * pItemArray,

[out, size_is(,dwCount)] OPCITEMRESULT ** ppAddResults,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

HRESULT ValidateItems(

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCITEMDEF * pItemArray,

[in] BOOL bBlobUpdate,

[out, size_is(,dwCount)] OPCITEMRESULT ** ppValidationResults,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

HRESULT RemoveItems(

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phServer,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

HRESULT SetActiveState(

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phServer,

[in] BOOL bActive,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

HRESULT SetClientHandles(

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phServer,

[in, size_is(dwCount)] OPCHANDLE * phClient,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

HRESULT SetDatatypes(

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phServer,

[in, size_is(dwCount)] VARTYPE * pRequestedDatatypes,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

HRESULT CreateEnumerator(

[in] REFIID riid,

[out, iid_is(riid)] LPUNKNOWN * ppUnk

);

}
 
 

//****************************************************

[

object,

uuid(39c13a55-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IEnumOPCItemAttributes : IUnknown

{

HRESULT Next(

[in] ULONG celt,

[out, size_is(,*pceltFetched)] OPCITEMATTRIBUTES ** ppItemArray,

[out] ULONG * pceltFetched

);

HRESULT Skip(

[in] ULONG celt

);

HRESULT Reset(

void

);

HRESULT Clone(

[out] IEnumOPCItemAttributes ** ppEnumItemAttributes

);

}
 
 

// Data Access V2.0 additions

[

object,

uuid(39c13a70-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IOPCDataCallback : IUnknown

{

HRESULT OnDataChange(

[in] DWORD dwTransid,

[in] OPCHANDLE hGroup,

[in] HRESULT hrMasterquality,

[in] HRESULT hrMastererror,

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phClientItems,

[in, size_is(dwCount)] VARIANT * pvValues,

[in, size_is(dwCount)] WORD * pwQualities,

[in, size_is(dwCount)] FILETIME * pftTimeStamps,

[in, size_is(dwCount)] HRESULT * pErrors

);

HRESULT OnReadComplete(

[in] DWORD dwTransid,

[in] OPCHANDLE hGroup,

[in] HRESULT hrMasterquality,

[in] HRESULT hrMastererror,

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phClientItems,

[in, size_is(dwCount)] VARIANT * pvValues,

[in, size_is(dwCount)] WORD * pwQualities,

[in, size_is(dwCount)] FILETIME * pftTimeStamps,

[in, size_is(dwCount)] HRESULT * pErrors

);

HRESULT OnWriteComplete(

[in] DWORD dwTransid,

[in] OPCHANDLE hGroup,

[in] HRESULT hrMastererr,

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * pClienthandles,

[in, size_is(dwCount)] HRESULT * pErrors

);

HRESULT OnCancelComplete(

[in] DWORD dwTransid,

[in] OPCHANDLE hGroup

);

}

//****************************************************

[

object,

uuid(39c13a71-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IOPCAsyncIO2 : IUnknown

{

HRESULT Read(

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phServer,

[in] DWORD dwTransactionID,

[out] DWORD * pdwCancelID,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

HRESULT Write(

[in] DWORD dwCount,

[in, size_is(dwCount)] OPCHANDLE * phServer,

[in, size_is(dwCount)] VARIANT * pItemValues,

[in] DWORD dwTransactionID,

[out] DWORD * pdwCancelID,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);
 
 

HRESULT Refresh2(

[in] OPCDATASOURCE dwSource,

[in] DWORD dwTransactionID,

[out] DWORD * pdwCancelID

);

HRESULT Cancel2(

[in] DWORD dwCancelID

);

HRESULT SetEnable(

[in] BOOL bEnable

);

HRESULT GetEnable(

[out] BOOL *pbEnable

);

}
 
 

//****************************************************

[

object,

uuid(39c13a72-011e-11d0-9675-0020afd8adb3),

pointer_default(unique)

]

interface IOPCItemProperties : IUnknown

{

HRESULT QueryAvailableProperties (

[in] LPWSTR szItemID,

[out] DWORD * pdwCount,

[out, size_is(,*pdwCount)] DWORD ** ppPropertyIDs,

[out, size_is(,*pdwCount)] LPWSTR ** ppDescriptions,

[out, size_is(,*pdwCount)] VARTYPE ** ppvtDataTypes

);

HRESULT GetItemProperties (

[in] LPWSTR szItemID,

[in] DWORD dwCount,

[in, size_is(dwCount)] DWORD * pdwPropertyIDs,

[out, size_is(,dwCount)] VARIANT ** ppvData,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

HRESULT LookupItemIDs(

[in] LPWSTR szItemID,

[in] DWORD dwCount,

[in, size_is(dwCount)] DWORD * pdwPropertyIDs,

[out, string, size_is(,dwCount)] LPWSTR ** ppszNewItemIDs,

[out, size_is(,dwCount)] HRESULT ** ppErrors

);

}
 
 

// This TYPELIB is generated as a convenience to users of high level tools

// which are capable of using or browsing TYPELIBs.

// 'Smart Pointers' in VC5 is one example.

[

uuid(B28EEDB2-AC6F-11d1-84D5-00608CB8A7E9),

version(1.0),

helpstring("OPCDA 2.0 Type Library")

]

library OPCDA

{

importlib("stdole32.tlb");

importlib("stdole2.tlb");

interface IOPCServer ;

interface IOPCServerPublicGroups ;

interface IOPCBrowseServerAddressSpace;

interface IOPCGroupStateMgt ;

interface IOPCPublicGroupStateMgt ;

interface IOPCSyncIO ;

interface IOPCAsyncIO ;

interface IOPCItemMgt;

interface IEnumOPCItemAttributes ;

interface IOPCDataCallback ;

interface IOPCAsyncIO2 ;

interface IOPCItemProperties ;

};