void rts_flow_control_ack_command_read(rdpRpc* rpc, STREAM* s) { /* Ack (24 bytes) */ stream_seek_UINT32(s); /* BytesReceived (4 bytes) */ stream_seek_UINT32(s); /* AvailableWindow (4 bytes) */ stream_seek(s, 16); /* ChannelCookie (16 bytes) */ }
static UINT32 handle_EstablishContext(IRP* irp) { UINT32 len; UINT32 status; UINT32 scope; SCARDCONTEXT hContext = -1; stream_seek(irp->input, 8); stream_read_UINT32(irp->input, len); if (len != 8) return SCARD_F_INTERNAL_ERROR; stream_seek_UINT32(irp->input); stream_read_UINT32(irp->input, scope); status = SCardEstablishContext(scope, NULL, NULL, &hContext); stream_write_UINT32(irp->output, 4); // cbContext stream_write_UINT32(irp->output, -1); // ReferentID stream_write_UINT32(irp->output, 4); stream_write_UINT32(irp->output, hContext); /* TODO: store hContext in allowed context list */ smartcard_output_alignment(irp, 8); return SCARD_S_SUCCESS; }
static BOOL rdpsnd_server_recv_formats(rdpsnd_server* rdpsnd, STREAM* s) { int i; if (stream_get_left(s) < 20) return FALSE; stream_seek_UINT32(s); /* dwFlags */ stream_seek_UINT32(s); /* dwVolume */ stream_seek_UINT32(s); /* dwPitch */ stream_seek_UINT16(s); /* wDGramPort */ stream_read_UINT16(s, rdpsnd->context.num_client_formats); /* wNumberOfFormats */ stream_seek_BYTE(s); /* cLastBlockConfirmed */ stream_seek_UINT16(s); /* wVersion */ stream_seek_BYTE(s); /* bPad */ if (rdpsnd->context.num_client_formats > 0) { rdpsnd->context.client_formats = (rdpsndFormat*) malloc(rdpsnd->context.num_client_formats * sizeof(rdpsndFormat)); ZeroMemory(rdpsnd->context.client_formats, sizeof(rdpsndFormat)); for (i = 0; i < rdpsnd->context.num_client_formats; i++) { if (stream_get_left(s) < 18) { free(rdpsnd->context.client_formats); rdpsnd->context.client_formats = NULL; return FALSE; } stream_read_UINT16(s, rdpsnd->context.client_formats[i].wFormatTag); stream_read_UINT16(s, rdpsnd->context.client_formats[i].nChannels); stream_read_UINT32(s, rdpsnd->context.client_formats[i].nSamplesPerSec); stream_seek_UINT32(s); /* nAvgBytesPerSec */ stream_read_UINT16(s, rdpsnd->context.client_formats[i].nBlockAlign); stream_read_UINT16(s, rdpsnd->context.client_formats[i].wBitsPerSample); stream_read_UINT16(s, rdpsnd->context.client_formats[i].cbSize); if (rdpsnd->context.client_formats[i].cbSize > 0) { stream_seek(s, rdpsnd->context.client_formats[i].cbSize); } } } return TRUE; }
static BOOL audin_server_recv_formats(audin_server* audin, STREAM* s, UINT32 length) { int i; if (length < 8) return FALSE; stream_read_UINT32(s, audin->context.num_client_formats); /* NumFormats (4 bytes) */ stream_seek_UINT32(s); /* cbSizeFormatsPacket (4 bytes) */ length -= 8; if (audin->context.num_client_formats <= 0) return FALSE; audin->context.client_formats = malloc(audin->context.num_client_formats * sizeof(AUDIO_FORMAT)); ZeroMemory(audin->context.client_formats, audin->context.num_client_formats * sizeof(AUDIO_FORMAT)); for (i = 0; i < audin->context.num_client_formats; i++) { if (length < 18) { free(audin->context.client_formats); audin->context.client_formats = NULL; return FALSE; } stream_read_UINT16(s, audin->context.client_formats[i].wFormatTag); stream_read_UINT16(s, audin->context.client_formats[i].nChannels); stream_read_UINT32(s, audin->context.client_formats[i].nSamplesPerSec); stream_seek_UINT32(s); /* nAvgBytesPerSec */ stream_read_UINT16(s, audin->context.client_formats[i].nBlockAlign); stream_read_UINT16(s, audin->context.client_formats[i].wBitsPerSample); stream_read_UINT16(s, audin->context.client_formats[i].cbSize); if (audin->context.client_formats[i].cbSize > 0) { stream_seek(s, audin->context.client_formats[i].cbSize); } } IFCALL(audin->context.Opening, &audin->context); return TRUE; }
BOOL rdp_recv_control_pdu(STREAM* s, UINT16* action) { if (stream_get_left(s) < 8) return FALSE; stream_read_UINT16(s, *action); /* action (2 bytes) */ stream_seek_UINT16(s); /* grantId (2 bytes) */ stream_seek_UINT32(s); /* controlId (4 bytes) */ return TRUE; }
static void rfx_compose_message_tile(RFX_CONTEXT* context, STREAM* s, BYTE* tile_data, int tile_width, int tile_height, int rowstride, const UINT32* quantVals, int quantIdxY, int quantIdxCb, int quantIdxCr, int xIdx, int yIdx) { int YLen = 0; int CbLen = 0; int CrLen = 0; int start_pos, end_pos; stream_check_size(s, 19); start_pos = stream_get_pos(s); stream_write_UINT16(s, CBT_TILE); /* BlockT.blockType */ stream_seek_UINT32(s); /* set BlockT.blockLen later */ stream_write_BYTE(s, quantIdxY); stream_write_BYTE(s, quantIdxCb); stream_write_BYTE(s, quantIdxCr); stream_write_UINT16(s, xIdx); stream_write_UINT16(s, yIdx); stream_seek(s, 6); /* YLen, CbLen, CrLen */ rfx_encode_rgb(context, tile_data, tile_width, tile_height, rowstride, quantVals + quantIdxY * 10, quantVals + quantIdxCb * 10, quantVals + quantIdxCr * 10, s, &YLen, &CbLen, &CrLen); DEBUG_RFX("xIdx=%d yIdx=%d width=%d height=%d YLen=%d CbLen=%d CrLen=%d", xIdx, yIdx, tile_width, tile_height, YLen, CbLen, CrLen); end_pos = stream_get_pos(s); stream_set_pos(s, start_pos + 2); stream_write_UINT32(s, 19 + YLen + CbLen + CrLen); /* BlockT.blockLen */ stream_set_pos(s, start_pos + 13); stream_write_UINT16(s, YLen); stream_write_UINT16(s, CbLen); stream_write_UINT16(s, CrLen); stream_set_pos(s, end_pos); }
IRP* irp_new(DEVMAN* devman, STREAM* data_in) { IRP* irp; UINT32 DeviceId; DEVICE* device; stream_read_UINT32(data_in, DeviceId); device = devman_get_device_by_id(devman, DeviceId); if (device == NULL) { DEBUG_WARN("unknown DeviceId %d", DeviceId); return NULL; } irp = (IRP*) _aligned_malloc(sizeof(IRP), MEMORY_ALLOCATION_ALIGNMENT); ZeroMemory(irp, sizeof(IRP)); irp->device = device; irp->devman = devman; stream_read_UINT32(data_in, irp->FileId); stream_read_UINT32(data_in, irp->CompletionId); stream_read_UINT32(data_in, irp->MajorFunction); stream_read_UINT32(data_in, irp->MinorFunction); irp->input = data_in; irp->output = stream_new(256); stream_write_UINT16(irp->output, RDPDR_CTYP_CORE); stream_write_UINT16(irp->output, PAKID_CORE_DEVICE_IOCOMPLETION); stream_write_UINT32(irp->output, DeviceId); stream_write_UINT32(irp->output, irp->CompletionId); stream_seek_UINT32(irp->output); /* IoStatus */ irp->Complete = irp_complete; irp->Discard = irp_free; DEBUG_SVC("DeviceId %d FileId %d CompletionId %d MajorFunction 0x%X MinorFunction 0x%x", irp->device->id, irp->FileId, irp->CompletionId, irp->MajorFunction, irp->MinorFunction); return irp; }
void rts_destination_command_read(rdpRpc* rpc, STREAM* s) { stream_seek_UINT32(s); /* Destination (4 bytes) */ }
static void rfx_compose_message_tileset(RFX_CONTEXT* context, STREAM* s, BYTE* image_data, int width, int height, int rowstride) { int i; int size; int start_pos, end_pos; int numQuants; const UINT32* quantVals; const UINT32* quantValsPtr; int quantIdxY; int quantIdxCb; int quantIdxCr; int numTiles; int numTilesX; int numTilesY; int xIdx; int yIdx; int tilesDataSize; if (context->num_quants == 0) { numQuants = 1; quantVals = rfx_default_quantization_values; quantIdxY = 0; quantIdxCb = 0; quantIdxCr = 0; } else { numQuants = context->num_quants; quantVals = context->quants; quantIdxY = context->quant_idx_y; quantIdxCb = context->quant_idx_cb; quantIdxCr = context->quant_idx_cr; } numTilesX = (width + 63) / 64; numTilesY = (height + 63) / 64; numTiles = numTilesX * numTilesY; size = 22 + numQuants * 5; stream_check_size(s, size); start_pos = stream_get_pos(s); stream_write_UINT16(s, WBT_EXTENSION); /* CodecChannelT.blockType */ stream_seek_UINT32(s); /* set CodecChannelT.blockLen later */ stream_write_BYTE(s, 1); /* CodecChannelT.codecId */ stream_write_BYTE(s, 0); /* CodecChannelT.channelId */ stream_write_UINT16(s, CBT_TILESET); /* subtype */ stream_write_UINT16(s, 0); /* idx */ stream_write_UINT16(s, context->properties); /* properties */ stream_write_BYTE(s, numQuants); /* numQuants */ stream_write_BYTE(s, 0x40); /* tileSize */ stream_write_UINT16(s, numTiles); /* numTiles */ stream_seek_UINT32(s); /* set tilesDataSize later */ quantValsPtr = quantVals; for (i = 0; i < numQuants * 5; i++) { stream_write_BYTE(s, quantValsPtr[0] + (quantValsPtr[1] << 4)); quantValsPtr += 2; } DEBUG_RFX("width:%d height:%d rowstride:%d", width, height, rowstride); end_pos = stream_get_pos(s); for (yIdx = 0; yIdx < numTilesY; yIdx++) { for (xIdx = 0; xIdx < numTilesX; xIdx++) { rfx_compose_message_tile(context, s, image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel, (xIdx < numTilesX - 1) ? 64 : width - xIdx * 64, (yIdx < numTilesY - 1) ? 64 : height - yIdx * 64, rowstride, quantVals, quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx); } } tilesDataSize = stream_get_pos(s) - end_pos; size += tilesDataSize; end_pos = stream_get_pos(s); stream_set_pos(s, start_pos + 2); stream_write_UINT32(s, size); /* CodecChannelT.blockLen */ stream_set_pos(s, start_pos + 18); stream_write_UINT32(s, tilesDataSize); stream_set_pos(s, end_pos); }
static UINT32 handle_State(IRP* irp) { LONG status; SCARDHANDLE hCard; DWORD state = 0, protocol = 0; DWORD readerLen; DWORD atrLen = MAX_ATR_SIZE; char* readerName; BYTE pbAtr[MAX_ATR_SIZE]; #ifdef WITH_DEBUG_SCARD int i; #endif stream_seek(irp->input, 0x24); stream_seek_UINT32(irp->input); /* atrLen */ stream_seek(irp->input, 0x0c); stream_read_UINT32(irp->input, hCard); stream_seek(irp->input, 0x04); #ifdef SCARD_AUTOALLOCATE readerLen = SCARD_AUTOALLOCATE; status = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); #else readerLen = 256; readerName = malloc(readerLen); status = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); #endif if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); return smartcard_output_return(irp, status); } DEBUG_SCARD("Success (hcard: 0x%08x len: %d state: 0x%08x, proto: 0x%08x)", (unsigned) hCard, (int) atrLen, (unsigned) state, (unsigned) protocol); #ifdef WITH_DEBUG_SCARD printf(" ATR: "); for (i = 0; i < atrLen; i++) printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':'); printf("\n"); #endif state = smartcard_map_state(state); stream_write_UINT32(irp->output, state); stream_write_UINT32(irp->output, protocol); stream_write_UINT32(irp->output, atrLen); stream_write_UINT32(irp->output, 0x00000001); stream_write_UINT32(irp->output, atrLen); stream_write(irp->output, pbAtr, atrLen); smartcard_output_repos(irp, atrLen); smartcard_output_alignment(irp, 8); #ifdef SCARD_AUTOALLOCATE free(readerName); #else free(readerName); #endif return status; }
static UINT32 handle_ListReaders(IRP* irp, BOOL wide) { UINT32 len, status; SCARDCONTEXT hContext; DWORD dwReaders; char *readerList = NULL, *walker; int elemLength, dataLength; int pos, poslen1, poslen2; stream_seek(irp->input, 8); stream_read_UINT32(irp->input, len); stream_seek(irp->input, 0x1c); stream_read_UINT32(irp->input, len); if (len != 4) return SCARD_F_INTERNAL_ERROR; stream_read_UINT32(irp->input, hContext); /* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */ status = SCARD_S_SUCCESS; #ifdef SCARD_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; status = SCardListReaders(hContext, NULL, (LPSTR) &readerList, &dwReaders); #else status = SCardListReaders(hContext, NULL, NULL, &dwReaders); readerList = malloc(dwReaders); status = SCardListReaders(hContext, NULL, readerList, &dwReaders); #endif if (status != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(status), (unsigned) status); return status; } /* DEBUG_SCARD("Success 0x%08x %d %d", (unsigned) hContext, (unsigned) cchReaders, (int) strlen(readerList));*/ poslen1 = stream_get_pos(irp->output); stream_seek_UINT32(irp->output); stream_write_UINT32(irp->output, 0x01760650); poslen2 = stream_get_pos(irp->output); stream_seek_UINT32(irp->output); walker = readerList; dataLength = 0; while (1) { elemLength = strlen(walker); if (elemLength == 0) break; dataLength += smartcard_output_string(irp, walker, wide); walker += elemLength + 1; elemLength = strlen(walker); } dataLength += smartcard_output_string(irp, "\0", wide); pos = stream_get_pos(irp->output); stream_set_pos(irp->output, poslen1); stream_write_UINT32(irp->output, dataLength); stream_set_pos(irp->output, poslen2); stream_write_UINT32(irp->output, dataLength); stream_set_pos(irp->output, pos); smartcard_output_repos(irp, dataLength); smartcard_output_alignment(irp, 8); #ifdef SCARD_AUTOALLOCATE SCardFreeMemory(hContext, readerList); #else free(readerList); #endif return status; }
void rts_receive_window_size_command_read(rdpRpc* rpc, STREAM* s) { stream_seek_UINT32(s); /* ReceiveWindowSize (4 bytes) */ }
static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL user_loggedon) { int i; int pos; BYTE c; UINT32 count; int data_len; int count_pos; STREAM* data_out; DEVICE* device; LIST_ITEM* item; data_out = stream_new(256); stream_write_UINT16(data_out, RDPDR_CTYP_CORE); stream_write_UINT16(data_out, PAKID_CORE_DEVICELIST_ANNOUNCE); count_pos = stream_get_pos(data_out); count = 0; stream_seek_UINT32(data_out); /* deviceCount */ for (item = rdpdr->devman->devices->head; item; item = item->next) { device = (DEVICE*) item->data; /** * 1. versionMinor 0x0005 doesn't send PAKID_CORE_USER_LOGGEDON * so all devices should be sent regardless of user_loggedon * 2. smartcard devices should be always sent * 3. other devices are sent only after user_loggedon */ if ((rdpdr->versionMinor == 0x0005) || (device->type == RDPDR_DTYP_SMARTCARD) || user_loggedon) { data_len = (device->data == NULL ? 0 : stream_get_length(device->data)); stream_check_size(data_out, 20 + data_len); stream_write_UINT32(data_out, device->type); /* deviceType */ stream_write_UINT32(data_out, device->id); /* deviceID */ strncpy((char*) stream_get_tail(data_out), device->name, 8); for (i = 0; i < 8; i++) { stream_peek_BYTE(data_out, c); if (c > 0x7F) stream_write_BYTE(data_out, '_'); else stream_seek_BYTE(data_out); } stream_write_UINT32(data_out, data_len); if (data_len > 0) stream_write(data_out, stream_get_data(device->data), data_len); count++; printf("registered device #%d: %s (type=%d id=%d)\n", count, device->name, device->type, device->id); } } pos = stream_get_pos(data_out); stream_set_pos(data_out, count_pos); stream_write_UINT32(data_out, count); stream_set_pos(data_out, pos); stream_seal(data_out); svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out); }
BOOL gcc_read_client_core_data(STREAM* s, rdpSettings* settings, UINT16 blockLength) { char* str; UINT32 version; UINT32 color_depth; UINT16 colorDepth = 0; UINT16 postBeta2ColorDepth = 0; UINT16 highColorDepth = 0; UINT16 supportedColorDepths = 0; UINT16 earlyCapabilityFlags = 0; UINT32 serverSelectedProtocol = 0; /* Length of all required fields, until imeFileName */ if (blockLength < 128) return FALSE; stream_read_UINT32(s, version); /* version */ settings->RdpVersion = (version == RDP_VERSION_4 ? 4 : 7); stream_read_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ stream_read_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ stream_read_UINT16(s, colorDepth); /* ColorDepth */ stream_seek_UINT16(s); /* SASSequence (Secure Access Sequence) */ stream_read_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */ stream_read_UINT32(s, settings->ClientBuild); /* ClientBuild */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), 32 / 2, &str, 0, NULL, NULL); stream_seek(s, 32); sprintf_s(settings->ClientHostname, 31, "%s", str); settings->ClientHostname[31] = 0; free(str); stream_read_UINT32(s, settings->KeyboardType); /* KeyboardType */ stream_read_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */ stream_read_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey */ stream_seek(s, 64); /* imeFileName */ blockLength -= 128; /** * The following fields are all optional. If one field is present, all of the preceding * fields MUST also be present. If one field is not present, all of the subsequent fields * MUST NOT be present. * We must check the bytes left before reading each field. */ do { if (blockLength < 2) break; stream_read_UINT16(s, postBeta2ColorDepth); /* postBeta2ColorDepth */ blockLength -= 2; if (blockLength < 2) break; stream_seek_UINT16(s); /* clientProductID */ blockLength -= 2; if (blockLength < 4) break; stream_seek_UINT32(s); /* serialNumber */ blockLength -= 4; if (blockLength < 2) break; stream_read_UINT16(s, highColorDepth); /* highColorDepth */ blockLength -= 2; if (blockLength < 2) break; stream_read_UINT16(s, supportedColorDepths); /* supportedColorDepths */ blockLength -= 2; if (blockLength < 2) break; stream_read_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ blockLength -= 2; if (blockLength < 64) break; ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) stream_get_tail(s), 64 / 2, &str, 0, NULL, NULL); stream_seek(s, 64); sprintf_s(settings->ClientProductId, 32, "%s", str); free(str); blockLength -= 64; if (blockLength < 1) break; stream_read_BYTE(s, settings->PerformanceFlags); /* connectionType */ blockLength -= 1; if (blockLength < 1) break; stream_seek_BYTE(s); /* pad1octet */ blockLength -= 1; if (blockLength < 4) break; stream_read_UINT32(s, serverSelectedProtocol); /* serverSelectedProtocol */ blockLength -= 4; if (settings->SelectedProtocol != serverSelectedProtocol) return FALSE; } while (0); if (highColorDepth > 0) { color_depth = highColorDepth; } else if (postBeta2ColorDepth > 0) { switch (postBeta2ColorDepth) { case RNS_UD_COLOR_4BPP: color_depth = 4; break; case RNS_UD_COLOR_8BPP: color_depth = 8; break; case RNS_UD_COLOR_16BPP_555: color_depth = 15; break; case RNS_UD_COLOR_16BPP_565: color_depth = 16; break; case RNS_UD_COLOR_24BPP: color_depth = 24; break; default: return FALSE; } } else { switch (colorDepth) { case RNS_UD_COLOR_4BPP: color_depth = 4; break; case RNS_UD_COLOR_8BPP: color_depth = 8; break; default: return FALSE; } } /* * If we are in server mode, accept client's color depth only if * it is smaller than ours. This is what Windows server does. */ if (color_depth < settings->ColorDepth || !settings->ServerMode) settings->ColorDepth = color_depth; return TRUE; }
void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s) { stream_seek_UINT32(s); /* PingTrafficSent (4 bytes) */ }
void rts_connection_timeout_command_read(rdpRpc* rpc, STREAM* s) { stream_seek_UINT32(s); /* ConnectionTimeout (4 bytes) */ }
void rts_version_command_read(rdpRpc* rpc, STREAM* s) { stream_seek_UINT32(s); /* Version (4 bytes) */ }
void rts_client_keepalive_command_read(rdpRpc* rpc, STREAM* s) { stream_seek_UINT32(s); /* ClientKeepalive (4 bytes) */ }
void rts_channel_lifetime_command_read(rdpRpc* rpc, STREAM* s) { stream_seek_UINT32(s); /* ChannelLifetime (4 bytes) */ }