24#include <freerdp/config.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  const BOOL gotV1 = header->Version == GENERAL_CAPABILITY_VERSION_01;
 
   81  const size_t expect = gotV1 ? 32 : 36;
 
   82  if (header->CapabilityLength != expect)
 
   84    WLog_Print(
rdpdr->log, WLOG_ERROR,
 
   85               "CAP_GENERAL_TYPE::CapabilityLength expected %" PRIuz 
", got %" PRIu32, expect,
 
   86               header->CapabilityLength);
 
   87    return ERROR_INVALID_DATA;
 
   89  if (!Stream_CheckAndLogRequiredLengthWLog(
rdpdr->log, s, expect))
 
   90    return ERROR_INVALID_DATA;
 
   92  rdpdr->serverOsType = Stream_Get_UINT32(s);    
 
   93  rdpdr->serverOsVersion = Stream_Get_UINT32(s); 
 
   94  rdpdr->serverVersionMajor = Stream_Get_UINT16(s); 
 
   95  rdpdr->serverVersionMinor = Stream_Get_UINT16(s); 
 
   96  rdpdr->serverIOCode1 = Stream_Get_UINT32(s);      
 
   97  rdpdr->serverIOCode2 =
 
   99  rdpdr->serverExtendedPDU = Stream_Get_UINT32(s); 
 
  100  rdpdr->serverExtraFlags1 = Stream_Get_UINT32(s); 
 
  101  rdpdr->serverExtraFlags2 =
 
  102      Stream_Get_UINT32(s); 
 
  104    rdpdr->serverSpecialTypeDeviceCap = 0;
 
  106    rdpdr->serverSpecialTypeDeviceCap = Stream_Get_UINT32(
 
  109  return CHANNEL_RC_OK;
 
  117                                         PRINT_CAPABILITY_VERSION_01 };
 
  118  return rdpdr_write_capset_header(
rdpdr->log, s, &header) == CHANNEL_RC_OK;
 
  125  WINPR_ASSERT(header);
 
  126  Stream_Seek(s, header->CapabilityLength);
 
  127  return CHANNEL_RC_OK;
 
  135                                         PORT_CAPABILITY_VERSION_01 };
 
  136  return rdpdr_write_capset_header(
rdpdr->log, s, &header) == CHANNEL_RC_OK;
 
  143  WINPR_ASSERT(header);
 
  144  Stream_Seek(s, header->CapabilityLength);
 
  145  return CHANNEL_RC_OK;
 
  153                                         DRIVE_CAPABILITY_VERSION_02 };
 
  154  return rdpdr_write_capset_header(
rdpdr->log, s, &header) == CHANNEL_RC_OK;
 
  161  WINPR_ASSERT(header);
 
  162  Stream_Seek(s, header->CapabilityLength);
 
  163  return CHANNEL_RC_OK;
 
  171                                         SMARTCARD_CAPABILITY_VERSION_01 };
 
  172  return rdpdr_write_capset_header(
rdpdr->log, s, &header) == CHANNEL_RC_OK;
 
  179  WINPR_ASSERT(header);
 
  180  Stream_Seek(s, header->CapabilityLength);
 
  181  return CHANNEL_RC_OK;
 
  186  UINT status = CHANNEL_RC_OK;
 
  187  UINT16 numCapabilities = 0;
 
  190    return CHANNEL_RC_NULL_DATA;
 
  192  rdpdr_state_advance(
rdpdr, RDPDR_CHANNEL_STATE_CLIENT_CAPS);
 
  194  if (!Stream_CheckAndLogRequiredLengthWLog(
rdpdr->log, s, 4))
 
  195    return ERROR_INVALID_DATA;
 
  197  Stream_Read_UINT16(s, numCapabilities);
 
  200  memset(
rdpdr->capabilities, 0, 
sizeof(
rdpdr->capabilities));
 
  201  for (UINT16 i = 0; i < numCapabilities; i++)
 
  204    UINT error = rdpdr_read_capset_header(
rdpdr->log, s, &header);
 
  205    if (error != CHANNEL_RC_OK)
 
  208    switch (header.CapabilityType)
 
  210      case CAP_GENERAL_TYPE:
 
  211        rdpdr->capabilities[header.CapabilityType] = TRUE;
 
  212        status = rdpdr_process_general_capset(
rdpdr, s, &header);
 
  215      case CAP_PRINTER_TYPE:
 
  216        rdpdr->capabilities[header.CapabilityType] = TRUE;
 
  217        status = rdpdr_process_printer_capset(
rdpdr, s, &header);
 
  221        rdpdr->capabilities[header.CapabilityType] = TRUE;
 
  222        status = rdpdr_process_port_capset(
rdpdr, s, &header);
 
  226        rdpdr->capabilities[header.CapabilityType] = TRUE;
 
  227        status = rdpdr_process_drive_capset(
rdpdr, s, &header);
 
  230      case CAP_SMARTCARD_TYPE:
 
  231        rdpdr->capabilities[header.CapabilityType] = TRUE;
 
  232        status = rdpdr_process_smartcard_capset(
rdpdr, s, &header);
 
  239    if (status != CHANNEL_RC_OK)
 
  243  return CHANNEL_RC_OK;
 
  254  WINPR_ASSERT(
rdpdr->rdpcontext);
 
  256  rdpSettings* settings = 
rdpdr->rdpcontext->settings;
 
  257  WINPR_ASSERT(settings);
 
  263    WLog_Print(
rdpdr->log, WLOG_ERROR, 
"Stream_New failed!");
 
  264    return CHANNEL_RC_NO_MEMORY;
 
  268      freerdp_device_collection_find_type(settings, RDPDR_DTYP_FILESYSTEM);
 
  269  const RDPDR_DEVICE* cserial = freerdp_device_collection_find_type(settings, RDPDR_DTYP_SERIAL);
 
  271      freerdp_device_collection_find_type(settings, RDPDR_DTYP_PARALLEL);
 
  273      freerdp_device_collection_find_type(settings, RDPDR_DTYP_SMARTCARD);
 
  274  const RDPDR_DEVICE* cprinter = freerdp_device_collection_find_type(settings, RDPDR_DTYP_PRINT);
 
  277  const BOOL drives = cdrives && 
rdpdr->capabilities[CAP_DRIVE_TYPE];
 
  278  const BOOL serial = cserial && 
rdpdr->capabilities[CAP_PORT_TYPE];
 
  279  const BOOL parallel = cparallel && 
rdpdr->capabilities[CAP_PORT_TYPE];
 
  280  const BOOL smart = csmart && 
rdpdr->capabilities[CAP_SMARTCARD_TYPE];
 
  281  const BOOL printer = cprinter && 
rdpdr->capabilities[CAP_PRINTER_TYPE];
 
  285  if (serial || parallel)
 
  292  Stream_Write_UINT16(s, RDPDR_CTYP_CORE);
 
  293  Stream_Write_UINT16(s, PAKID_CORE_CLIENT_CAPABILITY);
 
  294  Stream_Write_UINT16(s, count); 
 
  295  Stream_Write_UINT16(s, 0); 
 
  297  if (!rdpdr_write_general_capset(
rdpdr, s))
 
  302    if (!rdpdr_write_printer_capset(
rdpdr, s))
 
  305  if (serial || parallel)
 
  307    if (!rdpdr_write_port_capset(
rdpdr, s))
 
  312    if (!rdpdr_write_drive_capset(
rdpdr, s))
 
  317    if (!rdpdr_write_smartcard_capset(
rdpdr, s))
 
  320  return rdpdr_send(
rdpdr, s);
 
  324  return ERROR_OUTOFMEMORY;