terminal/src/server/ApiMessage.h
Leonard Hecker 296037a0fa
Remove CONSOLE_API_MSG::UpdateUserBufferPointers hack (#10326)
## Summary of the Pull Request

This commit introduces a copy constructor/operator for
`_CONSOLE_API_MSG`. The change is not trivial as the struct contains a
union of unnamed structs that cannot be copied using regular language
features. As such a copy operator using `memcpy` was implemented.
Additionally all access specifiers were removed, as those allow a C++
compiler to reorder struct members. This would break message passing.
This commit is a good opportunity to prevent such miscompilations
proactively.

## Validation Steps Performed

* Command prompts of WSL2 fish-shell and pwsh still work ✔️

Closes #10076
2021-06-14 19:52:40 +00:00

95 lines
3.1 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- ApiMessage.h
Abstract:
- This file extends the published structure of an API message to provide encapsulation and helper methods
Author:
- Michael Niksa (miniksa) 12-Oct-2016
Revision History:
- Adapted from original items in util.cpp & conapi.h & csrutil.cpp
--*/
#pragma once
#include "ApiMessageState.h"
#include "IApiRoutines.h"
class ConsoleProcessHandle;
class ConsoleHandleData;
class IDeviceComm;
typedef struct _CONSOLE_API_MSG
{
_CONSOLE_API_MSG();
_CONSOLE_API_MSG(_CONSOLE_API_MSG&&) = delete;
_CONSOLE_API_MSG& operator=(_CONSOLE_API_MSG&&) = delete;
_CONSOLE_API_MSG(const _CONSOLE_API_MSG& other);
_CONSOLE_API_MSG& operator=(const _CONSOLE_API_MSG&);
ConsoleProcessHandle* GetProcessHandle() const;
ConsoleHandleData* GetObjectHandle() const;
[[nodiscard]] HRESULT ReadMessageInput(const ULONG cbOffset, _Out_writes_bytes_(cbSize) PVOID pvBuffer, const ULONG cbSize);
[[nodiscard]] HRESULT GetAugmentedOutputBuffer(const ULONG cbFactor,
_Outptr_result_bytebuffer_(*pcbSize) PVOID* ppvBuffer,
_Out_ PULONG pcbSize);
[[nodiscard]] HRESULT GetOutputBuffer(_Outptr_result_bytebuffer_(*pcbSize) void** const ppvBuffer, _Out_ ULONG* const pcbSize);
[[nodiscard]] HRESULT GetInputBuffer(_Outptr_result_bytebuffer_(*pcbSize) void** const ppvBuffer, _Out_ ULONG* const pcbSize);
[[nodiscard]] HRESULT ReleaseMessageBuffers();
void SetReplyStatus(const NTSTATUS Status);
void SetReplyInformation(const ULONG_PTR pInformation);
// DO NOT PUT ACCESS SPECIFIERS HERE.
// The tail end of this structure is overwritten with console driver packet.
// It's important that we have a deterministic, C-like field ordering
// as this ensures that the packet data fields are last.
// Putting access specifiers here ("private:") would break this.
CD_IO_COMPLETE Complete{};
CONSOLE_API_STATE State{};
IDeviceComm* _pDeviceComm{ nullptr };
IApiRoutines* _pApiRoutines{ nullptr };
boost::container::small_vector<BYTE, 128> _inputBuffer;
boost::container::small_vector<BYTE, 128> _outputBuffer;
// From here down is the actual packet data sent/received.
CD_IO_DESCRIPTOR Descriptor;
union
{
struct
{
CD_CREATE_OBJECT_INFORMATION CreateObject;
CONSOLE_CREATESCREENBUFFER_MSG CreateScreenBuffer;
};
struct
{
CONSOLE_MSG_HEADER msgHeader;
union
{
CONSOLE_MSG_BODY_L1 consoleMsgL1;
CONSOLE_MSG_BODY_L2 consoleMsgL2;
CONSOLE_MSG_BODY_L3 consoleMsgL3;
} u;
};
};
// End packet data
// DO NOT PUT MORE FIELDS DOWN HERE.
// The tail end of this structure will have a console driver packet
// copied over it and it will overwrite any fields declared here.
} CONSOLE_API_MSG, *PCONSOLE_API_MSG, * const PCCONSOLE_API_MSG;