////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation.
//
// SYNOPSIS
//
//    IDL source for NAP protocol helpers.
//
////////////////////////////////////////////////////////////

#ifndef NAPPROTOCOL_IDL
#define NAPPROTOCOL_IDL

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


// The following helper interfaces are used by SHAs and SHVs
// to construct and process SoH packets.
// 
// SoH packets are collections of TLVs. The TLVs are ordered
// such that certain TLVs (eg. system health ID TLV and 
// health class TLV) are separators between groups or 
// sub-groups of TLVs.
//
// Rules for TLVs inside an SoH-Request packet:
// 1). The system health ID TLV must be the first one.
// 
// Rules for TLVs inside an SoH-Response packet:
// 1). The system health ID TLV must be the first one.
// 2). A Compliance-Result-Code TLV (Res-TLV) or 
//     Failure-Category TLV (FC-TLV) must be present.
//     Any number of these TLVs may be used.  
//     If more than one Res-TLV is present, all of them
//     are merged to make a compliance decision.
//     If more than one FC-TLV is present, 
//     the first FC-TLV is used by the 
//     NAP Server to make a compliance decision.
// 3). At most one of Ipv4-Fixup-Servers may be present.
// 4). At most one of Ipv6-Fixup-Servers may be present.

[pointer_default(unique)]
interface INapSoHTypes
{
   // This defines TLV-type information.
   // 
   // The following attributes are consumed by the 
   // NAP system:
   //    System-Health-Id
   //    IPv4-Fixup-Servers
   //    IPv6-Fixup-Servers
   //    Compliance-Result-Codes
   //    Failure-Category
   // 
   // The rest of the types are meant 
   // purely as a prescriptive guidance for usage by SHAs 
   // and SHVs.
   // 
   typedef enum tagSoHAttributeType
   {
      sohAttributeTypeSystemHealthId = 2,
      sohAttributeTypeIpv4FixupServers = 3,
      sohAttributeTypeComplianceResultCodes = 4,
      sohAttributeTypeTimeOfLastUpdate = 5,
      sohAttributeTypeClientId = 6,
      sohAttributeTypeVendorSpecific = 7,
      sohAttributeTypeHealthClass = 8,
      sohAttributeTypeSoftwareVersion = 9,
      sohAttributeTypeProductName = 10,
      sohAttributeTypeHealthClassStatus = 11,
      sohAttributeTypeSoHGenerationTime = 12,
      sohAttributeTypeErrorCodes = 13,
      sohAttributeTypeFailureCategory = 14,
      sohAttributeTypeIpv6FixupServers = 15,
      sohAttributeTypeExtendedIsolationState = 16,
   } SoHAttributeType;


   // The health class TLV can take the following values.
   // 
   typedef enum tagHealthClassValue
   {
      healthClassFirewall = 0,
      healthClassPatchLevel = 1,
      healthClassAntiVirus = 2,
      healthClassCriticalUpdate = 3,
      healthClassReserved = 128
   } HealthClassValue;


   typedef [switch_type(SoHAttributeType)] 
   union tagSoHAttributeValue
   {
      [case(sohAttributeTypeSystemHealthId)]
         SystemHealthEntityId idVal;
   
      // The addresses must be in network byte order.
      [case(sohAttributeTypeIpv4FixupServers)]
         struct tagIpv4Addresses
         {
            [range(1, maxIpv4CountPerSoHAttribute)] 
               UINT16 count;
            [size_is(count)] Ipv4Address* addresses;
         } v4AddressesVal;

      [case(sohAttributeTypeIpv6FixupServers)]
         struct tagIpv6Addresses
         {
            [range(1, maxIpv6CountPerSoHAttribute)]
               UINT16 count;
            [size_is(count)] Ipv6Address* addresses;
         } v6AddressesVal;

      // The HRESULTs must be in host byte order
      [case(sohAttributeTypeComplianceResultCodes, 
            sohAttributeTypeErrorCodes)]
         ResultCodes codesVal;

      [case(sohAttributeTypeTimeOfLastUpdate, 
            sohAttributeTypeSoHGenerationTime)]
         FILETIME dateTimeVal;

      // Vendor-specific data must be in network byte order.
      [case(sohAttributeTypeVendorSpecific)]
         struct tagVendorSpecific
         {
            UINT32 vendorId;
            [range(0, maxSoHAttributeSize - 4)] 
               UINT16 size;
            [size_is(size)] BYTE* vendorSpecificData;
         } vendorSpecificVal;

      [case(sohAttributeTypeHealthClass, 
            sohAttributeTypeFailureCategory,
            sohAttributeTypeExtendedIsolationState)]
         UINT8 uint8Val;

      // The following attributes are octet string:
      //     sohAttributeTypeSoftwareVersion,
      //     sohAttributeTypeClientId,
      //     sohAttributeTypeProductName,
      //     sohAttributeTypeHealthClassStatus
      // For forward compatibility, all unrecognized 
      // attributes are returned as octet strings.
      // Data must be in network byte order.
      [default]
         struct tagOctetString
         {
            [range(0, maxSoHAttributeSize)] UINT16 size;
            [size_is(size)] BYTE* data;
         } octetStringVal;

   } SoHAttributeValue;
};


// This interface is used by SHAs to construct SoH-requests
// and by SHVs to construct SoH-responses.
// 
[object, 
uuid(35298344-96A6-45e7-9B6B-62ECC6E09920), 
pointer_default(unique)]
interface INapSoHConstructor : IUnknown
{
   // Initializes the protocol packet. Must be called 
   // exactly once. This establishes the owner and the type
   // of the packet.
   //   id: ID of the SHA or SHV that's constructing the 
   //       packet. This will be put into the SoH packet as 
   //       the first TLV.
   //   isRequest: true if the packet is meant to be an 
   //       SoH-Request, false for SoH-Response.
   HRESULT 
   Initialize(
      [in] SystemHealthEntityId id,
      [in] BOOL isRequest
      );


   // Adds a TLV to the end of the SoH buffer.
   // SystemHealthId TLV must not be added using this 
   // function.
   // Note: When appending an attribute which will be
   //          consumed by the Nap System,it 
   //          should not be encrypted or modified in
   //          any manner.  If the HealthEntity requires
   //          encryption/integrity checking (MACs) of
   //          private information, it should be
   //          included only in the VendorSpecific
   //          attribute.
   //
   HRESULT
   AppendAttribute(
      [in] SoHAttributeType type,
      [in, switch_is(type)] const SoHAttributeValue* value
      );


   // Retrieve the constructed SoH-Request or 
   // SoH-Response packet.
   // 
   HRESULT
   GetSoH(
      [out] SoH** soh
      );


   // Checks the validity of the packet. Return S_OK if the 
   // pkt is valid, NAP_E_INVALID_PACKET if the packet is 
   // invalid.
   //   isRequest: true if the packet is meant to be an 
   //       SoH-Request, false for SoH-Response.
   HRESULT
   Validate(
      [in] const SoH* soh,
      [in] BOOL isRequest
      );
};


// This interface is used by SHAs to process SoH-responses
// and by SHVs to process SoH-requests.
// 
// The attribute locations are 0-based.
// 
[object, 
uuid(FB2FA8B0-2CD5-457d-ABA8-4376F63EA1C0), 
pointer_default(unique)]
interface INapSoHProcessor : IUnknown
{
   // Initializes the protocol packet. Must be called 
   // exactly once.
   //   soh: the packet to be processed.
   //   isRequest: true if the packet is meant to be an 
   //       SoH-Request, false for SoH-Response.
   //   id: the ID retrieved from the SoH packet.
   //
   // This method returns NAP_E_INVALID_PACKET if the 
   // packet is invalid.
   //
   HRESULT 
   Initialize(
      [in] const SoH* soh,
      [in] BOOL isRequest,
      [out] SystemHealthEntityId* id
      );


   // Finds the location of the next attribute of type 
   // 'type' from the 'fromLocation' location.
   // This method returns ERROR_FILE_NOT_FOUND if not found.
   // 
   HRESULT
   FindNextAttribute(
      [in] UINT16 fromLocation,
      [in] SoHAttributeType type,
      [out] UINT16* attributeLocation
      );


   // Retrieves the attribute type and value, given the
   // attribute location.
   // 
   HRESULT
   GetAttribute(
      [in] UINT16 attributeLocation,
      [out] SoHAttributeType* type,
      [out, switch_is(*type)] SoHAttributeValue** value
      );


   // Retrieves the total number of attributes in the SoH.
   // 
   HRESULT
   GetNumberOfAttributes([out] UINT16* attributeCount);
};


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 CLSID_NapSoHConstructor;")
cpp_quote("EXTERN_C const CLSID CLSID_NapSoHProcessor;")

#endif // NAPPROTOCOL_IDL

