# WCF Contract Evidence ## Local run evidence - `current\aahClient.dll` export inventory ran successfully. SHA256: `77a778988e2d8f2d0e88113f8c8b0788a0ef34fa5134938a353976778144dc83`. - `ArchestrA.HistorianAccess.OpenConnection` succeeded against `localhost:32568` using `HistorianConnectionArgs` with `ConnectionType=Process` and `ReadOnly=true`. - Holding that native connection open produced established TCP sessions from the native PowerShell process to `127.0.0.1:32568`; the server-side listener was owned by `SMSvcHost.exe`, consistent with WCF Net.TCP port sharing. - The managed harness command `dotnet run --no-build --project tools\AVEVA.Historian.ReverseEngineering -- wcf-probe localhost 32568` successfully called `GetV` through fully managed WCF/MDAS: - `net.tcp://localhost:32568/Hist` returned version `11` - `net.tcp://localhost:32568/Retr` returned version `4` - `net.tcp://localhost:32568/Stat` returned version `0` - `net.tcp://localhost:32568/Trx` returned version `2` - `net.tcp://localhost:32568/Storage` did not listen on this local install - `net.tcp://localhost:32568/HistCert` and `/Hist-Integrated` reset when called with the plain managed `GetV` contract, while prefixed variants such as `/HCAP/HistCert` returned `EndpointNotFound` Sanitized output is stored in `docs\reverse-engineering\wcf-probe-localhost.json`. - `netsh trace` and `pktmon` produced ETL files under `%TEMP%\histsdk-captures`, but their converted PCAPNG files contained zero packets. Built-in Windows packet capture is not sufficient for loopback evidence on this machine. - A dedicated managed certificate-binding probe now reaches `HistCert.GetV` through MDAS over WCF Net.TCP transport security: - `net.tcp://localhost:32568/HistCert` returned version `11` - `net.tcp://10.100.0.48:32568/HistCert` initially failed endpoint identity validation because the server certificate presented DNS identity `localhost` - the same remote endpoint returned version `11` when the client supplied endpoint DNS identity `localhost` Sanitized outputs are stored in `docs\reverse-engineering\wcf-cert-probe-localhost-latest.json`, `docs\reverse-engineering\wcf-cert-probe-remote-latest.json`, and `docs\reverse-engineering\wcf-cert-probe-remote-localhost-identity-latest.json`. - The same remote server also accepts the plain managed WCF/MDAS probe on the expected non-security-specific service paths: - `net.tcp://10.100.0.48:32568/Hist` returned version `11` - `net.tcp://10.100.0.48:32568/Retr` returned version `4` - `net.tcp://10.100.0.48:32568/Stat` returned version `0` - `net.tcp://10.100.0.48:32568/Trx` returned version `2` Sanitized output is stored in `docs\reverse-engineering\wcf-probe-remote-latest.json`. - Managed remote `Open2` evidence matches localhost: integrated Windows auth succeeds on `net.tcp://10.100.0.48:32568/Hist-Integrated`, while the same Windows transport binding fails on plain `/Hist` before dispatch. The successful returned handle is accepted by `Retr.IsOriginalAllowed`. Session output bytes and transient handle values are redacted in `docs\reverse-engineering\wcf-open2-remote-latest.json`. - Managed remote `StartQuery2` evidence is still negative but sharper: all 22 reconstructed `DataQueryRequest` variants successfully open the integrated session and pass `Retr.IsOriginalAllowed`, then `StartQuery2` returns `false` with zero response and error sizes. The legacy `StartQuery` call returns code `238` for each request and also returns zero response size/no response buffer. Sanitized request hashes are stored in `docs\reverse-engineering\wcf-start-query-remote-latest.json`. - A later bounded managed replay of the first byte-matched full-history candidate used the same integrated open and `Retr.IsOriginalAllowed` path; `StartQuery2` still returned `false` with zero response/error sizes, while legacy `StartQuery` faulted with a server null-reference. This keeps `Open2` as useful connection evidence, but not as a viable replacement for the native `OpenConnection3` session state required by query reads. - Managed wildcard tag browse remains positive evidence for an `Open2`-backed operation: `Retr.StartLikeTagNameSearch` returned `0`, and one `GetLikeTagnames` batch returned the deterministic 66-byte single-tag buffer with SHA-256 `2d450a55f392aed0026e9a957fefa3b116aab6ec81912c5d824c6b9a1ff5a4a1`. - Managed remote scalar tag calls also accept the integrated session handle: `Retr.GetTagTypeFromName` returns code `0` and tag type `1` for `OtOpcUaParityTest_001.Counter`; `Retr.IsManualTag` returns code `0` and `false`; legacy `Retr.GetTagInfoFromName` returns `238` with zero metadata bytes. Five `GetTgByNm` tag-name buffer variants and five `GetTg` tag-id buffer variants all return `238`, sequence `0`, and zero output bytes. This suggests the calls are reaching server logic but the metadata-returning contract shape or request buffer is still incomplete. Sanitized output is stored in `docs\reverse-engineering\wcf-tag-info-remote-latest.json`. ## Decompiled service contracts `current\aahClientManaged.dll` contains WCF contracts with namespace `aa`: - `HistoryServiceContract.IHistoryServiceContract` - `[ServiceContract(Name = "Hist", Namespace = "aa")]` - `GetInterfaceVersion` as operation `GetV` - `OpenConnection` as operation `Open` - `CloseConnection` as operation `Close` - `ValidateClient` as operation `VldC` - `UpdateClientStatus` as operation `UpdC` - `AddTags` as `AddT`, `RegisterTags` as `RTag` - `AddStreamValues` as `AddS`, `SetClientTimeOut` as `SetT` - `HistoryServiceContract.IHistoryServiceContract2` - `[ServiceContract(Name = "Hist", Namespace = "aa")]` - byte-buffer session open uses `OpenConnection2` as operation `Open2` - extended client status uses `UpdC2` / `UpdC3` - extended write and maintenance calls include `EnsT`, `DelT`, `AddS2`, `ExKey`, `ValCl`, and `GetI` - `RetrievalServiceContract.IRetrievalServiceContract` - `[ServiceContract(Name = "Retr", Namespace = "aa")]` - `StartQuery`, `GetNextQueryResultBuffer`, `EndQuery` use default operation names - tag type/name helpers and tag info calls use default operation names - `RetrievalServiceContract.IRetrievalServiceContract2/3/4` - extended bool/error-buffer variants - SQL/recordset byte stream calls - tag query calls `QTB`, `QTG`, `QTE` - event query calls use default operation names - extended property calls include `GetTgByNm2` and `GetTepByNm` - `StorageServiceContract.IStorageServiceContract` - `[ServiceContract(Name = "Storage", Namespace = "aa")]` - storage/session, metadata, streamed-value, block, snapshot, and delete-tag calls - `StatusServiceContract.IStatusServiceContract` - `[ServiceContract(Name = "Stat", Namespace = "aa")]` - `GetInterfaceVersion` as `GetV` - server time, timezone, DB case sensitivity, and logging use default operation names - `StatusServiceContract.IStatusServiceContract2` - extended status operations include `GetSystemParameter`, `GetTimeZoneNames`, license checks, historian info, and process/ping helpers - ping and historian-info helpers use aliases `PNGS`, `PNGP`, and `GETHI` - `TransactionServiceContract.ITransactionServiceContract` - `[ServiceContract(Name = "Trx", Namespace = "aa")]` - snapshot forwarding and non-streamed value transactions `aahMDASEncoder.ClientMessageEncoder` wraps an inner WCF encoder and exposes media/content type `application/x-mdas`. This means the first managed driver transport target should be WCF Net.TCP plus the MDAS content-type encoder, not the earlier speculative raw-frame layer. ## Current unknowns - Endpoint URI paths `net.tcp://{host}:32568/Hist`, `/Retr`, `/Stat`, and `/Trx` are confirmed for `GetV` calls on the local 2020 install. - Relay and local WCF probe evidence also identify security-specific history endpoints `/HistCert` and `/Hist-Integrated`. `/HistCert` is confirmed as a `Hist` contract endpoint when called with MDAS over TLS transport security; `/Hist-Integrated` remains the Windows negotiate endpoint for integrated session open. - Managed `Open2` evidence confirms `/Hist-Integrated` is the correct endpoint for integrated Windows auth. The plain `/Hist` endpoint rejects the Windows transport-security upgrade before dispatching the operation. - The storage contract is confirmed statically, but `/Storage` was not a listening endpoint in the local probe; storage may be routed through session-specific storage/shard endpoints. - `Hist.OpenConnection` reaches server logic, but the native password/session packet encoding is not decoded yet. See `wcf-open-localhost.md`. - `Hist.Open2` is confirmed reachable with a managed version-1 byte buffer. Empty credentials return custom native error `171` (`AuthenticationFailed`), and the harness decodes observed five-byte error buffers as type plus little-endian error code. This confirms framing has progressed past packet-version rejection. See `wcf-open2-localhost.md`. - `Stat` is reachable, but `CStatusConnectionWCF.GetServerTime` is a no-op stub in the decompiled native WCF path and handle-dependent status calls fail with handle `0`. See `wcf-status-localhost.md`. - Query request and response byte-buffer layouts are still proprietary payloads inside WCF operations such as `StartQuery` and `GetNextQueryResultBuffer`. - Write payload layouts remain out of scope until read/query payloads are decoded and fixture-backed.