forked from microsoft/terminal
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDeviceComm.cpp
More file actions
152 lines (139 loc) · 6.71 KB
/
Copy pathDeviceComm.cpp
File metadata and controls
152 lines (139 loc) · 6.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "DeviceComm.h"
DeviceComm::DeviceComm(_In_ HANDLE Server) :
_Server(Server)
{
THROW_HR_IF(E_HANDLE, Server == INVALID_HANDLE_VALUE);
}
DeviceComm::~DeviceComm()
{
}
// 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 DeviceComm::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 seperately.)
// - pMessage - A structure to hold the message data retrieved from the driver.
// Return Value:
// - HRESULT S_OK or suitable error.
[[nodiscard]] HRESULT DeviceComm::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 seperately.)
// Return Value:
// - HRESULT S_OK or suitable error.
[[nodiscard]] HRESULT DeviceComm::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 DeviceComm::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 DeviceComm::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 DeviceComm::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 DeviceComm::_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;
}