/********************************************************************* * * Windows Remote Desktop Services * Graphics virtual channel interface definition * * Copyright (c) Microsoft Corporation. All rights reserved. * **********************************************************************/ cpp_quote("#include ") #pragma region Desktop Family cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)") import "unknwn.idl"; import "oaidl.idl"; cpp_quote("#if (NTDDI_VERSION >= NTDDI_WIN8)") // // ========================================================================= // // Interface: IWRdsGraphicsChannelEvents // // Implementation: Server Side // // Description: // Interface used for receiving notifications from graphics channel // objects. // // // ========================================================================= // const ULONG WRdsGraphicsChannels_Bandwidth_Unavailable = (ULONG)(-1); const ULONG WRdsGraphicsChannels_LossyChannelMaxMessageSize = 988; const ULONG WRdsGraphicsChannels_RTT_Unavailable = (ULONG)(-1); cpp_quote("EXTERN_C __declspec(selectany) const IID IID_IWRdsGraphicsChannelEvents = {0x67f2368c, 0xd674, 0x4fae, {0xa5, 0x66, 0xd2, 0x06, 0x28, 0xa6, 0x40, 0xd2}};") [ object, uuid(67f2368c-d674-4fae-66a5-d20628a640d2), pointer_default(unique) ] interface IWRdsGraphicsChannelEvents : IUnknown { // // Called whenever a full message from the server is received // The message is fully reassembled and has the exact size // as the Write() call on the server // HRESULT OnDataReceived( [in] ULONG cbSize, // size of data in bytes [in] BYTE *pBuffer // data buffer ); // // The channel is disconnected, all Write() calls will fail // no more incomming data is expected. // HRESULT OnClose(); // // Notifies channel callback implementing object of the channel being open. // After this callback data can flow in both directions. // // OpenResult - HRESULT of the channel creation, pChannel is non-null if this value is S_OK // pOpenContext - passed in OpenChannel // // HRESULT OnChannelOpened( [in] HRESULT OpenResult, [in] IUnknown* pOpenContext ); // // Notification that a Write performed on the IWRdsGraphicsChannel interface // has been sent to the lower layer and the buffer is safe for reuse. // // pWriteContext - the parameter passed to IWRdsGraphicsChannel::Write // bCancelled - TRUE if the connection was dropped // pBuffer/cbBuffer - the same parameters a they were specified in the "Write" // // HRESULT OnDataSent( [in] IUnknown *pWriteContext, [in] BOOL bCancelled, [in] BYTE *pBuffer, [in] ULONG cbBuffer ); // // Notifies the consumer about current network conditions. // // bandwidth -The current expected bandwidth in bytes/sec that the consumer can expect to send data at. // // 0xffffffff if bandwidth statistics are not available. // // RTT - The RTT of the link on which we are operating. // // 0xffffffff if latency statistics are not available // // dwCurrentSendByteIndex - the byte index of the last byte that was sent from this channel at this time. // begins at zero in increases for lifetime of connection, rounds back to zero // on overflow. // // // Comments: // The goal of this API is for all generic consumers to have estimate of bandwidth and queue depth to make encoding decisions. // // The API provides a mechanism for consumers to know their queue depth and drain rate, in order to estimate their ideal send time. // // The bandwidth estimates and queue depth are for this particular virtual channel consumer. Competing flows either at transport or // virtual circuit layer effect the bandwidth estimate. For eg. If another VC takes up n% of the available transport bandwidth, then the // consumer will receive (100-n)% of available link bandwidth as its bandwidth share. // // The API is not guarenteed to be called as the bandwidth estimates are not always available // and consumer cannot take dependency on being called with the API. // // Eg. of use - The graphics encoder is expected to derive an ideal send time for its next encoded frame based on how long it expects // the already queued data to go out on the network. (t0+ EncoderQueueSize / Bandwidth). The graphics encoder knows its queue // size based on the data that it has sent on the channel, and the last byte that got sent as part of this API callback. // (dwCurrentSentByteIndex) // // // HRESULT OnMetricsUpdate( [in] DWORD bandwidth, [in] DWORD RTT, [in] UINT64 lastSentByteIndex ); }; // // ========================================================================= // // Interface: IWRdsGraphicsChannel // // Implementation: Server Side // // Description: // Interface used by the graphics channel conumser for sending and // receiving data. // ========================================================================= // cpp_quote("EXTERN_C __declspec(selectany) const IID IID_IWRdsGraphicsChannel = {0x684b7a0b, 0xedff, 0x43ad, {0xa2, 0xd5, 0x4a, 0x8d, 0x53, 0x88, 0xf4, 0x01}};") [ object, uuid(684b7a0b-edff-43ad-d5a2-4a8d5388f401), pointer_default(unique) ] interface IWRdsGraphicsChannel : IUnknown { // // Method use to send data on the virtual channel. The interface implementation will take // ownership of the buffer. The buffer is returned to the interface consumer through the // OnDataSent callback. // // HRESULT Write( [in] ULONG cbSize, // Size of the buffer [in] BYTE *pBuffer, // Pointer to the payload [in] IUnknown *pContext // Consumer provider pointer. Implementer should return // this in the OnDataSent callaback. ); // // The consumer requests to close the channel // This will result in IRDPCoreVirtualChannelEvents::OnClose() call. // The implementer should complete all the sends requests indicating // that the channel was closed (see the bCancelled parameter in OnDataSent). // All I/O will cease. // HRESULT Close(); // // Used to bind the callback interface to the virtual channel // Essentially the user says - I am ready, i.e: binds server side // The channel is completly bound when OnChannelOpened is received // on the IRDPCoreVirtualChannelEvents. After OnChannelOpened data is // ready to flow in both directions // // pVirtualChannelCallback - passed in by caller to bind the callback to this VirtualChannel // pOpenContext - caller provided context passed back to caller in OnChannelOpened // // HRESULT Open( [in] IWRdsGraphicsChannelEvents *pChannelEvents, [in] IUnknown *pOpenContext ); }; typedef enum { WRdsGraphicsChannelType_GuaranteedDelivery = 0, WRdsGraphicsChannelType_BestEffortDelivery = 1 } WRdsGraphicsChannelType; // // ========================================================================= // // Interface: IWRdsGraphicsChannelManager // // Implementation: Server Side // // Description: // This interface is used by the RemoteFX graphics services API to // create the virtual channels necessary for remoting graphics data // // ========================================================================= // cpp_quote("EXTERN_C __declspec(selectany) const IID IID_IWRdsGraphicsChannelManager = {0x0fd57159, 0xe83e, 0x476a, {0xb9, 0xa8, 0x4a, 0x79, 0x76, 0xe7, 0x1e, 0x18}};") [ object, uuid(0fd57159-e83e-476a-a8b9-4a7976e71e18), pointer_default(unique) ] interface IWRdsGraphicsChannelManager : IUnknown { // // pszEndpointName - name of the channel // ppVirtualChannel - Channel object instance // // HRESULT CreateChannel( [in] const char *pszChannelName, [in] WRdsGraphicsChannelType channelType, [out, retval] IWRdsGraphicsChannel **ppVirtualChannel ); }; cpp_quote("#endif //(NTDDI_VERSION >= NTDDI_WIN8)") // // The following section describes some RDP protocol specific types. // These structs are used by downlevel code and it is not associated with // a specific Windows version so it is not guarded by NTDDI_VERSION macros // cpp_quote("#if defined(_WIN64)") cpp_quote("#define RFX_GFX_UNALIGNED __unaligned") cpp_quote("#elif defined(_ARM_)") cpp_quote("#define RFX_GFX_UNALIGNED __unaligned") cpp_quote("#else") cpp_quote("#define RFX_GFX_UNALIGNED") cpp_quote("#endif") // // This section contains the identifiers for the messages exchanged on // the desktop information channel. Messages with uMSGType values not specified // by this header should be ignored by the client implementation code. // cpp_quote("#define RFX_RDP_MSG_PREFIX 0x00") cpp_quote("#define RFX_GFX_MSG_PREFIX 0x30") cpp_quote("#define RFX_GFX_MSG_PREFIX_MASK 0x30") cpp_quote("#define RFX_GFX_MSG_MAKE_16BIT_CODE(B0, B1) ((B1) << 8 | (B0))") // RDP payload messages (prefix is 0x00) cpp_quote("#define RFX_GFX_MSG_TYPE_MOUSE_POINTER_SHAPE RFX_GFX_MSG_MAKE_16BIT_CODE(0x8B, 0x00)") cpp_quote("#define RFX_GFX_MSG_TYPE_MOUSE_POINTER_POSITION RFX_GFX_MSG_MAKE_16BIT_CODE(0x88, 0x00)") cpp_quote("#define RFX_GFX_MSG_TYPE_MOUSE_POINTER_CACHED RFX_GFX_MSG_MAKE_16BIT_CODE(0x8A, 0x00)") // Desktop config msg cpp_quote("#define RFX_GFX_MSG_TYPE_CLIENT_DESKTOP_INFO_REQUEST RFX_GFX_MSG_MAKE_16BIT_CODE(RFX_GFX_MSG_PREFIX, 0x1)") cpp_quote("#define RFX_GFX_MSG_TYPE_CLIENT_DESKTOP_INFO_RESPONSE RFX_GFX_MSG_MAKE_16BIT_CODE(RFX_GFX_MSG_PREFIX, 0x2)") cpp_quote("#define RFX_GFX_MSG_TYPE_DESKTOP_CONFIG_CHANGE_NOTIFY RFX_GFX_MSG_MAKE_16BIT_CODE(RFX_GFX_MSG_PREFIX, 0x3)") cpp_quote("#define RFX_GFX_MSG_TYPE_DESKTOP_CONFIG_CHANGE_CONFIRM RFX_GFX_MSG_MAKE_16BIT_CODE(RFX_GFX_MSG_PREFIX, 0x4)") cpp_quote("#define RFX_GFX_MSG_TYPE_DESKTOP_SIZE_CHANGE_NOTIFY RFX_GFX_MSG_MAKE_16BIT_CODE(RFX_GFX_MSG_PREFIX, 0x5)") cpp_quote("#define RFX_GFX_MSG_TYPE_DISCONNECT_NOTIFY RFX_GFX_MSG_MAKE_16BIT_CODE(RFX_GFX_MSG_PREFIX, 0x6)") cpp_quote("#define RFX_GFX_MSG_TYPE_DESKTOP_RESEND_REQUEST RFX_GFX_MSG_MAKE_16BIT_CODE(RFX_GFX_MSG_PREFIX, 0x7)") cpp_quote("#pragma pack(push, rfx_gfx_msg, 1)") // // Rect definition - used to describe coordinates in virtual desktop space // typedef struct tagRFX_GFX_RECT { INT32 left; INT32 top; INT32 right; INT32 bottom; } RFX_GFX_RECT; cpp_quote("typedef RFX_GFX_RECT RFX_GFX_UNALIGNED *PRFX_GFX_RECT;") // // Channel message header. Describes the message type and - optionally the size. // Since this is a message based protocol the size of the payload is not // always described by the header's cbSize but instead the size has to be // determined by decoding the message type. In those cases cbSize will // be set to 0. // typedef struct tagRFX_GFX_MSG_HEADER { UINT16 uMSGType; // One of the RFX_GFX_MSG_TYPE values UINT16 cbSize; // Optional - set to 0 for fixed size messages } RFX_GFX_MSG_HEADER; cpp_quote("typedef RFX_GFX_MSG_HEADER RFX_GFX_UNALIGNED *PRFX_GFX_MSG_HEADER;") // // Monitor info packet // typedef struct tagRFX_GFX_MONITOR_INFO { INT32 left; INT32 top; INT32 right; INT32 bottom; UINT32 physicalWidth; UINT32 physicalHeight; UINT32 orientation; BOOL primary; } RFX_GFX_MONITOR_INFO; cpp_quote("typedef RFX_GFX_MONITOR_INFO RFX_GFX_UNALIGNED *PRFX_GFX_MONITOR_INFO;") // // Message used by the server to query the monitor/desktop configuration // from the client. // typedef struct tagRFX_GFX_MSG_CLIENT_DESKTOP_INFO_REQUEST { RFX_GFX_MSG_HEADER channelHdr; } RFX_GFX_MSG_CLIENT_DESKTOP_INFO_REQUEST; cpp_quote("typedef RFX_GFX_MSG_CLIENT_DESKTOP_INFO_REQUEST RFX_GFX_UNALIGNED *PRFX_GFX_MSG_CLIENT_DESKTOP_INFO_REQUEST;") // // Reply in response to the RFX_GFX_MSG_CLIENT_DESKTOP_INFO_REQUEST. // The client must return at least one monitor. And at least one monitor // should have the primary flag set to TRUE. // The clientUniqueId represents the clientId as described by [MS-RDPBCGR] // (see clientDigProductId field in the TS_UD_CS_CORE data block). const int RFX_GFX_MAX_SUPPORTED_MONITORS = 16; const int RFX_CLIENT_ID_LENGTH = 32; typedef struct tagRFX_GFX_MSG_CLIENT_DESKTOP_INFO_RESPONSE { RFX_GFX_MSG_HEADER channelHdr; UINT32 reserved; // Reserved for future use - must be set to 0. UINT32 monitorCount; RFX_GFX_MONITOR_INFO MonitorData[RFX_GFX_MAX_SUPPORTED_MONITORS]; WCHAR clientUniqueId[RFX_CLIENT_ID_LENGTH]; } RFX_GFX_MSG_CLIENT_DESKTOP_INFO_RESPONSE; cpp_quote("typedef RFX_GFX_MSG_CLIENT_DESKTOP_INFO_RESPONSE RFX_GFX_UNALIGNED *PRFX_GFX_MSG_CLIENT_DESKTOP_INFO_RESPONSE;") // // Once the server receives the desktop info from the client it will try to // configure the session with the number of monitors requested by the client. // // However the session configuration might not match the client's request. // This message is used by the server to notify the client of what the // resulting desktop configuration. // // The client should reply with a RFX_GFX_MSG_DESKTOP_CONFIG_CHANGE_CONFIRM. // typedef struct tagRFX_GFX_MSG_DESKTOP_CONFIG_CHANGE_NOTIFY { RFX_GFX_MSG_HEADER channelHdr; ULONG ulWidth; ULONG ulHeight; ULONG ulBpp; ULONG Reserved; } RFX_GFX_MSG_DESKTOP_CONFIG_CHANGE_NOTIFY; cpp_quote("typedef RFX_GFX_MSG_DESKTOP_CONFIG_CHANGE_NOTIFY RFX_GFX_UNALIGNED *PRFX_GFX_MSG_DESKTOP_CONFIG_CHANGE_NOTIFY;") // // Sent by the client to inform the server that the new desktop configuration // was applied by the client successfuly. // typedef struct tagRFX_GFX_MSG_DESKTOP_CONFIG_CHANGE_CONFIRM { RFX_GFX_MSG_HEADER channelHdr; } RFX_GFX_MSG_DESKTOP_CONFIG_CHANGE_CONFIRM; cpp_quote("typedef RFX_GFX_MSG_DESKTOP_CONFIG_CHANGE_CONFIRM RFX_GFX_UNALIGNED *PRFX_GFX_MSG_DESKTOP_CONFIG_CHANGE_CONFIRM;") // // Notifies input components of desktop size changes. // Carries the same width/height as RFX_GFX_MSG_DESKTOP_CONFIG_CHANGE_NOTIFY // typedef struct tagRFX_GFX_MSG_DESKTOP_INPUT_RESET { RFX_GFX_MSG_HEADER channelHdr; UINT32 ulWidth; UINT32 ulHeight; } RFX_GFX_MSG_DESKTOP_INPUT_RESET; cpp_quote("typedef RFX_GFX_MSG_DESKTOP_INPUT_RESET RFX_GFX_UNALIGNED *PRFX_GFX_MSG_DESKTOP_INPUT_RESET;") // // Message used by the server to notify the client of an error that caused // the graphics stream to be stopped. // typedef struct tagRFX_GFX_MSG_DISCONNECT_NOTIFY { RFX_GFX_MSG_HEADER channelHdr; ULONG DisconnectReason; } RFX_GFX_MSG_DISCONNECT_NOTIFY; cpp_quote("typedef RFX_GFX_MSG_DISCONNECT_NOTIFY RFX_GFX_UNALIGNED *PRFX_GFX_MSG_DISCONNECT_NOTIFY;") // // Message used by the client to notify the server that a portion of the desktop // should be re-sent to the client. This can be used for instance in cases // the client encounters a temporary rendering error (like a DX device being lost). // typedef struct tagRFX_GFX_MSG_DESKTOP_RESEND_REQUEST { RFX_GFX_MSG_HEADER channelHdr; RFX_GFX_RECT RedrawRect; } RFX_GFX_MSG_DESKTOP_RESEND_REQUEST; cpp_quote("typedef RFX_GFX_MSG_DESKTOP_RESEND_REQUEST RFX_GFX_UNALIGNED *PRFX_GFX_MSG_DESKTOP_RESEND_REQUEST;") // // This packet is used to cary the payload of RDP format PDUs exchanged on the // desktop information channel. Such messages include mouse pointer information // as described in the protocol document [MS-RDPBCGR]. // typedef struct tagRFX_GFX_MSG_RDP_DATA { RFX_GFX_MSG_HEADER channelHdr; UINT8 rdpData[1]; } RFX_GFX_MSG_RDP_DATA; cpp_quote("typedef RFX_GFX_MSG_RDP_DATA RFX_GFX_UNALIGNED *PRFX_GFX_MSG_RDP_DATA;") cpp_quote("#pragma pack(pop, rfx_gfx_msg)") cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */") #pragma endregion