////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation.
//
// SYNOPSIS
//
//    IDL source for interaction with System health agents.
//
////////////////////////////////////////////////////////////

#ifndef NAPSYSTEMHEALTHAGENT_IDL
#define NAPSYSTEMHEALTHAGENT_IDL

import "NapTypes.idl";
import "unknwn.idl";


interface INapSystemHealthAgentCallback;

// System health agents must use the following interface to
// communicate with the NapAgent.
// All the APIs in this interface will return 
// RPC_E_DISCONNECTED if the NapAgent is stopped. This 
// object will recover automatically and rebind to the 
// NapAgent, once it restarts.
// 
[object, 
uuid(A6894F43-9CC7-44c9-A23F-19DBF36BAD28), 
pointer_default(unique)]
interface INapSystemHealthAgentBinding : IUnknown
{
   // Must be the first method called on this interface. 
   // This automatically starts up the NapAgent service.
   //
   // Parameters:-
   // id: Identifies the system health agent and its version
   // callback: COM pointer used by the NapAgent to callback 
   //   the health agent with notify/process. The NapAgent  
   //   holds a reference to this object until 
   //   Uninitialize() is called or NapAgent stops.
   // 
   // Return values:-
   // HRESULT(ERROR_ALREADY_INITIALIZED): If the SHA has 
   //   initialized previously, then this error code is 
   //   returned.
   // NAP_E_NOT_REGISTERED: If the SHA has not registered
   //   earlier, this error code is returned.
   //
   HRESULT
   Initialize(
      [in] SystemHealthEntityId id,
      [in] INapSystemHealthAgentCallback* callback
      );

   // NapAgent blocks until all existing calls on the 
   // Binding and Callback interfaces complete. At the end 
   // of this call, the NapAgent releases all its references 
   // on system health agent COM pointers.
   // 
   // Return values:-
   // NAP_E_NOT_INITIALIZED: The SHA has not been previously
   //   initialized.
   // 
   HRESULT
   Uninitialize();

   // System health agents calls this API when their SoH 
   // changes. The NapAgent does not hold this thread to 
   // process the SoH change. Instead, it returns 
   // immediately and processes the change asynchronously.
   // 
   // NOTE: This API must be called judiciously, since it
   // results in an SoH-exchange on the wire. SHAs must
   // *not* call this function speculatively.
   // 
   // Return values:-
   // NAP_E_NOT_INITIALIZED: The SHA has not been previously
   //   initialized.
   // 
   HRESULT
   NotifySoHChange();

   // System health agents call this API to determine the 
   // system isolation state.
   // 
   // Parameters:-
   // isolationInfo: indicates if the system is in 
   //    restricted access, probation, etc. This does not 
   //    reflect unknown connection states.
   // unknownConnections: set to true if any connections
   //    are in an unknown state.
   // 
   // Return values:-
   // NAP_E_NOT_INITIALIZED: The SHA has not been previously
   //   initialized.
   // 
   HRESULT
   GetSystemIsolationInfo(
      [out] IsolationInfo** isolationInfo,
      [out] BOOL* unknownConnections
      ) const;

   // The NapAgent maintains a cache of recent SoHs provided
   // by different SHAs. This cache is useful to optimize
   // boot-time, when SHAs may or may not be bound to the
   // system.
   // An SHA can flush only its own cache by calling this 
   // API.
   // 
   HRESULT
   FlushCache();
};
   

[object, 
uuid(1140C38E-5100-4ea1-8D43-87D326724028), 
pointer_default(unique)]
interface INapSystemHealthAgentBinding2 : INapSystemHealthAgentBinding
{
   // System health agents call this API to determine the 
   // system isolation state and extended isolation state.
   // 
   // Parameters:-
   // isolationInfo: indicates if the system is in 
   //    restricted access, probation, etc. This does not 
   //    reflect unknown connection states. It also indicates
   //    the extended isolation state of the system.
   // unknownConnections: set to true if any connections
   //    are in an unknown state.
   // 
   // Return values:-
   // NAP_E_NOT_INITIALIZED: The SHA has not been previously
   //   initialized.
   // 
   HRESULT
   GetSystemIsolationInfoEx(
      [out] IsolationInfoEx** isolationInfo,
      [out] BOOL* unknownConnections
      ) const;
};

interface INapSystemHealthAgentRequest;

// System health agents must implement this interface to 
// enable the NapAgent to communicate with it. They must 
// never do I/O in the methods below. Instead, they should 
// return these calls synchronously and queue work-items to 
// perform I/O as needed.
// 
// Return values:-
// RPC_S_SERVER_UNAVAILABLE: If any of the methods below 
// return this error code, then the SHA is removed from
// the bound-SHA list, and the corresponding NapAgent
// cache entry is flushed. Henceforth, the failing SHA can
// re-initialize itself with the NapAgent.
// 
// If any other error code is returned, it is ignored; 
// unless otherwise specified.
// 
[object, 
uuid(F1072A57-214F-4ee2-8377-14EF140CD9F3), 
async_uuid(860D8FD9-0219-43ea-AE7F-59611F4CC16A),
pointer_default(unique)]
interface INapSystemHealthAgentCallback : IUnknown
{
   // NapAgent calls this to query the system health agents 
   // SoHRequest. The system health agents can query the 
   // request passed for parameters that it needs to compute
   // the SoH-Request. It must set the computed SoHRequest 
   // on the request object. The health agents must not hold
   // references to the request object once this call has 
   // completed.
   // 
   // When this method is called, if there is an soh in
   // NapAgent's cache, then it is set on the request 
   // object. The SHA can query for it using GetSoHRequest().
   // If the SHA does not set a new one, then the
   // cached one is used.
   // 
   //
   // Parameters:-
   // request: COM pointer identifying the request object.
   //
   // Return values:-
   // RPC_S_SERVER_UNAVAILABLE: the NapAgent then removes
   //    the SHA from the bound-SHA list and flushes its
   //    cache entry.
   // <any other error code>: The NAP system constructs
   //    and returns the following SoH-Request to the 
   //    corresponding SHV:
   //       SHA-id = <id>
   //       Failure-Category = clientComponentFailure
   //       Error-Codes = <error-code>
   //
   // Note:-
   // For unbound SHAs which are registered with the system, 
   // the NAP system constructs and sends the following 
   // SoH-request to the corresponding SHV:
   //     SHA-id = <id>
   //     Failure-Category = clientComponentFailure
   //     Error-Codes = NAP_E_NOT_INITIALIZED
   //
   HRESULT
   GetSoHRequest(
      [in] INapSystemHealthAgentRequest* request
      );

   // When the NapAgent receives an SoHResponse destined for 
   // this health agent, it invokes this method. The health 
   // agent must query the SoHResponse from the request 
   // object. It must not hold references to the request 
   // object once this call has completed.
   //
   // Parameters:-
   // request: COM pointer identifying the request object.
   // 
   // Return values:-
   // NAP_E_INVALID_PACKET: must return this if the 
   //   response is not in the correct format. 
   //
   HRESULT
   ProcessSoHResponse(
      [in] INapSystemHealthAgentRequest* request
      );

   // NapAgent calls this method to indicate that the system
   // isolation state or the probation-end time has changed.
   // The health agent can query the system NAP state using 
   // the Binding::GetSystemIsolationInfo() described above.
   //
   HRESULT
   NotifySystemIsolationStateChange() const;

   // NapAgent calls this method to determine the state of 
   // the system health agent, while it is processing an 
   // SoH-Response. The health agent must return 
   // 'success' if it is not currently processing an 
   // SoH-Response.
   //
   // Parameters:-
   // info: indicates the fixup status of the agent.
   //
   HRESULT
   GetFixupInfo(
      [out] FixupInfo** info
      ) const;

   // The SHA should compare the SoH's and return isEqual as
   // TRUE if the SoHs are semantically equal.
   // The NapAgent uses this information to determine if 
   // an SoH exchange should be initiated due to change of 
   // state of the client machine.
   // 
   // If SHAs have put incremental ids or timestamps into 
   // their SoH, then 2 soh's may be semantically equal
   // (i.e. they may convey the same health information), 
   // but they may be byte-wise unequal. SHAs should be 
   // carefully to implement this function such that they
   // check for semantic equality on SoHs.
   // 
   // If SHAs have not put any timestamps or ids into their
   // SoH, they may choose to not implement this function
   // and return E_NOTIMPL. In this case, NapAgent performs
   // a byte-wise comparison on the SoHRequests.
   // 
   HRESULT
   CompareSoHRequests(
      [in] const SoHRequest* lhs, 
      [in] const SoHRequest* rhs,
      [out] BOOL* isEqual
      ) const;

   // If an SoH-Request was queried from the SHA, but the 
   // response never came back, then this method is called.
   // This can happen in the following cases:
   //    1). SoH-request could not be sent out on the wire.
   //    2). SoH-request was sent on the wire, but no resp
   //         came back, i.e. enforcer timed out or there
   //         was no corresponding SHV on the server-side.
   //    3). The connection went down or an enforcer 
   //        went away.
   // 
   // Note: This is only a best effort notification, so
   //    SHAs must not rely on this information to clean up
   //    state. There are several situations in which an
   //    SHA will not be notified:
   //    a). If an enforcer misbehaves, for eg. does not
   //        notify conn state down.
   //    b). If an enforcer crashes.
   //    c). In error conditions, for eg. NapAgent is out
   //        of memory.
   //    
   // Note: SHAs may get some spurious notifications when
   //    they first bind to the NapAgent, for instance, if 
   //    an SoH exchange is in progress when the SHA bound,
   //    and then it times out.
   // 
   // Parameters:-
   // correlationId: id of the orphaned soh-request.
   // 
   HRESULT
   NotifyOrphanedSoHRequest(
      [in] const CorrelationId* correlationId
      );
};


[object, 
uuid(5B360A69-212D-440d-B398-7EEFD497853A), 
pointer_default(unique)]
interface INapSystemHealthAgentRequest : IUnknown
{
   // System health agents can use this information to
   // correlate SoH's and SoH-Responses.
   // 
   // Parameters:-
   // correlationId: unique id for SoH exchange.
   HRESULT
   GetCorrelationId(
      [out] CorrelationId* correlationId
      ) const;

   // System health agents must log the correlation id
   // returned through the following method.
   // 
   HRESULT
   GetStringCorrelationId(
      [out] StringCorrelationId** correlationId
      ) const;

   // As a result of the Callback::GetSoHRequest(), system 
   // health agents must write their SoH request using the 
   // following method.
   //
   // Parameters:-
   // sohRequest: SoH-Request packet.
   // cacheSohForLaterUse: Set to false if the SHA does not 
   //   want NapAgent to cache Soh.
   // 
   HRESULT
   SetSoHRequest(
      [in] const SoHRequest* sohRequest,
      [in] BOOL cacheSohForLaterUse
      );

   // NapAgent caches SoHs previously provided by SHAs. 
   // SHAs can use the following method to get previously
   // cached SoH. 
   // 
   // Return codes:-
   //    NAP_E_NO_CACHED_SOH: The soh is not
   //       found; NapAgent does not have a cached copy.
   //    
   HRESULT
   GetSoHRequest(
      [out] SoHRequest** sohRequest
      ) const;

   // When NapAgent calls Callback::ProcessSoHResponse(),  
   // the health agent must retrieve their SoHResponse blob 
   // using the following method.
   //
   // Parameters:-
   // SoHResponse: SoH-Response packet.
   // flags: Flag to enable or disable fixup by SHA.
   //
   HRESULT
   GetSoHResponse(
      [out] SoHResponse** sohResponse,
      [out] UINT8* flags
      ) const;

   // The following method is used only by NapAgent.
   // 
   HRESULT
   GetCacheSoHFlag(BOOL* cacheSohForLaterUse) const;
};


cpp_quote("// Declarations of CLSIDs of objects provided  ")
cpp_quote("// by the system. Link to uuid.lib to get them ")
cpp_quote("// defined.                                    ")
cpp_quote("EXTERN_C const CLSID ")
cpp_quote("   CLSID_NapSystemHealthAgentBinding;")

#endif // NAPSYSTEMHEALTHAGENT_IDL

