AicsKnowledgeBase_client/msquic/include/msquic_winuser.h

377 lines
12 KiB
C
Raw Normal View History

2023-06-19 15:45:16 +08:00
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
Abstract:
This file contains the platform specific definitions for MsQuic structures
and error codes.
Environment:
Windows User mode
--*/
#pragma once
#ifndef _MSQUIC_WINUSER_
#define _MSQUIC_WINUSER_
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#pragma warning(push)
#pragma warning(disable:6553) // Annotation does not apply to value type.
#include <windows.h>
#pragma warning(pop)
#include <winsock2.h>
#include <ws2ipdef.h>
#pragma warning(push)
#pragma warning(disable:6385) // Invalid data: accessing [buffer-name], the readable size is size1 bytes but size2 bytes may be read
#pragma warning(disable:6101) // Returning uninitialized memory
#include <ws2tcpip.h>
#include <mstcpip.h>
#pragma warning(pop)
#include <stdint.h>
#define SUCCESS_HRESULT_FROM_WIN32(x) \
((HRESULT)(((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16)))
#ifndef ERROR_QUIC_HANDSHAKE_FAILURE
#define ERROR_QUIC_HANDSHAKE_FAILURE _HRESULT_TYPEDEF_(0x80410000L)
#endif
#ifndef ERROR_QUIC_VER_NEG_FAILURE
#define ERROR_QUIC_VER_NEG_FAILURE _HRESULT_TYPEDEF_(0x80410001L)
#endif
#ifndef ERROR_QUIC_USER_CANCELED
#define ERROR_QUIC_USER_CANCELED _HRESULT_TYPEDEF_(0x80410002L)
#endif
#ifndef ERROR_QUIC_INTERNAL_ERROR
#define ERROR_QUIC_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x80410003L)
#endif
#ifndef ERROR_QUIC_PROTOCOL_VIOLATION
#define ERROR_QUIC_PROTOCOL_VIOLATION _HRESULT_TYPEDEF_(0x80410004L)
#endif
#ifndef ERROR_QUIC_CONNECTION_IDLE
#define ERROR_QUIC_CONNECTION_IDLE _HRESULT_TYPEDEF_(0x80410005L)
#endif
#ifndef ERROR_QUIC_CONNECTION_TIMEOUT
#define ERROR_QUIC_CONNECTION_TIMEOUT _HRESULT_TYPEDEF_(0x80410006L)
#endif
#ifndef ERROR_QUIC_ALPN_NEG_FAILURE
#define ERROR_QUIC_ALPN_NEG_FAILURE _HRESULT_TYPEDEF_(0x80410007L)
#endif
#ifndef ERROR_QUIC_STREAM_LIMIT_REACHED
#define ERROR_QUIC_STREAM_LIMIT_REACHED _HRESULT_TYPEDEF_(0x80410008L)
#endif
#ifndef ERROR_QUIC_ALPN_IN_USE
#define ERROR_QUIC_ALPN_IN_USE _HRESULT_TYPEDEF_(0x80410009L)
#endif
#ifndef QUIC_TLS_ALERT_HRESULT_PREFIX
#define QUIC_TLS_ALERT_HRESULT_PREFIX _HRESULT_TYPEDEF_(0x80410100L)
#endif
#define QUIC_API __cdecl
#define QUIC_MAIN_EXPORT __cdecl
#define QUIC_STATUS HRESULT
#define QUIC_FAILED(X) FAILED(X)
#define QUIC_SUCCEEDED(X) SUCCEEDED(X)
#define QUIC_STATUS_SUCCESS S_OK // 0x0
#define QUIC_STATUS_PENDING SUCCESS_HRESULT_FROM_WIN32(ERROR_IO_PENDING) // 0x703e5
#define QUIC_STATUS_CONTINUE SUCCESS_HRESULT_FROM_WIN32(ERROR_CONTINUE) // 0x704de
#define QUIC_STATUS_OUT_OF_MEMORY E_OUTOFMEMORY // 0x8007000e
#define QUIC_STATUS_INVALID_PARAMETER E_INVALIDARG // 0x80070057
#define QUIC_STATUS_INVALID_STATE E_NOT_VALID_STATE // 0x8007139f
#define QUIC_STATUS_NOT_SUPPORTED E_NOINTERFACE // 0x80004002
#define QUIC_STATUS_NOT_FOUND HRESULT_FROM_WIN32(ERROR_NOT_FOUND) // 0x80070490
#define QUIC_STATUS_BUFFER_TOO_SMALL E_NOT_SUFFICIENT_BUFFER // 0x8007007a
#define QUIC_STATUS_HANDSHAKE_FAILURE ERROR_QUIC_HANDSHAKE_FAILURE // 0x80410000
#define QUIC_STATUS_ABORTED E_ABORT // 0x80004004
#define QUIC_STATUS_ADDRESS_IN_USE HRESULT_FROM_WIN32(WSAEADDRINUSE) // 0x80072740
#define QUIC_STATUS_INVALID_ADDRESS HRESULT_FROM_WIN32(WSAEADDRNOTAVAIL) // 0x80072741
#define QUIC_STATUS_CONNECTION_TIMEOUT ERROR_QUIC_CONNECTION_TIMEOUT // 0x80410006
#define QUIC_STATUS_CONNECTION_IDLE ERROR_QUIC_CONNECTION_IDLE // 0x80410005
#define QUIC_STATUS_UNREACHABLE HRESULT_FROM_WIN32(ERROR_HOST_UNREACHABLE) // 0x800704d0
#define QUIC_STATUS_INTERNAL_ERROR ERROR_QUIC_INTERNAL_ERROR // 0x80410003
#define QUIC_STATUS_CONNECTION_REFUSED HRESULT_FROM_WIN32(ERROR_CONNECTION_REFUSED) // 0x800704c9
#define QUIC_STATUS_PROTOCOL_ERROR ERROR_QUIC_PROTOCOL_VIOLATION // 0x80410004
#define QUIC_STATUS_VER_NEG_ERROR ERROR_QUIC_VER_NEG_FAILURE // 0x80410001
#define QUIC_STATUS_TLS_ERROR HRESULT_FROM_WIN32(WSA_SECURE_HOST_NOT_FOUND) // 0x80072b18
#define QUIC_STATUS_USER_CANCELED ERROR_QUIC_USER_CANCELED // 0x80410002
#define QUIC_STATUS_ALPN_NEG_FAILURE ERROR_QUIC_ALPN_NEG_FAILURE // 0x80410007
#define QUIC_STATUS_STREAM_LIMIT_REACHED ERROR_QUIC_STREAM_LIMIT_REACHED // 0x80410008
#define QUIC_STATUS_ALPN_IN_USE ERROR_QUIC_ALPN_IN_USE // 0x80410009
#define QUIC_STATUS_TLS_ALERT(Alert) (QUIC_TLS_ALERT_HRESULT_PREFIX | (0xff & Alert))
#define QUIC_STATUS_CLOSE_NOTIFY QUIC_STATUS_TLS_ALERT(0) // Close notify
#define QUIC_STATUS_BAD_CERTIFICATE QUIC_STATUS_TLS_ALERT(42) // Bad Certificate
#define QUIC_STATUS_UNSUPPORTED_CERTIFICATE QUIC_STATUS_TLS_ALERT(43) // Unsupported Certficiate
#define QUIC_STATUS_REVOKED_CERTIFICATE QUIC_STATUS_TLS_ALERT(44) // Revoked Certificate
#define QUIC_STATUS_EXPIRED_CERTIFICATE QUIC_STATUS_TLS_ALERT(45) // Expired Certificate
#define QUIC_STATUS_UNKNOWN_CERTIFICATE QUIC_STATUS_TLS_ALERT(46) // Unknown Certificate
#define QUIC_STATUS_REQUIRED_CERTIFICATE QUIC_STATUS_TLS_ALERT(116) // Required Certificate
#define QUIC_STATUS_CERT_EXPIRED CERT_E_EXPIRED
#define QUIC_STATUS_CERT_UNTRUSTED_ROOT CERT_E_UNTRUSTEDROOT
#define QUIC_STATUS_CERT_NO_CERT SEC_E_NO_CREDENTIALS
//
// Swaps byte orders between host and network endianness.
//
#ifdef htons
#define QuicNetByteSwapShort(x) htons(x)
#else
#define QuicNetByteSwapShort(x) ((uint16_t)((((x) & 0x00ff) << 8) | (((x) & 0xff00) >> 8)))
#endif
//
// IP Address Abstraction Helpers
//
typedef ADDRESS_FAMILY QUIC_ADDRESS_FAMILY;
typedef SOCKADDR_INET QUIC_ADDR;
#define QUIC_ADDR_V4_PORT_OFFSET FIELD_OFFSET(SOCKADDR_IN, sin_port)
#define QUIC_ADDR_V4_IP_OFFSET FIELD_OFFSET(SOCKADDR_IN, sin_addr)
#define QUIC_ADDR_V6_PORT_OFFSET FIELD_OFFSET(SOCKADDR_IN6, sin6_port)
#define QUIC_ADDR_V6_IP_OFFSET FIELD_OFFSET(SOCKADDR_IN6, sin6_addr)
#define QUIC_ADDRESS_FAMILY_UNSPEC AF_UNSPEC
#define QUIC_ADDRESS_FAMILY_INET AF_INET
#define QUIC_ADDRESS_FAMILY_INET6 AF_INET6
inline
BOOLEAN
QuicAddrIsValid(
_In_ const QUIC_ADDR* const Addr
)
{
return
Addr->si_family == QUIC_ADDRESS_FAMILY_UNSPEC ||
Addr->si_family == QUIC_ADDRESS_FAMILY_INET ||
Addr->si_family == QUIC_ADDRESS_FAMILY_INET6;
}
inline
BOOLEAN
QuicAddrCompareIp(
_In_ const QUIC_ADDR* const Addr1,
_In_ const QUIC_ADDR* const Addr2
)
{
if (Addr1->si_family == QUIC_ADDRESS_FAMILY_INET) {
return memcmp(&Addr1->Ipv4.sin_addr, &Addr2->Ipv4.sin_addr, sizeof(IN_ADDR)) == 0;
} else {
return memcmp(&Addr1->Ipv6.sin6_addr, &Addr2->Ipv6.sin6_addr, sizeof(IN6_ADDR)) == 0;
}
}
inline
BOOLEAN
QuicAddrCompare(
_In_ const QUIC_ADDR* const Addr1,
_In_ const QUIC_ADDR* const Addr2
)
{
if (Addr1->si_family != Addr2->si_family ||
Addr1->Ipv4.sin_port != Addr2->Ipv4.sin_port) {
return FALSE;
}
return QuicAddrCompareIp(Addr1, Addr2);
}
inline
BOOLEAN
QuicAddrIsWildCard(
_In_ const QUIC_ADDR* const Addr
)
{
if (Addr->si_family == QUIC_ADDRESS_FAMILY_UNSPEC) {
return TRUE;
} else if (Addr->si_family == QUIC_ADDRESS_FAMILY_INET) {
const IN_ADDR ZeroAddr = {0};
return memcmp(&Addr->Ipv4.sin_addr, &ZeroAddr, sizeof(IN_ADDR)) == 0;
} else {
const IN6_ADDR ZeroAddr = {0};
return memcmp(&Addr->Ipv6.sin6_addr, &ZeroAddr, sizeof(IN6_ADDR)) == 0;
}
}
inline
QUIC_ADDRESS_FAMILY
QuicAddrGetFamily(
_In_ const QUIC_ADDR* const Addr
)
{
return (QUIC_ADDRESS_FAMILY)Addr->si_family;
}
inline
void
QuicAddrSetFamily(
_Inout_ QUIC_ADDR* Addr,
_In_ QUIC_ADDRESS_FAMILY Family
)
{
Addr->si_family = (ADDRESS_FAMILY)Family;
}
inline
uint16_t // Returns in host byte order.
QuicAddrGetPort(
_In_ const QUIC_ADDR* const Addr
)
{
return QuicNetByteSwapShort(Addr->Ipv4.sin_port);
}
inline
void
QuicAddrSetPort(
_Out_ QUIC_ADDR* Addr,
_In_ uint16_t Port // Host byte order
)
{
Addr->Ipv4.sin_port = QuicNetByteSwapShort(Port);
}
inline
void
QuicAddrSetToLoopback(
_Inout_ QUIC_ADDR* Addr
)
{
if (Addr->si_family == QUIC_ADDRESS_FAMILY_INET) {
Addr->Ipv4.sin_addr.S_un.S_un_b.s_b1 = 127;
Addr->Ipv4.sin_addr.S_un.S_un_b.s_b4 = 1;
} else {
Addr->Ipv6.sin6_addr.u.Byte[15] = 1;
}
}
//
// Test only API to increment the IP address value.
//
inline
void
QuicAddrIncrement(
_Inout_ QUIC_ADDR* Addr
)
{
if (Addr->si_family == QUIC_ADDRESS_FAMILY_INET) {
Addr->Ipv4.sin_addr.S_un.S_un_b.s_b4++;
} else {
Addr->Ipv6.sin6_addr.u.Byte[15]++;
}
}
inline
uint32_t
QuicAddrHash(
_In_ const QUIC_ADDR* Addr
)
{
uint32_t Hash = 5387; // A random prime number.
#define UPDATE_HASH(byte) Hash = ((Hash << 5) - Hash) + (byte)
if (Addr->si_family == QUIC_ADDRESS_FAMILY_INET) {
UPDATE_HASH(Addr->Ipv4.sin_port & 0xFF);
UPDATE_HASH(Addr->Ipv4.sin_port >> 8);
for (uint8_t i = 0; i < sizeof(Addr->Ipv4.sin_addr); ++i) {
UPDATE_HASH(((uint8_t*)&Addr->Ipv4.sin_addr)[i]);
}
} else {
UPDATE_HASH(Addr->Ipv6.sin6_port & 0xFF);
UPDATE_HASH(Addr->Ipv6.sin6_port >> 8);
for (uint8_t i = 0; i < sizeof(Addr->Ipv6.sin6_addr); ++i) {
UPDATE_HASH(((uint8_t*)&Addr->Ipv6.sin6_addr)[i]);
}
}
return Hash;
}
#define QUIC_LOCALHOST_FOR_AF(Af) "localhost"
//
// Rtl String API's are not allowed in gamecore
//
#if WINAPI_FAMILY != WINAPI_FAMILY_GAMES
inline
_Success_(return != FALSE)
BOOLEAN
QuicAddrFromString(
_In_z_ const char* AddrStr,
_In_ uint16_t Port, // Host byte order
_Out_ QUIC_ADDR* Addr
)
{
if (RtlIpv4StringToAddressExA(AddrStr, FALSE, &Addr->Ipv4.sin_addr, &Addr->Ipv4.sin_port) == NO_ERROR) {
Addr->si_family = QUIC_ADDRESS_FAMILY_INET;
} else if (RtlIpv6StringToAddressExA(AddrStr, &Addr->Ipv6.sin6_addr, &Addr->Ipv6.sin6_scope_id, &Addr->Ipv6.sin6_port) == NO_ERROR) {
Addr->si_family = QUIC_ADDRESS_FAMILY_INET6;
} else {
return FALSE;
}
if (Addr->Ipv4.sin_port == 0) {
Addr->Ipv4.sin_port = QuicNetByteSwapShort(Port);
}
return TRUE;
}
//
// Represents an IP address and (optionally) port number as a string.
//
typedef struct QUIC_ADDR_STR {
char Address[64];
} QUIC_ADDR_STR;
inline
_Success_(return != FALSE)
BOOLEAN
QuicAddrToString(
_In_ const QUIC_ADDR* Addr,
_Out_ QUIC_ADDR_STR* AddrStr
)
{
LONG Status;
ULONG AddrStrLen = ARRAYSIZE(AddrStr->Address);
if (Addr->si_family == QUIC_ADDRESS_FAMILY_INET) {
Status =
RtlIpv4AddressToStringExA(
&Addr->Ipv4.sin_addr,
Addr->Ipv4.sin_port,
AddrStr->Address,
&AddrStrLen);
} else {
Status =
RtlIpv6AddressToStringExA(
&Addr->Ipv6.sin6_addr,
0,
Addr->Ipv6.sin6_port,
AddrStr->Address,
&AddrStrLen);
}
return Status == NO_ERROR;
}
#endif // WINAPI_FAMILY != WINAPI_FAMILY_GAMES
#endif // _MSQUIC_WINUSER_