void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIST_EVENT* cb_event) { int i; wStream* s; DEBUG_CLIPRDR("Sending Clipboard Format List"); if (cb_event->raw_format_data) { s = cliprdr_packet_new(CB_FORMAT_LIST, 0, cb_event->raw_format_data_size); stream_write(s, cb_event->raw_format_data, cb_event->raw_format_data_size); } else { wStream* body = stream_new(0); for (i = 0; i < cb_event->num_formats; i++) { const char* name; int name_length; switch (cb_event->formats[i]) { case CB_FORMAT_HTML: name = CFSTR_HTML; name_length = sizeof(CFSTR_HTML); break; case CB_FORMAT_PNG: name = CFSTR_PNG; name_length = sizeof(CFSTR_PNG); break; case CB_FORMAT_JPEG: name = CFSTR_JPEG; name_length = sizeof(CFSTR_JPEG); break; case CB_FORMAT_GIF: name = CFSTR_GIF; name_length = sizeof(CFSTR_GIF); break; default: name = "\0\0"; name_length = 2; break; } if (!cliprdr->use_long_format_names) name_length = 32; stream_extend(body, stream_get_size(body) + 4 + name_length); stream_write_UINT32(body, cb_event->formats[i]); stream_write(body, name, name_length); } s = cliprdr_packet_new(CB_FORMAT_LIST, 0, stream_get_size(body)); stream_write(s, stream_get_head(body), stream_get_size(body)); stream_free(body); } cliprdr_packet_send(cliprdr, s); }
void scard_device_control(SCARD_DEVICE* scard, IRP* irp) { uint32 output_len, input_len, ioctl_code; uint32 stream_len, result; uint32 pos, pad_len; uint32 irp_len; uint32 irp_result_pos, output_len_pos, result_pos; stream_read_uint32(irp->input, output_len); stream_read_uint32(irp->input, input_len); stream_read_uint32(irp->input, ioctl_code); stream_seek(irp->input, 20); /* padding */ // stream_seek(irp->input, 4); /* TODO: parse len, le, v1 */ // stream_seek(irp->input, 4); /* 0xcccccccc */ // stream_seek(irp->input, 4); /* rpce len */ /* [MS-RDPESC] 3.2.5.1 Sending Outgoing Messages */ stream_extend(irp->output, 2048); irp_result_pos = stream_get_pos(irp->output); stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ /* [MS-RPCE] 2.2.6.1 */ stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ stream_write_uint32(irp->output, 0xcccccccc); /* filler */ output_len_pos = stream_get_pos(irp->output); stream_seek(irp->output, 4); /* size */ stream_write_uint32(irp->output, 0x0); /* filler */ result_pos = stream_get_pos(irp->output); stream_seek(irp->output, 4); /* result */ /* body */ switch (ioctl_code) { case SCARD_IOCTL_ESTABLISH_CONTEXT: result = handle_EstablishContext(irp); break; case SCARD_IOCTL_IS_VALID_CONTEXT: result = handle_IsValidContext(irp); break; case SCARD_IOCTL_RELEASE_CONTEXT: result = handle_ReleaseContext(irp); break; case SCARD_IOCTL_LIST_READERS: result = handle_ListReaders(irp, 0); break; case SCARD_IOCTL_LIST_READERS + 4: result = handle_ListReaders(irp, 1); break; case SCARD_IOCTL_LIST_READER_GROUPS: case SCARD_IOCTL_LIST_READER_GROUPS + 4: /* typically not used unless list_readers fail */ result = SCARD_F_INTERNAL_ERROR; break; case SCARD_IOCTL_GET_STATUS_CHANGE: result = handle_GetStatusChange(irp, 0); break; case SCARD_IOCTL_GET_STATUS_CHANGE + 4: result = handle_GetStatusChange(irp, 1); break; case SCARD_IOCTL_CANCEL: result = handle_Cancel(irp); break; case SCARD_IOCTL_CONNECT: result = handle_Connect(irp, 0); break; case SCARD_IOCTL_CONNECT + 4: result = handle_Connect(irp, 1); break; case SCARD_IOCTL_RECONNECT: result = handle_Reconnect(irp); break; case SCARD_IOCTL_DISCONNECT: result = handle_Disconnect(irp); break; case SCARD_IOCTL_BEGIN_TRANSACTION: result = handle_BeginTransaction(irp); break; case SCARD_IOCTL_END_TRANSACTION: result = handle_EndTransaction(irp); break; case SCARD_IOCTL_STATE: result = handle_State(irp); break; case SCARD_IOCTL_STATUS: result = handle_Status(irp, 0); break; case SCARD_IOCTL_STATUS + 4: result = handle_Status(irp, 1); break; case SCARD_IOCTL_TRANSMIT: result = handle_Transmit(irp); break; case SCARD_IOCTL_CONTROL: result = handle_Control(irp); break; case SCARD_IOCTL_GETATTRIB: result = handle_GetAttrib(irp); break; case SCARD_IOCTL_ACCESS_STARTED_EVENT: result = handle_AccessStartedEvent(irp); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR: result = handle_LocateCardsByATR(irp, 0); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR + 4: result = handle_LocateCardsByATR(irp, 1); break; default: result = 0xc0000001; printf("scard unknown ioctl 0x%x\n", ioctl_code); break; } /* look for NTSTATUS errors */ if ((result & 0xc0000000) == 0xc0000000) return scard_error(scard, irp, result); /* per Ludovic Rousseau, map different usage of this particular * error code between pcsc-lite & windows */ if (result == 0x8010001F) result = 0x80100022; /* handle response packet */ pos = stream_get_pos(irp->output); stream_len = pos - irp_result_pos - 4; stream_set_pos(irp->output, output_len_pos); stream_write_uint32(irp->output, stream_len - 24); stream_set_pos(irp->output, result_pos); stream_write_uint32(irp->output, result); stream_set_pos(irp->output, pos); /* pad stream to 16 byte align */ pad_len = stream_len % 16; stream_write_zero(irp->output, pad_len); pos = stream_get_pos(irp->output); irp_len = stream_len + pad_len; stream_set_pos(irp->output, irp_result_pos); stream_write_uint32(irp->output, irp_len); stream_set_pos(irp->output, pos); #ifdef WITH_DEBUG_SCARD freerdp_hexdump(stream_get_data(irp->output), stream_get_length(irp->output)); #endif irp->IoStatus = 0; irp->Complete(irp); }