24 #include <freerdp/config.h>
30 #include <winpr/crt.h>
31 #include <winpr/stream.h>
33 #include <freerdp/freerdp.h>
34 #include <freerdp/utils/rdpdr_utils.h>
36 #include "rdpdr_main.h"
37 #include "rdpdr_capabilities.h"
39 #define RDPDR_CAPABILITY_HEADER_LENGTH 8
46 GENERAL_CAPABILITY_VERSION_02 };
48 const UINT32 ioCode1 = rdpdr->clientIOCode1 & rdpdr->serverIOCode1;
49 const UINT32 ioCode2 = rdpdr->clientIOCode2 & rdpdr->serverIOCode2;
51 if (rdpdr_write_capset_header(rdpdr->log, s, &header) != CHANNEL_RC_OK)
54 if (!Stream_EnsureRemainingCapacity(s, 36))
57 Stream_Write_UINT32(s, rdpdr->clientOsType);
58 Stream_Write_UINT32(s, rdpdr->clientOsVersion);
59 Stream_Write_UINT16(s, rdpdr->clientVersionMajor);
60 Stream_Write_UINT16(s, rdpdr->clientVersionMinor);
61 Stream_Write_UINT32(s, ioCode1);
62 Stream_Write_UINT32(s, ioCode2);
63 Stream_Write_UINT32(s, rdpdr->clientExtendedPDU);
64 Stream_Write_UINT32(s, rdpdr->clientExtraFlags1);
67 rdpdr->clientExtraFlags2);
69 s, rdpdr->clientSpecialTypeDeviceCap);
80 if (header->CapabilityLength != 36)
82 WLog_Print(rdpdr->log, WLOG_ERROR,
83 "CAP_GENERAL_TYPE::CapabilityLength expected 36, got %" PRIu32,
84 header->CapabilityLength);
85 return ERROR_INVALID_DATA;
87 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 36))
88 return ERROR_INVALID_DATA;
90 Stream_Read_UINT32(s, rdpdr->serverOsType);
91 Stream_Read_UINT32(s, rdpdr->serverOsVersion);
92 Stream_Read_UINT16(s, rdpdr->serverVersionMajor);
93 Stream_Read_UINT16(s, rdpdr->serverVersionMinor);
94 Stream_Read_UINT32(s, rdpdr->serverIOCode1);
96 s, rdpdr->serverIOCode2);
97 Stream_Read_UINT32(s, rdpdr->serverExtendedPDU);
98 Stream_Read_UINT32(s, rdpdr->serverExtraFlags1);
101 rdpdr->serverExtraFlags2);
103 s, rdpdr->serverSpecialTypeDeviceCap);
105 return CHANNEL_RC_OK;
113 PRINT_CAPABILITY_VERSION_01 };
114 return rdpdr_write_capset_header(rdpdr->log, s, &header) == CHANNEL_RC_OK;
121 WINPR_ASSERT(header);
122 Stream_Seek(s, header->CapabilityLength);
123 return CHANNEL_RC_OK;
131 PORT_CAPABILITY_VERSION_01 };
132 return rdpdr_write_capset_header(rdpdr->log, s, &header) == CHANNEL_RC_OK;
139 WINPR_ASSERT(header);
140 Stream_Seek(s, header->CapabilityLength);
141 return CHANNEL_RC_OK;
149 DRIVE_CAPABILITY_VERSION_02 };
150 return rdpdr_write_capset_header(rdpdr->log, s, &header) == CHANNEL_RC_OK;
157 WINPR_ASSERT(header);
158 Stream_Seek(s, header->CapabilityLength);
159 return CHANNEL_RC_OK;
167 SMARTCARD_CAPABILITY_VERSION_01 };
168 return rdpdr_write_capset_header(rdpdr->log, s, &header) == CHANNEL_RC_OK;
175 WINPR_ASSERT(header);
176 Stream_Seek(s, header->CapabilityLength);
177 return CHANNEL_RC_OK;
182 UINT status = CHANNEL_RC_OK;
183 UINT16 numCapabilities = 0;
186 return CHANNEL_RC_NULL_DATA;
188 WINPR_ASSERT(rdpdr->state == RDPDR_CHANNEL_STATE_SERVER_CAPS);
189 rdpdr_state_advance(rdpdr, RDPDR_CHANNEL_STATE_CLIENT_CAPS);
191 if (!Stream_CheckAndLogRequiredLengthWLog(rdpdr->log, s, 4))
192 return ERROR_INVALID_DATA;
194 Stream_Read_UINT16(s, numCapabilities);
197 memset(rdpdr->capabilities, 0,
sizeof(rdpdr->capabilities));
198 for (UINT16 i = 0; i < numCapabilities; i++)
201 UINT error = rdpdr_read_capset_header(rdpdr->log, s, &header);
202 if (error != CHANNEL_RC_OK)
205 switch (header.CapabilityType)
207 case CAP_GENERAL_TYPE:
208 rdpdr->capabilities[header.CapabilityType] = TRUE;
209 status = rdpdr_process_general_capset(rdpdr, s, &header);
212 case CAP_PRINTER_TYPE:
213 rdpdr->capabilities[header.CapabilityType] = TRUE;
214 status = rdpdr_process_printer_capset(rdpdr, s, &header);
218 rdpdr->capabilities[header.CapabilityType] = TRUE;
219 status = rdpdr_process_port_capset(rdpdr, s, &header);
223 rdpdr->capabilities[header.CapabilityType] = TRUE;
224 status = rdpdr_process_drive_capset(rdpdr, s, &header);
227 case CAP_SMARTCARD_TYPE:
228 rdpdr->capabilities[header.CapabilityType] = TRUE;
229 status = rdpdr_process_smartcard_capset(rdpdr, s, &header);
236 if (status != CHANNEL_RC_OK)
240 return CHANNEL_RC_OK;
248 UINT rdpdr_send_capability_response(
rdpdrPlugin* rdpdr)
251 WINPR_ASSERT(rdpdr->rdpcontext);
253 rdpSettings* settings = rdpdr->rdpcontext->settings;
254 WINPR_ASSERT(settings);
256 wStream* s = StreamPool_Take(rdpdr->pool, 256);
260 WLog_Print(rdpdr->log, WLOG_ERROR,
"Stream_New failed!");
261 return CHANNEL_RC_NO_MEMORY;
265 freerdp_device_collection_find_type(settings, RDPDR_DTYP_FILESYSTEM);
266 const RDPDR_DEVICE* cserial = freerdp_device_collection_find_type(settings, RDPDR_DTYP_SERIAL);
268 freerdp_device_collection_find_type(settings, RDPDR_DTYP_PARALLEL);
270 freerdp_device_collection_find_type(settings, RDPDR_DTYP_SMARTCARD);
271 const RDPDR_DEVICE* cprinter = freerdp_device_collection_find_type(settings, RDPDR_DTYP_PRINT);
274 const BOOL drives = cdrives && rdpdr->capabilities[CAP_DRIVE_TYPE];
275 const BOOL serial = cserial && rdpdr->capabilities[CAP_PORT_TYPE];
276 const BOOL parallel = cparallel && rdpdr->capabilities[CAP_PORT_TYPE];
277 const BOOL smart = csmart && rdpdr->capabilities[CAP_SMARTCARD_TYPE];
278 const BOOL printer = cprinter && rdpdr->capabilities[CAP_PRINTER_TYPE];
282 if (serial || parallel)
289 Stream_Write_UINT16(s, RDPDR_CTYP_CORE);
290 Stream_Write_UINT16(s, PAKID_CORE_CLIENT_CAPABILITY);
291 Stream_Write_UINT16(s, count);
292 Stream_Write_UINT16(s, 0);
294 if (!rdpdr_write_general_capset(rdpdr, s))
299 if (!rdpdr_write_printer_capset(rdpdr, s))
302 if (serial || parallel)
304 if (!rdpdr_write_port_capset(rdpdr, s))
309 if (!rdpdr_write_drive_capset(rdpdr, s))
314 if (!rdpdr_write_smartcard_capset(rdpdr, s))
317 return rdpdr_send(rdpdr, s);
321 return ERROR_OUTOFMEMORY;