/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT tsmf_ifman_remove_stream(TSMF_IFMAN* ifman) { int status = CHANNEL_RC_OK; UINT32 StreamId; TSMF_STREAM* stream; TSMF_PRESENTATION* presentation; DEBUG_TSMF(""); if (Stream_GetRemainingLength(ifman->input) < 20) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); Stream_Seek(ifman->input, GUID_SIZE); if (!presentation) { status = ERROR_NOT_FOUND; } else { Stream_Read_UINT32(ifman->input, StreamId); stream = tsmf_stream_find_by_id(presentation, StreamId); if (stream) tsmf_stream_free(stream); else status = ERROR_NOT_FOUND; } ifman->output_pending = TRUE; return status; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT tsmf_ifman_set_source_video_rect(TSMF_IFMAN* ifman) { UINT status = CHANNEL_RC_OK; float Left, Top; float Right, Bottom; TSMF_PRESENTATION* presentation; DEBUG_TSMF(""); if (Stream_GetRemainingLength(ifman->input) < 32) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); Stream_Seek(ifman->input, GUID_SIZE); if (!presentation) { status = ERROR_NOT_FOUND; } else { Left = tsmf_stream_read_float(ifman->input); /* Left (4 bytes) */ Top = tsmf_stream_read_float(ifman->input); /* Top (4 bytes) */ Right = tsmf_stream_read_float(ifman->input); /* Right (4 bytes) */ Bottom = tsmf_stream_read_float(ifman->input); /* Bottom (4 bytes) */ DEBUG_TSMF("SetSourceVideoRect: Left: %f Top: %f Right: %f Bottom: %f", Left, Top, Right, Bottom); } ifman->output_pending = TRUE; return status; }
/* http://msdn.microsoft.com/en-us/library/dd390700.aspx */ static UINT32 tsmf_codec_parse_VIDEOINFOHEADER(TS_AM_MEDIA_TYPE *mediatype, wStream *s) { /* typedef struct tagVIDEOINFOHEADER { RECT rcSource; //16 RECT rcTarget; //16 32 DWORD dwBitRate; //4 36 DWORD dwBitErrorRate; //4 40 REFERENCE_TIME AvgTimePerFrame; //8 48 BITMAPINFOHEADER bmiHeader; } VIDEOINFOHEADER; */ UINT64 AvgTimePerFrame; /* VIDEOINFOHEADER.rcSource, RECT(LONG left, LONG top, LONG right, LONG bottom) */ Stream_Seek_UINT32(s); Stream_Seek_UINT32(s); Stream_Read_UINT32(s, mediatype->Width); Stream_Read_UINT32(s, mediatype->Height); /* VIDEOINFOHEADER.rcTarget */ Stream_Seek(s, 16); /* VIDEOINFOHEADER.dwBitRate */ Stream_Read_UINT32(s, mediatype->BitRate); /* VIDEOINFOHEADER.dwBitErrorRate */ Stream_Seek_UINT32(s); /* VIDEOINFOHEADER.AvgTimePerFrame */ Stream_Read_UINT64(s, AvgTimePerFrame); mediatype->SamplesPerSecond.Numerator = 1000000; mediatype->SamplesPerSecond.Denominator = (int)(AvgTimePerFrame / 10LL); return 48; }
static int remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) { int status; UINT32 ChannelNameLen; char* pChannelName = NULL; if (Stream_GetRemainingLength(s) < 8) return -1; Stream_Read_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */ Stream_Read_UINT32(s, header->DataLength); /* DataLen (4 bytes) */ if (ChannelNameLen > 64) return -1; if ((ChannelNameLen % 2) != 0) return -1; if (Stream_GetRemainingLength(s) < ChannelNameLen) return -1; ZeroMemory(header->ChannelName, sizeof(header->ChannelName)); pChannelName = (char*) header->ChannelName; status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), ChannelNameLen / 2, &pChannelName, 32, NULL, NULL); Stream_Seek(s, ChannelNameLen); if (status <= 0) return -1; return 1; }
BOOL rdg_process_handshake_response(rdpRdg* rdg, wStream* s) { HRESULT errorCode; WLog_DBG(TAG, "Handshake response received"); if (rdg->state != RDG_CLIENT_STATE_HANDSHAKE) { return FALSE; } if (Stream_GetRemainingLength(s) < 12) return FALSE; Stream_Seek(s, 8); Stream_Read_UINT32(s, errorCode); if (FAILED(errorCode)) { WLog_DBG(TAG, "Handshake error %x", errorCode); return FALSE; } return rdg_send_tunnel_request(rdg); }
BOOL rdg_process_channel_response(rdpRdg* rdg, wStream* s) { HRESULT errorCode; WLog_DBG(TAG, "Channel response received"); if (rdg->state != RDG_CLIENT_STATE_CHANNEL_CREATE) { return FALSE; } if (Stream_GetRemainingLength(s) < 12) return FALSE; Stream_Seek(s, 8); Stream_Read_UINT32(s, errorCode); if (FAILED(errorCode)) { WLog_DBG(TAG, "Channel error %x", errorCode); return FALSE; } rdg->state = RDG_CLIENT_STATE_OPENED; return TRUE; }
BOOL rdg_process_tunnel_authorization_response(rdpRdg* rdg, wStream* s) { HRESULT errorCode; WLog_DBG(TAG, "Tunnel authorization received"); if (rdg->state != RDG_CLIENT_STATE_TUNNEL_AUTHORIZE) { return FALSE; } if (Stream_GetRemainingLength(s) < 12) return FALSE; Stream_Seek(s, 8); Stream_Read_UINT32(s, errorCode); if (FAILED(errorCode)) { WLog_DBG(TAG, "Tunnel authorization error %x", errorCode); return FALSE; } return rdg_send_channel_create(rdg); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman) { TSMF_PRESENTATION* presentation; UINT32 newVolume; UINT32 muted; DEBUG_TSMF("on stream volume"); if (Stream_GetRemainingLength(ifman->input) < GUID_SIZE + 8) return ERROR_INVALID_DATA; presentation = tsmf_presentation_find_by_id(Stream_Pointer(ifman->input)); if (!presentation) { WLog_ERR(TAG, "unknown presentation id"); return ERROR_NOT_FOUND; } Stream_Seek(ifman->input, 16); Stream_Read_UINT32(ifman->input, newVolume); DEBUG_TSMF("on stream volume: new volume=[%d]", newVolume); Stream_Read_UINT32(ifman->input, muted); DEBUG_TSMF("on stream volume: muted=[%d]", muted); if (!tsmf_presentation_volume_changed(presentation, newVolume, muted)) return ERROR_INVALID_OPERATION; ifman->output_pending = TRUE; return 0; }
static BOOL input_recv_keyboard_event(rdpInput* input, wStream* s) { UINT16 keyboardFlags, keyCode; if (Stream_GetRemainingLength(s) < 6) return FALSE; Stream_Read_UINT16(s, keyboardFlags); /* keyboardFlags (2 bytes) */ Stream_Read_UINT16(s, keyCode); /* keyCode (2 bytes) */ Stream_Seek(s, 2); /* pad2Octets (2 bytes) */ /** * Note: A lot of code in FreeRDP and in dependent projects checks the * KBDFLAGS_DOWN flag in order to detect a key press. * According to the specs only the absence of the slow-path * KBDFLAGS_RELEASE flag indicates a key-down event. * The slow-path KBDFLAGS_DOWN flag merely indicates that the key was * down prior to this event. * The checks for KBDFLAGS_DOWN only work successfully because the code * handling the fast-path keyboard input sets the KBDFLAGS_DOWN flag if * the FASTPATH_INPUT_KBDFLAGS_RELEASE flag is missing. * Since the same input callback is used for slow- and fast-path events * we have to follow that "convention" here. */ if (keyboardFlags & KBD_FLAGS_RELEASE) keyboardFlags &= ~KBD_FLAGS_DOWN; else keyboardFlags |= KBD_FLAGS_DOWN; IFCALL(input->KeyboardEvent, input, keyboardFlags, keyCode); return TRUE; }
static BOOL input_recv_event(rdpInput* input, wStream* s) { UINT16 messageType; if (Stream_GetRemainingLength(s) < 6) return FALSE; Stream_Seek(s, 4); /* eventTime (4 bytes), ignored by the server */ Stream_Read_UINT16(s, messageType); /* messageType (2 bytes) */ switch (messageType) { case INPUT_EVENT_SYNC: if (!input_recv_sync_event(input, s)) return FALSE; break; case INPUT_EVENT_SCANCODE: if (!input_recv_keyboard_event(input, s)) return FALSE; break; case INPUT_EVENT_UNICODE: if (!input_recv_unicode_keyboard_event(input, s)) return FALSE; break; case INPUT_EVENT_MOUSE: if (!input_recv_mouse_event(input, s)) return FALSE; break; case INPUT_EVENT_MOUSEX: if (!input_recv_extended_mouse_event(input, s)) return FALSE; break; default: fprintf(stderr, "Unknown messageType %u\n", messageType); /* Each input event uses 6 bytes. */ Stream_Seek(s, 6); break; } return TRUE; }
wStream* rdp_message_channel_pdu_init(rdpRdp* rdp) { wStream* s; s = transport_send_stream_init(rdp->transport, 2048); Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH); rdp_security_stream_init(rdp, s); return s; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_SURFACE_COMMAND cmd; RDPGFX_WIRE_TO_SURFACE_PDU_1 pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; UINT error; if (Stream_GetRemainingLength(s) < 17) { WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */ Stream_Read_UINT8(s, pdu.pixelFormat); /* pixelFormat (1 byte) */ if ((error = rdpgfx_read_rect16(s, &(pdu.destRect)))) /* destRect (8 bytes) */ { WLog_ERR(TAG, "rdpgfx_read_rect16 failed with error %lu", error); return error; } Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */ if (pdu.bitmapDataLength > Stream_GetRemainingLength(s)) { WLog_ERR(TAG, "not enough data!"); return ERROR_INVALID_DATA; } pdu.bitmapData = Stream_Pointer(s); Stream_Seek(s, pdu.bitmapDataLength); WLog_DBG(TAG, "RecvWireToSurface1Pdu: surfaceId: %d codecId: %s (0x%04X) pixelFormat: 0x%04X " "destRect: left: %d top: %d right: %d bottom: %d bitmapDataLength: %d", (int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, pdu.pixelFormat, pdu.destRect.left, pdu.destRect.top, pdu.destRect.right, pdu.destRect.bottom, pdu.bitmapDataLength); cmd.surfaceId = pdu.surfaceId; cmd.codecId = pdu.codecId; cmd.contextId = 0; cmd.format = pdu.pixelFormat; cmd.left = pdu.destRect.left; cmd.top = pdu.destRect.top; cmd.right = pdu.destRect.right; cmd.bottom = pdu.destRect.bottom; cmd.width = cmd.right - cmd.left; cmd.height = cmd.bottom - cmd.top; cmd.length = pdu.bitmapDataLength; cmd.data = pdu.bitmapData; if ((error = rdpgfx_decode(gfx, &cmd))) WLog_ERR(TAG, "rdpgfx_decode failed with error %lu!", error); return error; }
int transport_write(rdpTransport* transport, wStream* s) { int status = -1; int length; length = Stream_GetPosition(s); Stream_SetPosition(s, 0); #ifdef WITH_DEBUG_TRANSPORT if (length > 0) { fprintf(stderr, "Local > Remote\n"); winpr_HexDump(s->buffer, length); } #endif while (length > 0) { if (transport->layer == TRANSPORT_LAYER_TLS) status = tls_write(transport->TlsOut, Stream_Pointer(s), length); else if (transport->layer == TRANSPORT_LAYER_TCP) status = tcp_write(transport->TcpOut, Stream_Pointer(s), length); else if (transport->layer == TRANSPORT_LAYER_TSG) status = tsg_write(transport->tsg, Stream_Pointer(s), length); if (status < 0) break; /* error occurred */ if (status == 0) { /* when sending is blocked in nonblocking mode, the receiving buffer should be checked */ if (!transport->blocking) { /* and in case we do have buffered some data, we set the event so next loop will get it */ if (transport_read_nonblocking(transport) > 0) SetEvent(transport->ReceiveEvent); } if (transport->layer == TRANSPORT_LAYER_TLS) tls_wait_write(transport->TlsOut); else if (transport->layer == TRANSPORT_LAYER_TCP) tcp_wait_write(transport->TcpOut); else USleep(transport->SleepInterval); } length -= status; Stream_Seek(s, status); } if (status < 0) { /* A write error indicates that the peer has dropped the connection */ transport->layer = TRANSPORT_LAYER_CLOSED; } return status; }
BOOL rdp_recv_logon_plain_notify(rdpRdp* rdp, wStream* s) { if (Stream_GetRemainingLength(s) < 576) return FALSE; Stream_Seek(s, 576); /* pad */ return TRUE; }
wStream* rail_pdu_init(size_t length) { wStream* s; s = Stream_New(NULL, length + RAIL_PDU_HEADER_LENGTH); if (!s) return NULL; Stream_Seek(s, RAIL_PDU_HEADER_LENGTH); return s; }
BOOL rdp_read_security_header(wStream* s, UINT16* flags) { /* Basic Security Header */ if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Read_UINT16(s, *flags); /* flags */ Stream_Seek(s, 2); /* flagsHi (unused) */ return TRUE; }
int rdpgfx_recv_wire_to_surface_1_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { RDPGFX_SURFACE_COMMAND cmd; RDPGFX_WIRE_TO_SURFACE_PDU_1 pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; if (Stream_GetRemainingLength(s) < 17) return -1; Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.codecId); /* codecId (2 bytes) */ Stream_Read_UINT8(s, pdu.pixelFormat); /* pixelFormat (1 byte) */ rdpgfx_read_rect16(s, &(pdu.destRect)); /* destRect (8 bytes) */ Stream_Read_UINT32(s, pdu.bitmapDataLength); /* bitmapDataLength (4 bytes) */ if (pdu.bitmapDataLength > Stream_GetRemainingLength(s)) return -1; pdu.bitmapData = Stream_Pointer(s); Stream_Seek(s, pdu.bitmapDataLength); WLog_Print(gfx->log, WLOG_DEBUG, "RecvWireToSurface1Pdu: surfaceId: %d codecId: %s (0x%04X) pixelFormat: 0x%04X " "destRect: left: %d top: %d right: %d bottom: %d bitmapDataLength: %d", (int) pdu.surfaceId, rdpgfx_get_codec_id_string(pdu.codecId), pdu.codecId, pdu.pixelFormat, pdu.destRect.left, pdu.destRect.top, pdu.destRect.right, pdu.destRect.bottom, pdu.bitmapDataLength); cmd.surfaceId = pdu.surfaceId; cmd.codecId = pdu.codecId; cmd.contextId = 0; cmd.format = pdu.pixelFormat; cmd.left = pdu.destRect.left; cmd.top = pdu.destRect.top; cmd.right = pdu.destRect.right; cmd.bottom = pdu.destRect.bottom; cmd.width = cmd.right - cmd.left; cmd.height = cmd.bottom - cmd.top; cmd.length = pdu.bitmapDataLength; cmd.data = pdu.bitmapData; if (cmd.codecId == RDPGFX_CODECID_H264) { rdpgfx_decode(gfx, &cmd); } else { if (context && context->SurfaceCommand) { context->SurfaceCommand(context, &cmd); } } return 1; }
wStream* license_send_stream_init(rdpLicense* license) { wStream* s; s = transport_send_stream_init(license->rdp->transport, 4096); Stream_Seek(s, LICENSE_PACKET_HEADER_MAX_LENGTH); return s; }
/* http://msdn.microsoft.com/en-us/library/dd318229.aspx */ static UINT32 tsmf_codec_parse_BITMAPINFOHEADER(TS_AM_MEDIA_TYPE *mediatype, wStream *s, BOOL bypass) { UINT32 biSize; UINT32 biWidth; UINT32 biHeight; Stream_Read_UINT32(s, biSize); Stream_Read_UINT32(s, biWidth); Stream_Read_UINT32(s, biHeight); Stream_Seek(s, 28); if(mediatype->Width == 0) mediatype->Width = biWidth; if(mediatype->Height == 0) mediatype->Height = biHeight; /* Assume there will be no color table for video? */ if(bypass && biSize > 40) Stream_Seek(s, biSize - 40); return (bypass ? biSize : 40); }
wStream* license_send_stream_init(rdpLicense* license) { wStream* s; s = Stream_New(NULL, 4096); Stream_Seek(s, LICENSE_PACKET_HEADER_MAX_LENGTH); return s; }
static BOOL rdg_process_control_packet(rdpRdg* rdg, int type, size_t packetLength) { wStream* s = NULL; size_t readCount = 0; int status; size_t payloadSize = packetLength - sizeof(RdgPacketHeader); if (payloadSize) { s = Stream_New(NULL, payloadSize); if (!s) return FALSE; while (readCount < payloadSize) { status = BIO_read(rdg->tlsOut->bio, Stream_Pointer(s), sizeof(RdgPacketHeader) - readCount); if (status <= 0) { if (!BIO_should_retry(rdg->tlsOut->bio)) { Stream_Free(s, TRUE); return FALSE; } continue; } Stream_Seek(s, status); readCount += status; } } switch (type) { case PKT_TYPE_CLOSE_CHANNEL: EnterCriticalSection(&rdg->writeSection); status = rdg_process_close_packet(rdg); LeaveCriticalSection(&rdg->writeSection); break; case PKT_TYPE_KEEPALIVE: EnterCriticalSection(&rdg->writeSection); status = rdg_process_keep_alive_packet(rdg); LeaveCriticalSection(&rdg->writeSection); break; default: status = rdg_process_unknown_packet(rdg, type); break; } Stream_Free(s, TRUE); return status; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp) { UINT32 Length; UINT64 Offset; BYTE* buffer = NULL; DWORD nbRead = 0; Stream_Read_UINT32(irp->input, Length); /* Length (4 bytes) */ Stream_Read_UINT64(irp->input, Offset); /* Offset (8 bytes) */ Stream_Seek(irp->input, 20); /* Padding (20 bytes) */ buffer = (BYTE*)calloc(Length, sizeof(BYTE)); if (buffer == NULL) { irp->IoStatus = STATUS_NO_MEMORY; goto error_handle; } /* MS-RDPESP 3.2.5.1.4: If the Offset field is not set to 0, the value MUST be ignored * assert(Offset == 0); */ WLog_Print(serial->log, WLOG_DEBUG, "reading %d bytes from %s", Length, serial->device.name); /* FIXME: CommReadFile to be replaced by ReadFile */ if (CommReadFile(serial->hComm, buffer, Length, &nbRead, NULL)) { irp->IoStatus = STATUS_SUCCESS; } else { WLog_Print(serial->log, WLOG_DEBUG, "read failure to %s, nbRead=%ld, last-error: 0x%lX", serial->device.name, nbRead, GetLastError()); irp->IoStatus = _GetLastErrorToIoStatus(serial); } WLog_Print(serial->log, WLOG_DEBUG, "%lu bytes read from %s", nbRead, serial->device.name); error_handle: Stream_Write_UINT32(irp->output, nbRead); /* Length (4 bytes) */ if (nbRead > 0) { if (!Stream_EnsureRemainingCapacity(irp->output, nbRead)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); free(buffer); return CHANNEL_RC_NO_MEMORY; } Stream_Write(irp->output, buffer, nbRead); /* ReadData */ } free(buffer); return CHANNEL_RC_OK; }
static err_t Open(urlpart* p, const tchar_t* URL, int Flags) { err_t Result; const tchar_t *String, *Equal; tchar_t Value[MAXPATHFULL]; datetime_t Date = INVALID_DATETIME_T; String = tcsrchr(URL,URLPART_SEP_CHAR); if (!String) return ERR_INVALID_DATA; Clear(p); Node_SetData((node*)p,STREAM_URL,TYPE_STRING,URL); Equal = GetProtocol(URL,NULL,0,NULL); tcsncpy_s(Value,TSIZEOF(Value),Equal,String-Equal); tcsreplace(Value,TSIZEOF(Value),URLPART_SEP_ESCAPE,URLPART_SEPARATOR); Node_SetData((node*)p,URLPART_URL,TYPE_STRING,Value); while (String++ && *String) { Equal = tcschr(String,T('=')); if (Equal) { tchar_t *Sep = tcschr(Equal,T('#')); if (Sep) tcsncpy_s(Value,TSIZEOF(Value),Equal+1,Sep-Equal-1); else tcscpy_s(Value,TSIZEOF(Value),Equal+1); if (tcsncmp(String,T("ofs"),Equal-String)==0) p->Pos = StringToInt(Value,0); else if (tcsncmp(String,T("len"),Equal-String)==0) p->Length = StringToInt(Value,0); else if (tcsncmp(String,T("mime"),Equal-String)==0) Node_SetData((node*)p,URLPART_MIME,TYPE_STRING,Value); else if (tcsncmp(String,T("date"),Equal-String)==0) Date = StringToInt(Value,0); } String = tcschr(String,'#'); } if (Date!=INVALID_DATETIME_T && Date != FileDateTime(Node_Context(p),Node_GetDataStr((node*)p,URLPART_URL))) return ERR_INVALID_DATA; p->Input = GetStream(p,Node_GetDataStr((node*)p,URLPART_URL),Flags); if (!p->Input) return ERR_NOT_SUPPORTED; Stream_Blocking(p->Input,p->Blocking); Result = Stream_Open(p->Input,Node_GetDataStr((node*)p,URLPART_URL),Flags); if (Result == ERR_NONE && p->Pos!=INVALID_FILEPOS_T) // TODO: support asynchronous stream opening { if (Stream_Seek(p->Input,p->Pos,SEEK_SET)!=p->Pos) return ERR_INVALID_DATA; } return Result; }
static BOOL rfx_process_message_channels(RFX_CONTEXT* context, wStream* s) { BYTE channelId; BYTE numChannels; context->decodedHeaderBlocks &= ~_RFX_DECODED_CHANNELS; if (Stream_GetRemainingLength(s) < 1) { WLog_ERR(TAG, "RfxMessageChannels packet too small"); return FALSE; } Stream_Read_UINT8(s, numChannels); /* numChannels (1 byte), must bet set to 0x01 */ /* In RDVH sessions, numChannels will represent the number of virtual monitors * configured and does not always be set to 0x01 as [MS-RDPRFX] said. */ if (numChannels < 1) { WLog_ERR(TAG, "no channels announced"); return FALSE; } if (Stream_GetRemainingLength(s) < (size_t) (numChannels * 5)) { WLog_ERR(TAG, "RfxMessageChannels packet too small for numChannels=%d", numChannels); return FALSE; } /* RFX_CHANNELT */ Stream_Read_UINT8(s, channelId); /* channelId (1 byte), must be set to 0x00 */ if (channelId != 0x00) { WLog_ERR(TAG, "channelId:0x%02X, expected:0x00", channelId); return FALSE; } Stream_Read_UINT16(s, context->width); /* width (2 bytes) */ Stream_Read_UINT16(s, context->height); /* height (2 bytes) */ if (!context->width || !context->height) { WLog_ERR(TAG, "%s: invalid channel with/height: %ux%u", __FUNCTION__, context->width, context->height); return FALSE; } /* Now, only the first monitor can be used, therefore the other channels will be ignored. */ Stream_Seek(s, 5 * (numChannels - 1)); WLog_Print(context->priv->log, WLOG_DEBUG, "numChannels %d id %d, %dx%d.", numChannels, channelId, context->width, context->height); context->decodedHeaderBlocks |= _RFX_DECODED_CHANNELS; return TRUE; }
int rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s) { int pad; UINT32 index; MONITOR_DEF* monitor; RDPGFX_RESET_GRAPHICS_PDU pdu; RDPGFX_PLUGIN* gfx = (RDPGFX_PLUGIN*) callback->plugin; RdpgfxClientContext* context = (RdpgfxClientContext*) gfx->iface.pInterface; if (Stream_GetRemainingLength(s) < 12) return -1; Stream_Read_UINT32(s, pdu.width); /* width (4 bytes) */ Stream_Read_UINT32(s, pdu.height); /* height (4 bytes) */ Stream_Read_UINT32(s, pdu.monitorCount); /* monitorCount (4 bytes) */ if (Stream_GetRemainingLength(s) < (pdu.monitorCount * 20)) return -1; pdu.monitorDefArray = (MONITOR_DEF*) calloc(pdu.monitorCount, sizeof(MONITOR_DEF)); if (!pdu.monitorDefArray) return -1; for (index = 0; index < pdu.monitorCount; index++) { monitor = &(pdu.monitorDefArray[index]); Stream_Read_UINT32(s, monitor->left); /* left (4 bytes) */ Stream_Read_UINT32(s, monitor->top); /* top (4 bytes) */ Stream_Read_UINT32(s, monitor->right); /* right (4 bytes) */ Stream_Read_UINT32(s, monitor->bottom); /* bottom (4 bytes) */ Stream_Read_UINT32(s, monitor->flags); /* flags (4 bytes) */ } pad = 340 - (RDPGFX_HEADER_SIZE + 12 + (pdu.monitorCount * 20)); if (Stream_GetRemainingLength(s) < (size_t) pad) { free(pdu.monitorDefArray); return -1; } Stream_Seek(s, pad); /* pad (total size is 340 bytes) */ WLog_Print(gfx->log, WLOG_DEBUG, "RecvResetGraphicsPdu: width: %d height: %d count: %d", pdu.width, pdu.height, pdu.monitorCount); if (context && context->ResetGraphics) { context->ResetGraphics(context, &pdu); } free(pdu.monitorDefArray); return 1; }
wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen) { wStream* s; s = Stream_New(NULL, dataLen + 8); Stream_Write_UINT16(s, msgType); Stream_Write_UINT16(s, msgFlags); /* Write actual length after the entire packet has been constructed. */ Stream_Seek(s, 4); return s; }
/** * @brief Tries to read toRead bytes from the specified transport * * Try to read toRead bytes from the transport to the stream. * In case it was not possible to read toRead bytes 0 is returned. The stream is always advanced by the * number of bytes read. * * The function assumes that the stream has enough capacity to hold the data. * * @param[in] transport rdpTransport * @param[in] s wStream * @param[in] toRead number of bytes to read * @return < 0 on error; 0 if not enough data is available (non blocking mode); 1 toRead bytes read */ static int transport_read_layer_bytes(rdpTransport* transport, wStream* s, unsigned int toRead) { int status; status = transport_read_layer(transport, Stream_Pointer(s), toRead); if (status <= 0) return status; Stream_Seek(s, status); return status == toRead ? 1 : 0; }
UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s) { UINT status = CHANNEL_RC_OK; UINT16 i; UINT16 numCapabilities; UINT16 capabilityType; if (!rdpdr || !s) return CHANNEL_RC_NULL_DATA; if (Stream_GetRemainingLength(s) < 4) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, numCapabilities); Stream_Seek(s, 2); /* pad (2 bytes) */ for (i = 0; i < numCapabilities; i++) { if (Stream_GetRemainingLength(s) < sizeof(UINT16)) return ERROR_INVALID_DATA; Stream_Read_UINT16(s, capabilityType); switch (capabilityType) { case CAP_GENERAL_TYPE: status = rdpdr_process_general_capset(rdpdr, s); break; case CAP_PRINTER_TYPE: status = rdpdr_process_printer_capset(rdpdr, s); break; case CAP_PORT_TYPE: status = rdpdr_process_port_capset(rdpdr, s); break; case CAP_DRIVE_TYPE: status = rdpdr_process_drive_capset(rdpdr, s); break; case CAP_SMARTCARD_TYPE: status = rdpdr_process_smartcard_capset(rdpdr, s); break; default: break; } if (status != CHANNEL_RC_OK) return status; } return CHANNEL_RC_OK; }
BOOL update_read_bitmap_data(rdpUpdate* update, wStream* s, BITMAP_DATA* bitmapData) { if (Stream_GetRemainingLength(s) < 18) return FALSE; Stream_Read_UINT16(s, bitmapData->destLeft); Stream_Read_UINT16(s, bitmapData->destTop); Stream_Read_UINT16(s, bitmapData->destRight); Stream_Read_UINT16(s, bitmapData->destBottom); Stream_Read_UINT16(s, bitmapData->width); Stream_Read_UINT16(s, bitmapData->height); Stream_Read_UINT16(s, bitmapData->bitsPerPixel); Stream_Read_UINT16(s, bitmapData->flags); Stream_Read_UINT16(s, bitmapData->bitmapLength); if (bitmapData->flags & BITMAP_COMPRESSION) { if (!(bitmapData->flags & NO_BITMAP_COMPRESSION_HDR)) { Stream_Read_UINT16(s, bitmapData->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */ Stream_Read_UINT16(s, bitmapData->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */ Stream_Read_UINT16(s, bitmapData->cbScanWidth); /* cbScanWidth (2 bytes) */ Stream_Read_UINT16(s, bitmapData->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */ bitmapData->bitmapLength = bitmapData->cbCompMainBodySize; } bitmapData->compressed = TRUE; Stream_GetPointer(s, bitmapData->bitmapDataStream); Stream_Seek(s, bitmapData->bitmapLength); } else { if (Stream_GetRemainingLength(s) < bitmapData->bitmapLength) return FALSE; bitmapData->compressed = FALSE; Stream_GetPointer(s, bitmapData->bitmapDataStream); Stream_Seek(s, bitmapData->bitmapLength); } return TRUE; }
static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp) { char* path = NULL; int status; SERIAL_TTY* tty; UINT32 PathLength; UINT32 FileId; Stream_Seek(irp->input, 28); /* DesiredAccess(4) AllocationSize(8), FileAttributes(4) */ /* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */ Stream_Read_UINT32(irp->input, PathLength); status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(irp->input), PathLength / 2, &path, 0, NULL, NULL); if (status < 1) path = (char*) calloc(1, 1); FileId = irp->devman->id_sequence++; tty = serial_tty_new(serial->path, FileId); if (tty == NULL) { irp->IoStatus = STATUS_UNSUCCESSFUL; FileId = 0; DEBUG_WARN("failed to create %s", path); } else { serial->tty = tty; serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_NONE, STATUS_CANCELLED); serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_READ, STATUS_CANCELLED); serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_WRITE, STATUS_CANCELLED); serial->mthread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) serial_thread_mfunc, (void*) serial, 0, NULL); DEBUG_SVC("%s(%d) created.", serial->path, FileId); } Stream_Write_UINT32(irp->output, FileId); Stream_Write_UINT8(irp->output, 0); free(path); irp->Complete(irp); }