////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation.
//
// SYNOPSIS
//
//    IDL source for interaction with enforcement clients.
//
////////////////////////////////////////////////////////////

#ifndef NAPENFORCEMENTCLIENT_IDL
#define NAPENFORCEMENTCLIENT_IDL

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

interface INapEnforcementClientCallback;
interface INapEnforcementClientConnection;


// Enforcement clients must use this 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(92B93223-7487-42d9-9A91-5B8507720384), 
pointer_default(unique)]
interface INapEnforcementClientBinding : IUnknown
{
   // Must be the first method called on this interface. 
   // This starts up the NapAgent service automatically.
   // 
   // Parameters:-
   // id: identifies the enforcement client and its version.
   // callback: COM pointer used by the NapAgent to callback
   //   the enforcement clients with notify/process. 
   //   NapAgent holds a reference to this object until 
   //   Uninitialize() is called.
   //
   // Return values:-
   // HRESULT(ERROR_ALREADY_INITIALIZED): If the enforcer  
   //   has initialized previously, then this error code is 
   //   returned.
   // NAP_E_NOT_REGISTERED: If the enforcer has not registered
   //   earlier, this error code is returned.
   //
   HRESULT
   Initialize(
      [in] EnforcementEntityId id,
      [in] INapEnforcementClientCallback* 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 enforcement client COM pointers.
   // 
   // Before this function is called, the enforcer must
   // call NotifyConnectionStateDown() on all its 
   // active connections, so that the SHAs can be notified
   // if any of their SoH-Requests got orphaned.
   //
   // Return values:-
   // NAP_E_NOT_INITIALIZED: The enforcer has not been 
   //   previously initialized.
   // 
   HRESULT
   Uninitialize();

   // Enforcers use this factory method to create connection
   // objects.
   // 
   // Parameters:-
   // connection: COM pointer in which the new connection 
   //   object is returned.
   //
   HRESULT
   CreateConnection(
      [out] INapEnforcementClientConnection** connection
      ) const;

   // Enforcement client calls this method when they need an
   // SoH request for a particular connection. The NapAgent 
   // sets the SoH request on the connection object.
   // 
   // If an SoH-request was outstanding on this connection,
   // then it is discarded, and the SHAs are notified of
   // orphaned soh-requests.
   //
   // Parameters:-
   // connection: COM object identifying the connection. 
   //   NapAgent does not hold references to this after the 
   //   function completes. 
   // retriggerHint: Boolean value indicating if the 
   //   connection should be re-triggered. Examples where 
   //   NapAgent returns true are
   //   1). if SoHRequest is different than the previous 
   //       time this function was called, OR
   //   2). Probation Time has expired. 
   //
   // Return values:-
   // NAP_E_NOT_INITIALIZED: The enforcer has not been 
   //   previously initialized.
   // 
   HRESULT
   GetSoHRequest(
      [in] INapEnforcementClientConnection* connection,
      [out] BOOL* retriggerHint
      );

   // Enforcement clients call this method whenever they get
   // an SoHResponse blob from the enforcement server.
   // NapAgent queries the SoHResponse blob from the 
   // connection object, processes it, and sets the 
   // resultant decision (eg. full/restricted access/etc)
   // on the connection object.
   //
   // Parameters:-
   // connection: COM pointer that identifies the connection 
   //   object. NapAgent does not hold references to this 
   //   after this call completes.
   // 
   // Return values:-
   // 
   // NAP_E_INVALID_PACKET: the enforcement client must 
   //   drop the packet if the NapAgent returns 
   //   NAP_E_INVALID_PACKET. In this case, the enforcer
   //   must assume that the server it is talking to is 
   //   not NAP-enabled and remove the connection from
   //   the *active* list; i.e. notify NapAgent of a
   //   connection state down.
   // 
   // NAP_E_MISMATCHED_ID: this indicates that the 
   //   correlation id in the SoH-Response packet did not 
   //   match up to the outstanding SoH. This may be a 
   //   response to an older request message. In this case, 
   //   the enforcer should drop the packet and wait for 
   //   another newer SoH-Response packet.
   // 
   // NAP_E_NOT_INITIALIZED: The enforcer has not been 
   //   previously initialized.
   // 
   HRESULT
   ProcessSoHResponse(
      [in] INapEnforcementClientConnection* connection
      );

   // When any of the connections established by an 
   // enforcement client goes down, it removes the 
   // connection from its active list and informs the 
   // NapAgent using this method. As soon as this call
   // returns, the connection object can be released
   // and freed. The NapAgent will not hold references
   // to the connection object.
   // 
   // The NapAgent then updates its system NAP state as 
   // appropriate.
   //
   // Return values:-
   // NAP_E_NOT_INITIALIZED: The enforcer has not been 
   //   previously initialized.
   // 
   HRESULT
   NotifyConnectionStateDown(
      [in] INapEnforcementClientConnection* downCxn
      );

   // If the enforcement client could not process a previous
   // Callback::NotifySoHChange(), it informs the NapAgent 
   // using the following method. The NapAgent then retries 
   // applying the SoH change at a later time by calling 
   // NotifySoHChange() again. Once the enforcement client 
   // has called GetSoHRequest(), then it must apply the 
   // change, i.e. no failures are handled by the NapAgent 
   // after this point.
   //
   // Return values:-
   // NAP_E_NOT_INITIALIZED: The enforcer has not been 
   //   previously initialized.
   // 
   HRESULT
   NotifySoHChangeFailure();
};
   

// Enforcement clients must implement the following callback
// interface to enable the NapAgent to communicate with it.
// 
// Return values:-
// RPC_S_SERVER_UNAVAILABLE: If any of the methods below 
// return this error code, then the enforcer is removed from
// the bound-QEC list. Henceforth, the failing QEC can
// re-initialize itself with the NapAgent.
// 
[object, 
uuid(F5A0B90A-83A1-4f76-BA3F-025418682814), 
pointer_default(unique)]
interface INapEnforcementClientCallback : IUnknown
{
   // NapAgent informs the enforcement client of SoH changes 
   // using this method. The enforcer must then call
   // Binding::GetSoHRequest() to retrieve the new request.
   // This call can be made on the same thread as 
   // NotifySoHChange.
   //
   HRESULT
   NotifySoHChange();

   // To update the system isolation state, the NapAgent 
   // needs to know all the connections maintained by 
   // enforcers. NapAgent uses this method to get connection 
   // information. Enforcement clients must provide only a 
   // list of connections that are UP.
   //
   // Parameters:-
   // connectionList: list of connection objects.
   //
   typedef struct tagConnections
   {
      [range(0, maxConnectionCountPerEnforcer)] UINT16 count;
      [size_is(count)] 
      INapEnforcementClientConnection** connections;
   } Connections;
   HRESULT
   GetConnections([out] Connections** connections) const;
};


[object, 
uuid(FB3A3505-DDB1-468a-B307-F328A57419D8), 
pointer_default(unique)]
interface INapEnforcementClientConnection : IUnknown
{
   // Initialize the Connection
   // Set by the NapAgent at time of creation.
   //
   // Parameters:-
   // id: identifies the enforcement client
   //     requesting the connection
   HRESULT
   Initialize([in] EnforcementEntityId id);
   
   // Set by enforcement client.
   //
   // Parameters:-
   // maxSize: indicates the maximum size in bytes for the 
   //    SoH.
   //
   const UINT32 defaultProtocolMaxSize = 4000;
   const UINT32 minProtocolMaxSize = 300;
   const UINT32 maxProtocolMaxSize = 0xffff;
   typedef [range(minProtocolMaxSize, maxProtocolMaxSize)] UINT32 
      ProtocolMaxSize;
   HRESULT
   SetMaxSize([in] ProtocolMaxSize maxSize);
   HRESULT
   GetMaxSize([out] ProtocolMaxSize* maxSize) const;

   // Set by the NapAgent, used to differentiate
   // first-time responses from responses due to 
   // SoHRequests cached by the enforcers.
   //
   // Parameters:-
   // flags: Flag to determine if the SoHResponse
   //        is due to a cached SoHRequest
   HRESULT
   SetFlags([in] UINT8 flags);
   HRESULT
   GetFlags([out] UINT8* flags) const;

   // Must be set by the enforcement client as soon as the
   // connection is created. Used primarily for 
   // logging purposes. 
   //
   // Parameters:-
   // connectionId: uniquely identifies a connection.
   //
   HRESULT
   SetConnectionId([in] const ConnectionId* connectionId);
   HRESULT
   GetConnectionId([out] ConnectionId** connectionId) const;

   // Set by the NapAgent, based on the connection-id.
   // This is used to correlate requests and responses,
   // i.e. it uniquely describes an SoH-exchange.
   // It always contains the id of the most recent SoH
   // set on the connection object. When an SoH-Response
   // is received, the NapAgent first ensures that ids
   // match up; if not, then an error code is returned and
   // the enforcer must drop the packet. See 
   // ProcessSoHResponse() for more details.
   // 
   HRESULT
   GetCorrelationId([out] CorrelationId* correlationId) const;
   HRESULT
   GetStringCorrelationId(
      [out] StringCorrelationId** correlationId
      ) const;
   HRESULT
   SetCorrelationId([in] CorrelationId correlationId);

   // Set by NapAgent. Queried by enforcers to send on wire.
   // A zero-sized packet is invalid.
   //
   // Parameters::
   // sohRequest: Blob that is opaque to the enforcer.
   //
   HRESULT
   SetSoHRequest([in, unique] const NetworkSoHRequest* sohRequest);
   HRESULT
   GetSoHRequest([out] NetworkSoHRequest** sohRequest) const;

   // Set by the enforcement client on receiving a packet.
   // A zero-sized packet is invalid.
   //
   // Parameters:-
   // sohResponse: Blob that is opaque to the enforcer.
   //
   HRESULT
   SetSoHResponse(
      [in] const NetworkSoHResponse* sohResponse
      );
   HRESULT
   GetSoHResponse(
      [out] NetworkSoHResponse** sohResponse
      ) const;
      
   // Set by NapAgent after processing an SoHResponse. Must
   // not be set by the enforcer.
   //
   // Parameters:-
   // isolationState: indicates the connectivity state.
   //
   HRESULT
   SetIsolationInfo(
      [in] const IsolationInfo* isolationInfo
      );
   HRESULT
   GetIsolationInfo(
      [out] IsolationInfo** isolationInfo
      ) const;

   // Set and queried by NapAgent.
   //
   // Parameters:-
   // privateData: blob that only the NapAgent can interpret
   //
   HRESULT
   SetPrivateData([in] const PrivateData* privateData);
   HRESULT
   GetPrivateData([out] PrivateData** privateData) const;

   // Set and queried by enforcer.
   //
   // Parameters:-
   // privateData: blob that only the enforcer can interpret
   //
   HRESULT
   SetEnforcerPrivateData(
      [in] const PrivateData* privateData
      );
   HRESULT
   GetEnforcerPrivateData(
      [out] PrivateData** privateData
      ) const;
};

[object, 
uuid(BD244906-70DD-4690-BEEA-648653393500), 
pointer_default(unique)]
interface INapEnforcementClientConnection2 : INapEnforcementClientConnection
{
   // Set by NapAgent after processing an SoHResponse. Must
   // not be set by the enforcer.
   //
   // Parameters:-
   // isolationState: indicates the connectivity state.
   //
   HRESULT
   SetIsolationInfoEx(
      [in] const IsolationInfoEx* isolationInfo
      );
   HRESULT
   GetIsolationInfoEx(
      [out] IsolationInfoEx** isolationInfo
      ) const;

   HRESULT
   GetInstalledShvs(
      [out] SystemHealthEntityCount* count,
      [out, size_is(, *count)]
        SystemHealthEntityId** ids
      ) const;

   HRESULT
   SetInstalledShvs(
      [in] SystemHealthEntityCount count,
      [in, size_is(count)] 
        SystemHealthEntityId* ids
      );
   
};   

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_NapEnforcementClientBinding;")


#endif // NAPENFORCEMENTCLIENT_IDL

