3822d5b662
Contains: - Delegation Configurator that can lookup/edit/save configuration information to registry - Conhost can lookup the CLSID of a registered default - Conhost has the ability to handoff a starting visible-window interactive session to the registered default - Velocity key since this is a big deal and we want to be careful - IDL for the interface Related work items: MSFT-16458099 Retrieved from https://microsoft.visualstudio.com os.2020 OS official/rs_wdx_dxp_windev 0ca55027d8180fbbaa145f2fe7a15005856c0f7c
185 lines
7.9 KiB
C++
185 lines
7.9 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#include "precomp.h"
|
|
#include "ConDrvDeviceComm.h"
|
|
|
|
ConDrvDeviceComm::ConDrvDeviceComm(_In_ HANDLE Server) :
|
|
_Server(Server)
|
|
{
|
|
THROW_HR_IF(E_HANDLE, Server == INVALID_HANDLE_VALUE);
|
|
}
|
|
|
|
ConDrvDeviceComm::~ConDrvDeviceComm()
|
|
{
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Needs to be called once per server session and typically as the absolute first operation.
|
|
// - This sets up the driver with the input event that it will need to coordinate with when client
|
|
// applications attempt to read data and need to be blocked. (It will be the signal to unblock those clients.)
|
|
// Arguments:
|
|
// - pServerInfo - Structure containing information required to initialize driver state for this console connection.
|
|
// Return Value:
|
|
// - HRESULT S_OK or suitable error.
|
|
[[nodiscard]] HRESULT ConDrvDeviceComm::SetServerInformation(_In_ CD_IO_SERVER_INFORMATION* const pServerInfo) const
|
|
{
|
|
return _CallIoctl(IOCTL_CONDRV_SET_SERVER_INFORMATION,
|
|
pServerInfo,
|
|
sizeof(*pServerInfo),
|
|
nullptr,
|
|
0);
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Retrieves a packet message from the driver representing the next action/activity that should be performed.
|
|
// Arguments:
|
|
// - pCompletion - Optional completion structure from the previous activity (can be used in lieu of calling CompleteIo separately.)
|
|
// - pMessage - A structure to hold the message data retrieved from the driver.
|
|
// Return Value:
|
|
// - HRESULT S_OK or suitable error.
|
|
[[nodiscard]] HRESULT ConDrvDeviceComm::ReadIo(_In_opt_ PCONSOLE_API_MSG const pReplyMsg,
|
|
_Out_ CONSOLE_API_MSG* const pMessage) const
|
|
{
|
|
HRESULT hr = _CallIoctl(IOCTL_CONDRV_READ_IO,
|
|
pReplyMsg == nullptr ? nullptr : &pReplyMsg->Complete,
|
|
pReplyMsg == nullptr ? 0 : sizeof(pReplyMsg->Complete),
|
|
&pMessage->Descriptor,
|
|
sizeof(CONSOLE_API_MSG) - FIELD_OFFSET(CONSOLE_API_MSG, Descriptor));
|
|
|
|
if (hr == HRESULT_FROM_WIN32(ERROR_IO_PENDING))
|
|
{
|
|
WaitForSingleObjectEx(_Server.get(), 0, FALSE);
|
|
hr = S_OK; // TODO: MSFT: 9115192 - ??? This isn't really relevant anymore with a switch from NtDeviceIoControlFile to DeviceIoControl...
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Marks an action/activity as completed to the driver so control/responses can be returned to the client application.
|
|
// Arguments:
|
|
// - pCompletion - Completion structure from the previous activity (can be used in lieu of calling CompleteIo separately.)
|
|
// Return Value:
|
|
// - HRESULT S_OK or suitable error.
|
|
[[nodiscard]] HRESULT ConDrvDeviceComm::CompleteIo(_In_ CD_IO_COMPLETE* const pCompletion) const
|
|
{
|
|
return _CallIoctl(IOCTL_CONDRV_COMPLETE_IO,
|
|
pCompletion,
|
|
sizeof(*pCompletion),
|
|
nullptr,
|
|
0);
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Used to retrieve any buffered input data related to an action/activity message.
|
|
// Arguments:
|
|
// - pIoOperation - Structure containing the identifier matching the action/activity message and containing a suitable buffer space
|
|
// to hold retrieved buffered input data from the client application.
|
|
// Return Value:
|
|
// - HRESULT S_OK or suitable error.
|
|
[[nodiscard]] HRESULT ConDrvDeviceComm::ReadInput(_In_ CD_IO_OPERATION* const pIoOperation) const
|
|
{
|
|
return _CallIoctl(IOCTL_CONDRV_READ_INPUT,
|
|
pIoOperation,
|
|
sizeof(*pIoOperation),
|
|
nullptr,
|
|
0);
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Used to return any buffered output data related to an action/activity message.
|
|
// Arguments:
|
|
// - pIoOperation - Structure containing the identifier matching the action/activity message and containing a suitable buffer space
|
|
// to hold buffered output data to be sent to the client application.
|
|
// Return Value:
|
|
// - HRESULT S_OK or suitable error.
|
|
[[nodiscard]] HRESULT ConDrvDeviceComm::WriteOutput(_In_ CD_IO_OPERATION* const pIoOperation) const
|
|
{
|
|
return _CallIoctl(IOCTL_CONDRV_WRITE_OUTPUT,
|
|
pIoOperation,
|
|
sizeof(*pIoOperation),
|
|
nullptr,
|
|
0);
|
|
}
|
|
|
|
// Routine Description:
|
|
// - To be called when the console instantiates UI to permit low-level UIAccess patterns to be used for retrieval of
|
|
// accessibility data from the console session.
|
|
// Arguments:
|
|
// - <none>
|
|
// Return Value:
|
|
// - HRESULT S_OK or suitable error.
|
|
[[nodiscard]] HRESULT ConDrvDeviceComm::AllowUIAccess() const
|
|
{
|
|
return _CallIoctl(IOCTL_CONDRV_ALLOW_VIA_UIACCESS,
|
|
nullptr,
|
|
0,
|
|
nullptr,
|
|
0);
|
|
}
|
|
|
|
// Routine Description:
|
|
// - For internal use. This function will send the appropriate control code verb and buffers to the driver and return a result.
|
|
// - Usage of the optional buffers depends on which verb is sent and is specific to the particular driver and its protocol.
|
|
// Arguments:
|
|
// - dwIoControlCode - The action code to send to the driver
|
|
// - pInBuffer - An optional buffer to send as input with the verb. Usage depends on the control code.
|
|
// - cbInBufferSize - The length in bytes of the optional input buffer.
|
|
// - pOutBuffer - An optional buffer to send as output with the verb. Usage depends on the control code.
|
|
// - cbOutBufferSize - The length in bytes of the optional output buffer.
|
|
// Return Value:
|
|
// - HRESULT S_OK or suitable error.
|
|
[[nodiscard]] HRESULT ConDrvDeviceComm::_CallIoctl(_In_ DWORD dwIoControlCode,
|
|
_In_reads_bytes_opt_(cbInBufferSize) PVOID pInBuffer,
|
|
_In_ DWORD cbInBufferSize,
|
|
_Out_writes_bytes_opt_(cbOutBufferSize) PVOID pOutBuffer,
|
|
_In_ DWORD cbOutBufferSize) const
|
|
{
|
|
// See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363216(v=vs.85).aspx
|
|
// Written is unused but cannot be nullptr because we aren't using overlapped.
|
|
DWORD cbWritten = 0;
|
|
RETURN_IF_WIN32_BOOL_FALSE(DeviceIoControl(_Server.get(),
|
|
dwIoControlCode,
|
|
pInBuffer,
|
|
cbInBufferSize,
|
|
pOutBuffer,
|
|
cbOutBufferSize,
|
|
&cbWritten,
|
|
nullptr));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Implements IDeviceComm handle exchange for ConDrv.
|
|
// - "Translates" a pointer to an object into a handle value
|
|
// that the driver can use to identify objects in a console
|
|
// session.
|
|
// - The opposite of GetHandle
|
|
[[nodiscard]] ULONG_PTR ConDrvDeviceComm::PutHandle(const void* handle)
|
|
{
|
|
// ConDrv will pass back whatever large integer we send it, as an opaque data blob
|
|
// We'll use that to smuggle the actual pointer value to the handle.
|
|
return reinterpret_cast<ULONG_PTR>(handle);
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Implements IDeviceComm handle exchange for ConDrv.
|
|
// - "Translates" an object handle from ConDrv into
|
|
// a pointer to an object
|
|
// - The opposite of PutHandle
|
|
[[nodiscard]] void* ConDrvDeviceComm::GetHandle(ULONG_PTR handleId) const
|
|
{
|
|
return reinterpret_cast<void*>(handleId);
|
|
}
|
|
|
|
// Routine Description:
|
|
// - Provides acccess to the raw server handle so it can be used to hand off
|
|
// the session to another console host server.
|
|
[[nodiscard]] HRESULT ConDrvDeviceComm::GetServerHandle(_Out_ HANDLE* pHandle) const
|
|
{
|
|
*pHandle = _Server.get();
|
|
return S_OK;
|
|
}
|