This commit is contained in:
luosheng
2023-07-12 06:42:28 +08:00
parent 25555cad18
commit db591e0367
188 changed files with 56088 additions and 9 deletions

View File

@@ -0,0 +1,441 @@
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
//-----------------------------------------------------------------------------
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
// Web: https://www.technosoftware.com
//
// The source code in this file is covered under a dual-license scenario:
// - Owner of a purchased license: SCLA 1.0
// - GPL V3: everybody else
//
// SCLA license terms accompanied with this source code.
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
//
// GNU General Public License as published by the Free Software Foundation;
// version 3 of the License are accompanied with this source code.
// See https://technosoftware.com/license/GPLv3License.txt
//
// This source code is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
//-----------------------------------------------------------------------------
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
#region Using Directives
using System;
using System.Collections;
using Technosoftware.DaAeHdaClient.Hda;
using Technosoftware.OpcRcw.Hda;
using Technosoftware.OpcRcw.Comn;
#endregion
namespace Technosoftware.DaAeHdaClient.Com.Hda
{
/// <summary>
/// An in-process wrapper an OPC HDA browser object.
/// </summary>
internal class Browser : ITsCHdaBrowser
{
//======================================================================
// Construction
/// <summary>
/// Initializes the object with the specifed COM server.
/// </summary>
internal Browser(Server server, IOPCHDA_Browser browser, TsCHdaBrowseFilter[] filters, OpcResult[] results)
{
if (browser == null) throw new ArgumentNullException(nameof(browser));
// save the server object that created the browser.
m_server = server;
// save the COM server (released in Dispose()).
m_browser = browser;
// save only the filters that were accepted.
if (filters != null)
{
var validFilters = new ArrayList();
for (var ii = 0; ii < filters.Length; ii++)
{
if (results[ii].Succeeded())
{
validFilters.Add(filters[ii]);
}
}
m_filters = new TsCHdaBrowseFilterCollection(validFilters);
}
}
#region IDisposable Members
/// <summary>
/// This must be called explicitly by clients to ensure the COM server is released.
/// </summary>
public virtual void Dispose()
{
lock (this)
{
m_server = null;
Utilities.Interop.ReleaseServer(m_browser);
m_browser = null;
}
}
#endregion
//======================================================================
// Filters
/// <summary>
/// Returns the set of attribute filters used by the browser.
/// </summary>
public TsCHdaBrowseFilterCollection Filters
{
get
{
lock (this)
{
return (TsCHdaBrowseFilterCollection)m_filters.Clone();
}
}
}
//======================================================================
// Browse
/// <summary>
/// Browses the server's address space at the specified branch.
/// </summary>
/// <param name="itemID">The item id of the branch to search.</param>
/// <returns>The set of elements that meet the filter criteria.</returns>
public TsCHdaBrowseElement[] Browse(OpcItem itemID)
{
IOpcBrowsePosition position;
var elements = Browse(itemID, 0, out position);
if (position != null)
{
position.Dispose();
}
return elements;
}
/// <summary>
/// Begins a browsing the server's address space at the specified branch.
/// </summary>
/// <param name="itemID">The item id of the branch to search.</param>
/// <param name="maxElements">The maximum number of elements to return.</param>
/// <param name="position">The position object used to continue a browse operation.</param>
/// <returns>The set of elements that meet the filter criteria.</returns>
public TsCHdaBrowseElement[] Browse(OpcItem itemID, int maxElements, out IOpcBrowsePosition position)
{
position = null;
// interpret invalid values as 'no limit'.
if (maxElements <= 0)
{
maxElements = int.MaxValue;
}
lock (this)
{
var branchPath = (itemID != null && itemID.ItemName != null)?itemID.ItemName:"";
// move to the correct position in the server's address space.
try
{
m_browser.ChangeBrowsePosition(OPCHDA_BROWSEDIRECTION.OPCHDA_BROWSE_DIRECT, branchPath);
}
catch (Exception e)
{
throw Utilities.Interop.CreateException("IOPCHDA_Browser.ChangeBrowsePosition", e);
}
// browse for branches
var enumerator = GetEnumerator(true);
var elements = FetchElements(enumerator, maxElements, true);
// check if max element count reached.
if (elements.Count >= maxElements)
{
position = new BrowsePosition(branchPath, enumerator, false);
return (TsCHdaBrowseElement[])elements.ToArray(typeof(TsCHdaBrowseElement));
}
// release enumerator.
enumerator.Dispose();
// browse for items
enumerator = GetEnumerator(false);
var items = FetchElements(enumerator, maxElements-elements.Count, false);
if (items != null)
{
elements.AddRange(items);
}
// check if max element count reached.
if (elements.Count >= maxElements)
{
position = new BrowsePosition(branchPath, enumerator, true);
return (TsCHdaBrowseElement[])elements.ToArray(typeof(TsCHdaBrowseElement));
}
// release enumerator.
enumerator.Dispose();
return (TsCHdaBrowseElement[])elements.ToArray(typeof(TsCHdaBrowseElement));
}
}
//======================================================================
// BrowseNext
/// <summary>
/// Continues browsing the server's address space at the specified position.
/// </summary>
/// <param name="maxElements">The maximum number of elements to return.</param>
/// <param name="position">The position object used to continue a browse operation.</param>
/// <returns>The set of elements that meet the filter criteria.</returns>
public TsCHdaBrowseElement[] BrowseNext(int maxElements, ref IOpcBrowsePosition position)
{
// check arguments.
if (position == null || position.GetType() != typeof(BrowsePosition))
{
throw new ArgumentException("Not a valid browse position object.", nameof(position));
}
// interpret invalid values as 'no limit'.
if (maxElements <= 0)
{
maxElements = int.MaxValue;
}
lock (this)
{
var pos = (BrowsePosition)position;
var elements = new ArrayList();
if (!pos.FetchingItems)
{
elements = FetchElements(pos.Enumerator, maxElements, true);
// check if max element count reached.
if (elements.Count >= maxElements)
{
return (TsCHdaBrowseElement[])elements.ToArray(typeof(TsCHdaBrowseElement));
}
// release enumerator.
pos.Enumerator.Dispose();
pos.Enumerator = null;
pos.FetchingItems = true;
// move to the correct position in the server's address space.
try
{
m_browser.ChangeBrowsePosition(OPCHDA_BROWSEDIRECTION.OPCHDA_BROWSE_DIRECT, pos.BranchPath);
}
catch (Exception e)
{
throw Utilities.Interop.CreateException("IOPCHDA_Browser.ChangeBrowsePosition", e);
}
// create enumerator for items.
pos.Enumerator = GetEnumerator(false);
}
// fetch next set of items.
var items = FetchElements(pos.Enumerator, maxElements-elements.Count, false);
if (items != null)
{
elements.AddRange(items);
}
// check if max element count reached.
if (elements.Count >= maxElements)
{
return (TsCHdaBrowseElement[])elements.ToArray(typeof(TsCHdaBrowseElement));
}
// release position object.
position.Dispose();
position = null;
// return elements.
return (TsCHdaBrowseElement[])elements.ToArray(typeof(TsCHdaBrowseElement));
}
}
#region Private Methods
/// <summary>
/// Creates an enumerator for the elements contained with the current branch.
/// </summary>
private EnumString GetEnumerator(bool isBranch)
{
try
{
var browseType = (isBranch)?OPCHDA_BROWSETYPE.OPCHDA_BRANCH:OPCHDA_BROWSETYPE.OPCHDA_LEAF;
IEnumString pEnumerator = null;
m_browser.GetEnum(browseType, out pEnumerator);
return new EnumString(pEnumerator);
}
catch (Exception e)
{
throw Utilities.Interop.CreateException("IOPCHDA_Browser.GetEnum", e);
}
}
/// <summary>
/// Fetches the element names and item ids for each element.
/// </summary>
private ArrayList FetchElements(EnumString enumerator, int maxElements, bool isBranch)
{
var elements = new ArrayList();
while (elements.Count < maxElements)
{
// fetch next batch of element names.
var count = BLOCK_SIZE;
if (elements.Count + count > maxElements)
{
count = maxElements - elements.Count;
}
var names = enumerator.Next(count);
// check if no more elements found.
if (names == null || names.Length == 0)
{
break;
}
// create new element objects.
foreach (var name in names)
{
var element = new TsCHdaBrowseElement();
element.Name = name;
// lookup item id for element.
try
{
string itemID = null;
m_browser.GetItemID(name, out itemID);
element.ItemName = itemID;
element.ItemPath = null;
element.HasChildren = isBranch;
}
catch
{
// ignore errors.
}
elements.Add(element);
}
}
// validate items - this is necessary to set the IsItem flag correctly.
var results = m_server.ValidateItems((OpcItem[])elements.ToArray(typeof(OpcItem)));
if (results != null)
{
for (var ii = 0; ii < results.Length; ii++)
{
if (results[ii].Result.Succeeded())
{
((TsCHdaBrowseElement)elements[ii]).IsItem = true;
}
}
}
// return results.
return elements;
}
#endregion
#region Private Members
private Server m_server = null;
private IOPCHDA_Browser m_browser = null;
private TsCHdaBrowseFilterCollection m_filters = new TsCHdaBrowseFilterCollection();
private const int BLOCK_SIZE = 10;
#endregion
}
/// <summary>
/// Stores the state of a browse operation that was halted.
/// </summary>
internal class BrowsePosition : TsCHdaBrowsePosition
{
/// <summary>
/// Initializes a the object with the browse operation state information.
/// </summary>
/// <param name="branchPath">The item id of branch used in the browse operation.</param>
/// <param name="enumerator">The enumerator used for the browse operation.</param>
/// <param name="fetchingItems">Whether the enumerator is return branches or items.</param>
internal BrowsePosition(string branchPath, EnumString enumerator, bool fetchingItems)
{
m_branchPath = branchPath;
m_enumerator = enumerator;
m_fetchingItems = fetchingItems;
}
/// <summary>
/// The item id of the branch being browsed.
/// </summary>
internal string BranchPath
{
get => m_branchPath;
set => m_branchPath = value;
}
/// <summary>
/// The enumerator that was in use when the browse halted.
/// </summary>
internal EnumString Enumerator
{
get => m_enumerator;
set => m_enumerator = value;
}
/// <summary>
/// Whether the browse halted while fetching items.
/// </summary>
internal bool FetchingItems
{
get => m_fetchingItems;
set => m_fetchingItems = value;
}
#region IDisposable Members
/// <summary>
/// Releases any unmanaged resources held by the object.
/// </summary>
public override void Dispose()
{
if (m_enumerator != null)
{
m_enumerator.Dispose();
m_enumerator = null;
}
base.Dispose();
}
#endregion
#region Private Members
private string m_branchPath = null;
private EnumString m_enumerator = null;
private bool m_fetchingItems = false;
#endregion
}
}

View File

@@ -0,0 +1,591 @@
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
//-----------------------------------------------------------------------------
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
// Web: https://www.technosoftware.com
//
// The source code in this file is covered under a dual-license scenario:
// - Owner of a purchased license: SCLA 1.0
// - GPL V3: everybody else
//
// SCLA license terms accompanied with this source code.
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
//
// GNU General Public License as published by the Free Software Foundation;
// version 3 of the License are accompanied with this source code.
// See https://technosoftware.com/license/GPLv3License.txt
//
// This source code is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
//-----------------------------------------------------------------------------
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
#region Using Directives
using System;
using System.Collections;
using Technosoftware.DaAeHdaClient.Hda;
using Technosoftware.OpcRcw.Hda;
#endregion
namespace Technosoftware.DaAeHdaClient.Com.Hda
{
/// <summary>
/// A class that implements the HDA data callback interface.
/// </summary>
internal class DataCallback : IOPCHDA_DataCallback
{
/// <summary>
/// Initializes the object with the containing subscription object.
/// </summary>
public DataCallback() {}
/// <summary>
/// Fired when an exception occurs during callback processing.
/// </summary>
public event TsCHdaCallbackExceptionEventHandler CallbackExceptionEvent
{
add {lock (this) { _callbackExceptionEvent += value; }}
remove {lock (this) { _callbackExceptionEvent -= value; }}
}
/// <summary>
/// Creates a new request object.
/// </summary>
public Request CreateRequest(object requestHandle, Delegate callback)
{
lock (this)
{
// create a new request.
var request = new Request(requestHandle, callback, ++m_nextID);
// no items yet - callback may return before async call returns.
m_requests[request.RequestID] = request;
// return requests.
return request;
}
}
/// <summary>
/// Cancels an existing request.
/// </summary>
public bool CancelRequest(Request request, TsCHdaCancelCompleteEventHandler callback)
{
lock (this)
{
// check if it is a valid request.
if (!m_requests.Contains(request.RequestID))
{
return false;
}
// request will be removed when the cancel complete callback arrives.
if (callback != null)
{
request.CancelCompleteEvent += callback;
}
// no confirmation required - remove request immediately.
else
{
m_requests.Remove(request.RequestID);
}
// request will be cancelled.
return true;
}
}
#region IOPCHDA_DataCallback Members
/// <summary>
/// Called when new data arrives for a subscription.
/// </summary>
public void OnDataChange(
int dwTransactionID,
int hrStatus,
int dwNumItems,
OPCHDA_ITEM[] pItemValues,
int[] phrErrors)
{
try
{
lock (this)
{
// lookup request transaction.
var request = (Request)m_requests[dwTransactionID];
if (request == null)
{
return;
}
// unmarshal results.
var results = new TsCHdaItemValueCollection[pItemValues.Length];
for (var ii = 0; ii < pItemValues.Length; ii++)
{
results[ii] = Interop.GetItemValueCollection(pItemValues[ii], false);
results[ii].ServerHandle = results[ii].ClientHandle;
results[ii].ClientHandle = null;
results[ii].Result = Utilities.Interop.GetResultId(phrErrors[ii]);
}
// invoke callback - remove request if unexpected error occured.
if (request.InvokeCallback(results))
{
m_requests.Remove(request.RequestID);
}
}
}
catch (Exception exception)
{
HandleException(dwTransactionID, exception);
}
}
/// <summary>
/// Called when an asynchronous read request completes.
/// </summary>
public void OnReadComplete(
int dwTransactionID,
int hrStatus,
int dwNumItems,
OPCHDA_ITEM[] pItemValues,
int[] phrErrors)
{
try
{
lock (this)
{
// lookup request transaction.
var request = (Request)m_requests[dwTransactionID];
if (request == null)
{
return;
}
// unmarshal results.
var results = new TsCHdaItemValueCollection[pItemValues.Length];
for (var ii = 0; ii < pItemValues.Length; ii++)
{
results[ii] = Interop.GetItemValueCollection(pItemValues[ii], false);
results[ii].ServerHandle = pItemValues[ii].hClient;
results[ii].Result = Utilities.Interop.GetResultId(phrErrors[ii]);
}
// invoke callback - remove request if all results arrived.
if (request.InvokeCallback(results))
{
m_requests.Remove(request.RequestID);
}
}
}
catch (Exception exception)
{
HandleException(dwTransactionID, exception);
}
}
/// <summary>
/// Called when an asynchronous read modified request completes.
/// </summary>
public void OnReadModifiedComplete(
int dwTransactionID,
int hrStatus,
int dwNumItems,
OPCHDA_MODIFIEDITEM[] pItemValues,
int[] phrErrors)
{
try
{
lock (this)
{
// lookup request transaction.
var request = (Request)m_requests[dwTransactionID];
if (request == null)
{
return;
}
// unmarshal results.
var results = new TsCHdaModifiedValueCollection[pItemValues.Length];
for (var ii = 0; ii < pItemValues.Length; ii++)
{
results[ii] = Interop.GetModifiedValueCollection(pItemValues[ii], false);
results[ii].ServerHandle = pItemValues[ii].hClient;
results[ii].Result = Utilities.Interop.GetResultId(phrErrors[ii]);
}
// invoke callback - remove request if all results arrived.
if (request.InvokeCallback(results))
{
m_requests.Remove(request.RequestID);
}
}
}
catch (Exception exception)
{
HandleException(dwTransactionID, exception);
}
}
/// <summary>
/// Called when an asynchronous read attributes request completes.
/// </summary>
public void OnReadAttributeComplete(
int dwTransactionID,
int hrStatus,
int hClient,
int dwNumItems,
OPCHDA_ATTRIBUTE[] pAttributeValues,
int[] phrErrors)
{
try
{
lock (this)
{
// lookup request transaction.
var request = (Request)m_requests[dwTransactionID];
if (request == null)
{
return;
}
// create item object to collect results.
var item = new TsCHdaItemAttributeCollection();
item.ServerHandle = hClient;
// unmarshal results.
var results = new TsCHdaAttributeValueCollection[pAttributeValues.Length];
for (var ii = 0; ii < pAttributeValues.Length; ii++)
{
results[ii] = Interop.GetAttributeValueCollection(pAttributeValues[ii], false);
results[ii].Result = Utilities.Interop.GetResultId(phrErrors[ii]);
item.Add(results[ii]);
}
// invoke callback - remove request if all results arrived.
if (request.InvokeCallback(item))
{
m_requests.Remove(request.RequestID);
}
}
}
catch (Exception exception)
{
HandleException(dwTransactionID, exception);
}
}
/// <summary>
/// Called when an asynchronous read annotations request completes.
/// </summary>
public void OnReadAnnotations(
int dwTransactionID,
int hrStatus,
int dwNumItems,
OPCHDA_ANNOTATION[] pAnnotationValues,
int[] phrErrors)
{
try
{
lock (this)
{
// lookup request transaction.
var request = (Request)m_requests[dwTransactionID];
if (request == null)
{
return;
}
// unmarshal results.
var results = new TsCHdaAnnotationValueCollection[pAnnotationValues.Length];
for (var ii = 0; ii < pAnnotationValues.Length; ii++)
{
results[ii] = Interop.GetAnnotationValueCollection(pAnnotationValues[ii], false);
results[ii].ServerHandle = pAnnotationValues[ii].hClient;
results[ii].Result = Utilities.Interop.GetResultId(phrErrors[ii]);
}
// invoke callback - remove request if all results arrived.
if (request.InvokeCallback(results))
{
m_requests.Remove(request.RequestID);
}
}
}
catch (Exception exception)
{
HandleException(dwTransactionID, exception);
}
}
/// <summary>
/// Called when an asynchronous insert annotations request completes.
/// </summary>
public void OnInsertAnnotations(
int dwTransactionID,
int hrStatus,
int dwCount,
int[] phClients,
int[] phrErrors)
{
try
{
lock (this)
{
// lookup request transaction.
var request = (Request)m_requests[dwTransactionID];
if (request == null)
{
return;
}
// unmarshal results.
var results = new ArrayList();
if (dwCount > 0)
{
// subscription results in collections for the same item id.
var currentHandle = phClients[0];
var itemResults = new TsCHdaResultCollection();
for (var ii = 0; ii < dwCount; ii++)
{
// create a new collection for the next item's results.
if (phClients[ii] != currentHandle)
{
itemResults.ServerHandle = currentHandle;
results.Add(itemResults);
currentHandle = phClients[ii];
itemResults = new TsCHdaResultCollection();
}
var result = new TsCHdaResult(Utilities.Interop.GetResultId(phrErrors[ii]));
itemResults.Add(result);
}
// add the last set of item results.
itemResults.ServerHandle = currentHandle;
results.Add(itemResults);
}
// invoke callback - remove request if all results arrived.
if (request.InvokeCallback((TsCHdaResultCollection[])results.ToArray(typeof(TsCHdaResultCollection))))
{
m_requests.Remove(request.RequestID);
}
}
}
catch (Exception exception)
{
HandleException(dwTransactionID, exception);
}
}
/// <summary>
/// Called when a batch of data from playback request arrives.
/// </summary>
public void OnPlayback(
int dwTransactionID,
int hrStatus,
int dwNumItems,
IntPtr ppItemValues,
int[] phrErrors)
{
try
{
lock (this)
{
// lookup request transaction.
var request = (Request)m_requests[dwTransactionID];
if (request == null)
{
return;
}
// unmarshal results.
var results = new TsCHdaItemValueCollection[dwNumItems];
// the data is transfered as a array of pointers to items instead of simply
// as an array of items. This is due to a mistake in the HDA IDL.
var pItems = Utilities.Interop.GetInt32s(ref ppItemValues, dwNumItems, false);
for (var ii = 0; ii < dwNumItems; ii++)
{
// get pointer to item.
var pItem = (IntPtr)pItems[ii];
// unmarshal item as an array of length 1.
var item = Interop.GetItemValueCollections(ref pItem, 1, false);
if (item != null && item.Length == 1)
{
results[ii] = item[0];
results[ii].ServerHandle = results[ii].ClientHandle;
results[ii].ClientHandle = null;
results[ii].Result = Utilities.Interop.GetResultId(phrErrors[ii]);
}
}
// invoke callback - remove request if unexpected error occured.
if (request.InvokeCallback(results))
{
m_requests.Remove(request.RequestID);
}
}
}
catch (Exception exception)
{
HandleException(dwTransactionID, exception);
}
}
/// <summary>
/// Called when an asynchronous update request completes.
/// </summary>
public void OnUpdateComplete(
int dwTransactionID,
int hrStatus,
int dwCount,
int[] phClients,
int[] phrErrors)
{
try
{
lock (this)
{
// lookup request transaction.
var request = (Request)m_requests[dwTransactionID];
if (request == null)
{
return;
}
// unmarshal results.
var results = new ArrayList();
if (dwCount > 0)
{
// subscription results in collections for the same item id.
var currentHandle = phClients[0];
var itemResults = new TsCHdaResultCollection();
for (var ii = 0; ii < dwCount; ii++)
{
// create a new collection for the next item's results.
if (phClients[ii] != currentHandle)
{
itemResults.ServerHandle = currentHandle;
results.Add(itemResults);
currentHandle = phClients[ii];
itemResults = new TsCHdaResultCollection();
}
var result = new TsCHdaResult(Utilities.Interop.GetResultId(phrErrors[ii]));
itemResults.Add(result);
}
// add the last set of item results.
itemResults.ServerHandle = currentHandle;
results.Add(itemResults);
}
// invoke callback - remove request if all results arrived.
if (request.InvokeCallback((TsCHdaResultCollection[])results.ToArray(typeof(TsCHdaResultCollection))))
{
m_requests.Remove(request.RequestID);
}
}
}
catch (Exception exception)
{
HandleException(dwTransactionID, exception);
}
}
/// <summary>
/// Called when an asynchronous request was cancelled successfully.
/// </summary>
public void OnCancelComplete(int dwCancelID)
{
try
{
lock (this)
{
// lookup request.
var request = (Request)m_requests[dwCancelID];
if (request == null)
{
return;
}
// send the cancel complete notification.
request.OnCancelComplete();
// remove the request.
m_requests.Remove(request.RequestID);
}
}
catch (Exception exception)
{
HandleException(dwCancelID, exception);
}
}
#endregion
#region Private Methods
/// <summary>
/// Fires an event indicating an exception occurred during callback processing.
/// </summary>
void HandleException(int requestID, Exception exception)
{
lock (this)
{
// lookup request.
var request = (Request)m_requests[requestID];
if (request != null)
{
// send notification.
if (_callbackExceptionEvent != null)
{
_callbackExceptionEvent(request, exception);
}
}
}
}
#endregion
#region Private Members
private int m_nextID;
private Hashtable m_requests = new Hashtable();
private TsCHdaCallbackExceptionEventHandler _callbackExceptionEvent;
#endregion
}
}

View File

@@ -0,0 +1,441 @@
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
//-----------------------------------------------------------------------------
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
// Web: https://www.technosoftware.com
//
// The source code in this file is covered under a dual-license scenario:
// - Owner of a purchased license: SCLA 1.0
// - GPL V3: everybody else
//
// SCLA license terms accompanied with this source code.
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
//
// GNU General Public License as published by the Free Software Foundation;
// version 3 of the License are accompanied with this source code.
// See https://technosoftware.com/license/GPLv3License.txt
//
// This source code is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
//-----------------------------------------------------------------------------
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
#region Using Directives
using System;
using System.Runtime.InteropServices;
using Technosoftware.DaAeHdaClient.Da;
using Technosoftware.DaAeHdaClient.Hda;
#endregion
#pragma warning disable 0618
namespace Technosoftware.DaAeHdaClient.Com.Hda
{
/// <summary>
/// Contains state information for a single asynchronous Technosoftware.DaAeHdaClient.Com.Hda.Interop.
/// </summary>
internal class Interop
{
/// <summary>
/// Converts a standard FILETIME to an OpcRcw.Da.FILETIME structure.
/// </summary>
internal static OpcRcw.Hda.OPCHDA_FILETIME Convert(FILETIME input)
{
var output = new OpcRcw.Hda.OPCHDA_FILETIME();
output.dwLowDateTime = input.dwLowDateTime;
output.dwHighDateTime = input.dwHighDateTime;
return output;
}
/// <summary>
/// Converts an OpcRcw.Da.FILETIME to a standard FILETIME structure.
/// </summary>
internal static FILETIME Convert(OpcRcw.Hda.OPCHDA_FILETIME input)
{
var output = new FILETIME();
output.dwLowDateTime = input.dwLowDateTime;
output.dwHighDateTime = input.dwHighDateTime;
return output;
}
/// <summary>
/// Converts a decimal value to a OpcRcw.Hda.OPCHDA_TIME structure.
/// </summary>
internal static OpcRcw.Hda.OPCHDA_FILETIME GetFILETIME(decimal input)
{
var output = new OpcRcw.Hda.OPCHDA_FILETIME();
output.dwHighDateTime = (int)((((ulong)(input*10000000)) & 0xFFFFFFFF00000000)>>32);
output.dwLowDateTime = (int)((((ulong)(input*10000000)) & 0x00000000FFFFFFFF));
return output;
}
/// <summary>
/// Returns an array of FILETIMEs.
/// </summary>
internal static OpcRcw.Hda.OPCHDA_FILETIME[] GetFILETIMEs(DateTime[] input)
{
OpcRcw.Hda.OPCHDA_FILETIME[] output = null;
if (input != null)
{
output = new OpcRcw.Hda.OPCHDA_FILETIME[input.Length];
for (var ii = 0; ii < input.Length; ii++)
{
output[ii] = Convert(Technosoftware.DaAeHdaClient.Com.Interop.GetFILETIME(input[ii]));
}
}
return output;
}
/// <summary>
/// Converts a Technosoftware.DaAeHdaClient.Time object to a Technosoftware.DaAeHdaClient.Com.Hda.OPCHDA_TIME structure.
/// </summary>
internal static OpcRcw.Hda.OPCHDA_TIME GetTime(TsCHdaTime input)
{
var output = new OpcRcw.Hda.OPCHDA_TIME();
if (input != null)
{
output.ftTime = Convert(Technosoftware.DaAeHdaClient.Com.Interop.GetFILETIME(input.AbsoluteTime));
output.szTime = (input.IsRelative)?input.ToString():"";
output.bString = (input.IsRelative)?1:0;
}
// create a null value for a time structure.
else
{
output.ftTime = Convert(Technosoftware.DaAeHdaClient.Com.Interop.GetFILETIME(DateTime.MinValue));
output.szTime = "";
output.bString = 1;
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an array of OPCHDA_ITEM structures.
/// </summary>
internal static TsCHdaItemValueCollection[] GetItemValueCollections(ref IntPtr pInput, int count, bool deallocate)
{
TsCHdaItemValueCollection[] output = null;
if (pInput != IntPtr.Zero && count > 0)
{
output = new TsCHdaItemValueCollection[count];
var pos = pInput;
for (var ii = 0; ii < count; ii++)
{
output[ii] = GetItemValueCollection(pos, deallocate);
pos = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(OpcRcw.Hda.OPCHDA_ITEM)));
}
if (deallocate)
{
Marshal.FreeCoTaskMem(pInput);
pInput = IntPtr.Zero;
}
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an OPCHDA_ITEM structure.
/// </summary>
internal static TsCHdaItemValueCollection GetItemValueCollection(IntPtr pInput, bool deallocate)
{
TsCHdaItemValueCollection output = null;
if (pInput != IntPtr.Zero)
{
var item = Marshal.PtrToStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ITEM));
output = GetItemValueCollection((OpcRcw.Hda.OPCHDA_ITEM)item, deallocate);
if (deallocate)
{
Marshal.DestroyStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ITEM));
}
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an OPCHDA_ITEM structure.
/// </summary>
internal static TsCHdaItemValueCollection GetItemValueCollection(OpcRcw.Hda.OPCHDA_ITEM input, bool deallocate)
{
var output = new TsCHdaItemValueCollection();
output.ClientHandle = input.hClient;
output.Aggregate = input.haAggregate;
var values = Com.Interop.GetVARIANTs(ref input.pvDataValues, input.dwCount, deallocate);
var timestamps = Utilities.Interop.GetDateTimes(ref input.pftTimeStamps, input.dwCount, deallocate);
var qualities = Utilities.Interop.GetInt32s(ref input.pdwQualities, input.dwCount, deallocate);
for (var ii = 0; ii < input.dwCount; ii++)
{
var value = new TsCHdaItemValue();
value.Value = values[ii];
value.Timestamp = timestamps[ii];
value.Quality = new TsCDaQuality((short)(qualities[ii] & 0x0000FFFF));
value.HistorianQuality = (TsCHdaQuality)((int)(qualities[ii] & 0xFFFF0000));
output.Add(value);
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an array of OPCHDA_MODIFIEDITEM structures.
/// </summary>
internal static TsCHdaModifiedValueCollection[] GetModifiedValueCollections(ref IntPtr pInput, int count, bool deallocate)
{
TsCHdaModifiedValueCollection[] output = null;
if (pInput != IntPtr.Zero && count > 0)
{
output = new TsCHdaModifiedValueCollection[count];
var pos = pInput;
for (var ii = 0; ii < count; ii++)
{
output[ii] = GetModifiedValueCollection(pos, deallocate);
pos = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(OpcRcw.Hda.OPCHDA_MODIFIEDITEM)));
}
if (deallocate)
{
Marshal.FreeCoTaskMem(pInput);
pInput = IntPtr.Zero;
}
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an OPCHDA_MODIFIEDITEM structure.
/// </summary>
internal static TsCHdaModifiedValueCollection GetModifiedValueCollection(IntPtr pInput, bool deallocate)
{
TsCHdaModifiedValueCollection output = null;
if (pInput != IntPtr.Zero)
{
var item = Marshal.PtrToStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_MODIFIEDITEM));
output = GetModifiedValueCollection((OpcRcw.Hda.OPCHDA_MODIFIEDITEM)item, deallocate);
if (deallocate)
{
Marshal.DestroyStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_MODIFIEDITEM));
}
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an OPCHDA_MODIFIEDITEM structure.
/// </summary>
internal static TsCHdaModifiedValueCollection GetModifiedValueCollection(OpcRcw.Hda.OPCHDA_MODIFIEDITEM input, bool deallocate)
{
var output = new TsCHdaModifiedValueCollection();
output.ClientHandle = input.hClient;
var values = Com.Interop.GetVARIANTs(ref input.pvDataValues, input.dwCount, deallocate);
var timestamps = Utilities.Interop.GetDateTimes(ref input.pftTimeStamps, input.dwCount, deallocate);
var qualities = Utilities.Interop.GetInt32s(ref input.pdwQualities, input.dwCount, deallocate);
var modificationTimes = Utilities.Interop.GetDateTimes(ref input.pftModificationTime, input.dwCount, deallocate);
var editTypes = Utilities.Interop.GetInt32s(ref input.pEditType, input.dwCount, deallocate);
var users = Utilities.Interop.GetUnicodeStrings(ref input.szUser, input.dwCount, deallocate);
for (var ii = 0; ii < input.dwCount; ii++)
{
var value = new TsCHdaModifiedValue();
value.Value = values[ii];
value.Timestamp = timestamps[ii];
value.Quality = new TsCDaQuality((short)(qualities[ii] & 0x0000FFFF));
value.HistorianQuality = (TsCHdaQuality)((int)(qualities[ii] & 0xFFFF0000));
value.ModificationTime = modificationTimes[ii];
value.EditType = (TsCHdaEditType)editTypes[ii];
value.User = users[ii];
output.Add(value);
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an array of OPCHDA_ATTRIBUTE structures.
/// </summary>
internal static TsCHdaAttributeValueCollection[] GetAttributeValueCollections(ref IntPtr pInput, int count, bool deallocate)
{
TsCHdaAttributeValueCollection[] output = null;
if (pInput != IntPtr.Zero && count > 0)
{
output = new TsCHdaAttributeValueCollection[count];
var pos = pInput;
for (var ii = 0; ii < count; ii++)
{
output[ii] = GetAttributeValueCollection(pos, deallocate);
pos = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(OpcRcw.Hda.OPCHDA_ATTRIBUTE)));
}
if (deallocate)
{
Marshal.FreeCoTaskMem(pInput);
pInput = IntPtr.Zero;
}
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an OPCHDA_ATTRIBUTE structure.
/// </summary>
internal static TsCHdaAttributeValueCollection GetAttributeValueCollection(IntPtr pInput, bool deallocate)
{
TsCHdaAttributeValueCollection output = null;
if (pInput != IntPtr.Zero)
{
var item = Marshal.PtrToStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ATTRIBUTE));
output = GetAttributeValueCollection((OpcRcw.Hda.OPCHDA_ATTRIBUTE)item, deallocate);
if (deallocate)
{
Marshal.DestroyStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ATTRIBUTE));
}
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an OPCHDA_ATTRIBUTE structure.
/// </summary>
internal static TsCHdaAttributeValueCollection GetAttributeValueCollection(OpcRcw.Hda.OPCHDA_ATTRIBUTE input, bool deallocate)
{
var output = new TsCHdaAttributeValueCollection();
output.AttributeID = input.dwAttributeID;
var values = Com.Interop.GetVARIANTs(ref input.vAttributeValues, input.dwNumValues, deallocate);
var timestamps = Utilities.Interop.GetDateTimes(ref input.ftTimeStamps, input.dwNumValues, deallocate);
for (var ii = 0; ii < input.dwNumValues; ii++)
{
var value = new TsCHdaAttributeValue();
value.Value = values[ii];
value.Timestamp = timestamps[ii];
output.Add(value);
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an array of OPCHDA_ANNOTATION structures.
/// </summary>
internal static TsCHdaAnnotationValueCollection[] GetAnnotationValueCollections(ref IntPtr pInput, int count, bool deallocate)
{
TsCHdaAnnotationValueCollection[] output = null;
if (pInput != IntPtr.Zero && count > 0)
{
output = new TsCHdaAnnotationValueCollection[count];
var pos = pInput;
for (var ii = 0; ii < count; ii++)
{
output[ii] = GetAnnotationValueCollection(pos, deallocate);
pos = (IntPtr)(pos.ToInt64() + Marshal.SizeOf(typeof(OpcRcw.Hda.OPCHDA_ANNOTATION)));
}
if (deallocate)
{
Marshal.FreeCoTaskMem(pInput);
pInput = IntPtr.Zero;
}
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an OPCHDA_ANNOTATION structure.
/// </summary>
internal static TsCHdaAnnotationValueCollection GetAnnotationValueCollection(IntPtr pInput, bool deallocate)
{
TsCHdaAnnotationValueCollection output = null;
if (pInput != IntPtr.Zero)
{
var item = Marshal.PtrToStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ANNOTATION));
output = GetAnnotationValueCollection((OpcRcw.Hda.OPCHDA_ANNOTATION)item, deallocate);
if (deallocate)
{
Marshal.DestroyStructure(pInput, typeof(OpcRcw.Hda.OPCHDA_ANNOTATION));
}
}
return output;
}
/// <summary>
/// Unmarshals and deallocates an OPCHDA_ANNOTATION structure.
/// </summary>
internal static TsCHdaAnnotationValueCollection GetAnnotationValueCollection(OpcRcw.Hda.OPCHDA_ANNOTATION input, bool deallocate)
{
var output = new TsCHdaAnnotationValueCollection();
output.ClientHandle = input.hClient;
var timestamps = Utilities.Interop.GetDateTimes(ref input.ftTimeStamps, input.dwNumValues, deallocate);
var annotations = Utilities.Interop.GetUnicodeStrings(ref input.szAnnotation, input.dwNumValues, deallocate);
var creationTimes = Utilities.Interop.GetDateTimes(ref input.ftAnnotationTime, input.dwNumValues, deallocate);
var users = Utilities.Interop.GetUnicodeStrings(ref input.szUser, input.dwNumValues, deallocate);
for (var ii = 0; ii < input.dwNumValues; ii++)
{
var value = new TsCHdaAnnotationValue();
value.Timestamp = timestamps[ii];
value.Annotation = annotations[ii];
value.CreationTime = creationTimes[ii];
value.User = users[ii];
output.Add(value);
}
return output;
}
}
}

View File

@@ -0,0 +1,404 @@
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
//-----------------------------------------------------------------------------
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
// Web: https://www.technosoftware.com
//
// The source code in this file is covered under a dual-license scenario:
// - Owner of a purchased license: SCLA 1.0
// - GPL V3: everybody else
//
// SCLA license terms accompanied with this source code.
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
//
// GNU General Public License as published by the Free Software Foundation;
// version 3 of the License are accompanied with this source code.
// See https://technosoftware.com/license/GPLv3License.txt
//
// This source code is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
//-----------------------------------------------------------------------------
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
#region Using Directives
using System;
using System.Collections;
using Technosoftware.DaAeHdaClient.Hda;
#endregion
namespace Technosoftware.DaAeHdaClient.Com.Hda
{
/// <summary>
/// An object that mainatains the state of asynchronous requests.
/// </summary>
internal class Request : IOpcRequest, ITsCHdaActualTime
{
/// <summary>
/// The unique id assigned to the request when it was created.
/// </summary>
public int RequestID => m_requestID;
/// <summary>
/// The unqiue id assigned by the server when it was created.
/// </summary>
public int CancelID => m_cancelID;
/// <summary>
/// Fired when the server acknowledges that a request was cancelled.
/// </summary>
public event TsCHdaCancelCompleteEventHandler CancelCompleteEvent
{
add { lock (this) { m_cancelCompleteEvent += value; } }
remove { lock (this) { m_cancelCompleteEvent -= value; } }
}
/// <summary>
/// Initializes the object with all required information.
/// </summary>
public Request(object requestHandle, Delegate callback, int requestID)
{
m_requestHandle = requestHandle;
m_callback = callback;
m_requestID = requestID;
}
/// <summary>
/// Updates the request with the initial results.
/// </summary>
public bool Update(int cancelID, OpcItem[] results)
{
lock (this)
{
// save the server assigned id.
m_cancelID = cancelID;
// create a table of items indexed by the handle returned by the server in a callback.
m_items = new Hashtable();
foreach (var result in results)
{
if (!typeof(IOpcResult).IsInstanceOfType(result) || ((IOpcResult)result).Result.Succeeded())
{
m_items[result.ServerHandle] = new OpcItem(result);
}
}
// nothing more to do - no good items.
if (m_items.Count == 0)
{
return true;
}
// invoke callbacks for results that have already arrived.
var complete = false;
if (m_results != null)
{
foreach (var result in m_results)
{
complete = InvokeCallback(result);
}
}
// all done.
return complete;
}
}
/// <summary>
/// Invokes the callback for the request.
/// </summary>
public bool InvokeCallback(object results)
{
lock (this)
{
// save the results if the initial call to the server has not completed yet.
if (m_items == null)
{
// create cache for results.
if (m_results == null)
{
m_results = new ArrayList();
}
m_results.Add(results);
// request not initialized completely
return false;
}
// invoke on data update callback.
if (typeof(TsCHdaDataUpdateEventHandler).IsInstanceOfType(m_callback))
{
return InvokeCallback((TsCHdaDataUpdateEventHandler)m_callback, results);
}
// invoke read completed callback.
if (typeof(TsCHdaReadValuesCompleteEventHandler).IsInstanceOfType(m_callback))
{
return InvokeCallback((TsCHdaReadValuesCompleteEventHandler)m_callback, results);
}
// invoke read attributes completed callback.
if (typeof(TsCHdaReadAttributesCompleteEventHandler).IsInstanceOfType(m_callback))
{
return InvokeCallback((TsCHdaReadAttributesCompleteEventHandler)m_callback, results);
}
// invoke read annotations completed callback.
if (typeof(TsCHdaReadAnnotationsCompleteEventHandler).IsInstanceOfType(m_callback))
{
return InvokeCallback((TsCHdaReadAnnotationsCompleteEventHandler)m_callback, results);
}
// invoke update completed callback.
if (typeof(TsCHdaUpdateCompleteEventHandler).IsInstanceOfType(m_callback))
{
return InvokeCallback((TsCHdaUpdateCompleteEventHandler)m_callback, results);
}
// callback not supported.
return true;
}
}
/// <summary>
/// Called when the server acknowledges that a request was cancelled.
/// </summary>
public void OnCancelComplete()
{
lock (this)
{
if (m_cancelCompleteEvent != null)
{
m_cancelCompleteEvent(this);
}
}
}
#region IOpcRequest Members
/// <summary>
/// An unique identifier, assigned by the client, for the request.
/// </summary>
public object Handle => m_requestHandle;
#endregion
#region IActualTime Members
/// <summary>
/// The actual start time used by a server while processing a request.
/// </summary>
public DateTime StartTime
{
get => m_startTime;
set => m_startTime = value;
}
/// <summary>
/// The actual end time used by a server while processing a request.
/// </summary>
public DateTime EndTime
{
get => m_endTime;
set => m_endTime = value;
}
#endregion
#region Private Methods
/// <summary>
/// Invokes callback for a data change update.
/// </summary>
private bool InvokeCallback(TsCHdaDataUpdateEventHandler callback, object results)
{
// check for valid result type.
if (!typeof(TsCHdaItemValueCollection[]).IsInstanceOfType(results))
{
return false;
}
var values = (TsCHdaItemValueCollection[])results;
// update item handles and actual times.
UpdateResults(values);
try
{
callback(this, values);
}
catch
{
// ignore exceptions in the callbacks.
}
// request never completes.
return false;
}
/// <summary>
/// Invokes callback for a read request.
/// </summary>
private bool InvokeCallback(TsCHdaReadValuesCompleteEventHandler callback, object results)
{
// check for valid result type.
if (!typeof(TsCHdaItemValueCollection[]).IsInstanceOfType(results))
{
return false;
}
var values = (TsCHdaItemValueCollection[])results;
// update item handles and actual times.
UpdateResults(values);
try
{
callback(this, values);
}
catch
{
// ignore exceptions in the callbacks.
}
// check if all data has been sent.
foreach (var value in values)
{
if (value.Result == OpcResult.Hda.S_MOREDATA)
{
return false;
}
}
// request is complete.
return true;
}
/// <summary>
/// Invokes callback for a read attributes request.
/// </summary>
private bool InvokeCallback(TsCHdaReadAttributesCompleteEventHandler callback, object results)
{
// check for valid result type.
if (!typeof(TsCHdaItemAttributeCollection).IsInstanceOfType(results))
{
return false;
}
var values = (TsCHdaItemAttributeCollection)results;
// update item handles and actual times.
UpdateResults(new TsCHdaItemAttributeCollection[] { values });
try
{
callback(this, values);
}
catch
{
// ignore exceptions in the callbacks.
}
// request always completes
return true;
}
/// <summary>
/// Invokes callback for a read annotations request.
/// </summary>
private bool InvokeCallback(TsCHdaReadAnnotationsCompleteEventHandler callback, object results)
{
// check for valid result type.
if (!typeof(TsCHdaAnnotationValueCollection[]).IsInstanceOfType(results))
{
return false;
}
var values = (TsCHdaAnnotationValueCollection[])results;
// update item handles and actual times.
UpdateResults(values);
try
{
callback(this, values);
}
catch
{
// ignore exceptions in the callbacks.
}
// request always completes
return true;
}
/// <summary>
/// Invokes callback for a read annotations request.
/// </summary>
private bool InvokeCallback(TsCHdaUpdateCompleteEventHandler callback, object results)
{
// check for valid result type.
if (!typeof(TsCHdaResultCollection[]).IsInstanceOfType(results))
{
return false;
}
var values = (TsCHdaResultCollection[])results;
// update item handles and actual times.
UpdateResults(values);
try
{
callback(this, values);
}
catch
{
// ignore exceptions in the callbacks.
}
// request always completes
return true;
}
/// <summary>
/// Updates the result objects with locally cached information.
/// </summary>
private void UpdateResults(OpcItem[] results)
{
foreach (var result in results)
{
// update actual times.
if (typeof(ITsCHdaActualTime).IsInstanceOfType(result))
{
((ITsCHdaActualTime)result).StartTime = StartTime;
((ITsCHdaActualTime)result).EndTime = EndTime;
}
// add item identifier to value collection.
var itemID = (OpcItem)m_items[result.ServerHandle];
if (itemID != null)
{
result.ItemName = itemID.ItemName;
result.ItemPath = itemID.ItemPath;
result.ServerHandle = itemID.ServerHandle;
result.ClientHandle = itemID.ClientHandle;
}
}
}
#endregion
#region Private Members
private object m_requestHandle = null;
private Delegate m_callback = null;
private int m_requestID = 0;
private int m_cancelID = 0;
private DateTime m_startTime = DateTime.MinValue;
private DateTime m_endTime = DateTime.MinValue;
private Hashtable m_items = null;
private ArrayList m_results = null;
private event TsCHdaCancelCompleteEventHandler m_cancelCompleteEvent = null;
#endregion
}
}

View File

@@ -0,0 +1,68 @@
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
//-----------------------------------------------------------------------------
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
// Web: https://www.technosoftware.com
//
// The source code in this file is covered under a dual-license scenario:
// - Owner of a purchased license: SCLA 1.0
// - GPL V3: everybody else
//
// SCLA license terms accompanied with this source code.
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
//
// GNU General Public License as published by the Free Software Foundation;
// version 3 of the License are accompanied with this source code.
// See https://technosoftware.com/license/GPLv3License.txt
//
// This source code is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
//-----------------------------------------------------------------------------
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
#region Using Directives
#endregion
namespace Technosoftware.DaAeHdaClient.Com
{
namespace Hda
{
/// <summary>
/// Defines all well known COM HDA HRESULT codes.
/// </summary>
internal struct Result
{
/// <remarks/>
public const int E_MAXEXCEEDED = -0X3FFBEFFF; // 0xC0041001
/// <remarks/>
public const int S_NODATA = +0x40041002; // 0x40041002
/// <remarks/>
public const int S_MOREDATA = +0x40041003; // 0x40041003
/// <remarks/>
public const int E_INVALIDAGGREGATE = -0X3FFBEFFC; // 0xC0041004
/// <remarks/>
public const int S_CURRENTVALUE = +0x40041005; // 0x40041005
/// <remarks/>
public const int S_EXTRADATA = +0x40041006; // 0x40041006
/// <remarks/>
public const int W_NOFILTER = -0x7FFBEFF9; // 0x80041007
/// <remarks/>
public const int E_UNKNOWNATTRID = -0x3FFBEFF8; // 0xC0041008
/// <remarks/>
public const int E_NOT_AVAIL = -0x3FFBEFF7; // 0xC0041009
/// <remarks/>
public const int E_INVALIDDATATYPE = -0x3FFBEFF6; // 0xC004100A
/// <remarks/>
public const int E_DATAEXISTS = -0x3FFBEFF5; // 0xC004100B
/// <remarks/>
public const int E_INVALIDATTRID = -0x3FFBEFF4; // 0xC004100C
/// <remarks/>
public const int E_NODATAEXISTS = -0x3FFBEFF3; // 0xC004100D
/// <remarks/>
public const int S_INSERTED = +0x4004100E; // 0x4004100E
/// <remarks/>
public const int S_REPLACED = +0x4004100F; // 0x4004100F
}
}
}

File diff suppressed because it is too large Load Diff