static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) { UINT32 ChannelId; wStream* data_out; int value; int error; ChannelId = drdynvc_read_variable_uint(s, cbChId); DEBUG_DVC("ChannelId=%d", ChannelId); dvcman_close_channel(drdynvc->channel_mgr, ChannelId); data_out = Stream_New(NULL, 4); value = (CLOSE_REQUEST_PDU << 4) | (cbChId & 0x03); Stream_Write_UINT8(data_out, value); drdynvc_write_variable_uint(data_out, ChannelId); error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); if (error != CHANNEL_RC_OK) { DEBUG_WARN("VirtualChannelWrite failed %d", error); return 1; } drdynvc->channel_error = error; return 0; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) { int value; UINT error; UINT32 ChannelId; wStream* data_out; if (Stream_GetRemainingLength(s) < drdynvc_cblen_to_bytes(cbChId)) return ERROR_INVALID_DATA; ChannelId = drdynvc_read_variable_uint(s, cbChId); WLog_Print(drdynvc->log, WLOG_DEBUG, "process_close_request: Sp=%d cbChId=%d, ChannelId=%"PRIu32"", Sp, cbChId, ChannelId); if ((error = dvcman_close_channel(drdynvc->channel_mgr, ChannelId))) { WLog_Print(drdynvc->log, WLOG_ERROR, "dvcman_close_channel failed with error %"PRIu32"!", error); return error; } data_out = Stream_New(NULL, 4); if (!data_out) { WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } value = (CLOSE_REQUEST_PDU << 4) | (cbChId & 0x03); Stream_Write_UINT8(data_out, value); drdynvc_write_variable_uint(data_out, ChannelId); error = drdynvc_send(drdynvc, data_out); if (error) WLog_Print(drdynvc->log, WLOG_ERROR, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", WTSErrorToString(error), error); return error; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, wStream* s) { int value; UINT error; UINT32 ChannelId; wStream* data_out; ChannelId = drdynvc_read_variable_uint(s, cbChId); WLog_DBG(TAG, "process_close_request: Sp=%d cbChId=%d, ChannelId=%d", Sp, cbChId, ChannelId); if ((error = dvcman_close_channel(drdynvc->channel_mgr, ChannelId))) { WLog_ERR(TAG, "dvcman_close_channel failed with error %lu!", error); return error; } data_out = Stream_New(NULL, 4); if (!data_out) { WLog_ERR(TAG, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } value = (CLOSE_REQUEST_PDU << 4) | (cbChId & 0x03); Stream_Write_UINT8(data_out, value); drdynvc_write_variable_uint(data_out, ChannelId); error = drdynvc_send(drdynvc, data_out); if (error) WLog_ERR(TAG, "VirtualChannelWrite failed with %s [%08X]", WTSErrorToString(error), error); return error; }
int drdynvc_write_data(drdynvcPlugin* drdynvc, uint32 ChannelId, char* data, uint32 data_size) { STREAM* data_out; uint32 pos = 0; uint32 cbChId; uint32 cbLen; uint32 chunk_len; int error; DEBUG_DVC("ChannelId=%d size=%d", ChannelId, data_size); data_out = stream_new(CHANNEL_CHUNK_LENGTH); stream_set_pos(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); if (data_size <= CHANNEL_CHUNK_LENGTH - pos) { pos = stream_get_pos(data_out); stream_set_pos(data_out, 0); stream_write_uint8(data_out, 0x30 | cbChId); stream_set_pos(data_out, pos); stream_write(data_out, data, data_size); error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); } else { /* Fragment the data */ cbLen = drdynvc_write_variable_uint(data_out, data_size); pos = stream_get_pos(data_out); stream_set_pos(data_out, 0); stream_write_uint8(data_out, 0x20 | cbChId | (cbLen << 2)); stream_set_pos(data_out, pos); chunk_len = CHANNEL_CHUNK_LENGTH - pos; stream_write(data_out, data, chunk_len); data += chunk_len; data_size -= chunk_len; error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); while (error == CHANNEL_RC_OK && data_size > 0) { data_out = stream_new(CHANNEL_CHUNK_LENGTH); stream_set_pos(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); pos = stream_get_pos(data_out); stream_set_pos(data_out, 0); stream_write_uint8(data_out, 0x30 | cbChId); stream_set_pos(data_out, pos); chunk_len = data_size; if (chunk_len > CHANNEL_CHUNK_LENGTH - pos) chunk_len = CHANNEL_CHUNK_LENGTH - pos; stream_write(data_out, data, chunk_len); data += chunk_len; data_size -= chunk_len; error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); } } if (error != CHANNEL_RC_OK) { DEBUG_WARN("VirtualChannelWrite failed %d", error); return 1; } return 0; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const BYTE* data, UINT32 dataSize) { wStream* data_out; size_t pos; UINT32 cbChId; UINT32 cbLen; unsigned long chunkLength; UINT status; if (!drdynvc) return CHANNEL_RC_BAD_CHANNEL_HANDLE; WLog_Print(drdynvc->log, WLOG_DEBUG, "write_data: ChannelId=%"PRIu32" size=%"PRIu32"", ChannelId, dataSize); data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); if (!data_out) { WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); pos = Stream_GetPosition(data_out); if (dataSize == 0) { Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x40 | cbChId); Stream_SetPosition(data_out, pos); status = drdynvc_send(drdynvc, data_out); } else if (dataSize <= CHANNEL_CHUNK_LENGTH - pos) { Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x30 | cbChId); Stream_SetPosition(data_out, pos); Stream_Write(data_out, data, dataSize); status = drdynvc_send(drdynvc, data_out); } else { /* Fragment the data */ cbLen = drdynvc_write_variable_uint(data_out, dataSize); pos = Stream_GetPosition(data_out); Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x20 | cbChId | (cbLen << 2)); Stream_SetPosition(data_out, pos); chunkLength = CHANNEL_CHUNK_LENGTH - pos; Stream_Write(data_out, data, chunkLength); data += chunkLength; dataSize -= chunkLength; status = drdynvc_send(drdynvc, data_out); while (status == CHANNEL_RC_OK && dataSize > 0) { data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); if (!data_out) { WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!"); return CHANNEL_RC_NO_MEMORY; } Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); pos = Stream_GetPosition(data_out); Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x30 | cbChId); Stream_SetPosition(data_out, pos); chunkLength = dataSize; if (chunkLength > CHANNEL_CHUNK_LENGTH - pos) chunkLength = CHANNEL_CHUNK_LENGTH - pos; Stream_Write(data_out, data, chunkLength); data += chunkLength; dataSize -= chunkLength; status = drdynvc_send(drdynvc, data_out); } } if (status != CHANNEL_RC_OK) { WLog_Print(drdynvc->log, WLOG_ERROR, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", WTSErrorToString(status), status); return status; } return CHANNEL_RC_OK; }
int drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UINT32 dataSize) { wStream* data_out; UINT32 pos = 0; UINT32 cbChId; UINT32 cbLen; UINT32 chunkLength; int status; DEBUG_DVC("ChannelId=%d size=%d", ChannelId, dataSize); if (drdynvc->channel_error != CHANNEL_RC_OK) return 1; data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); if (dataSize == 0) { pos = Stream_GetPosition(data_out); Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x40 | cbChId); Stream_SetPosition(data_out, pos); status = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); } else if (dataSize <= CHANNEL_CHUNK_LENGTH - pos) { pos = Stream_GetPosition(data_out); Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x30 | cbChId); Stream_SetPosition(data_out, pos); Stream_Write(data_out, data, dataSize); status = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); } else { /* Fragment the data */ cbLen = drdynvc_write_variable_uint(data_out, dataSize); pos = Stream_GetPosition(data_out); Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x20 | cbChId | (cbLen << 2)); Stream_SetPosition(data_out, pos); chunkLength = CHANNEL_CHUNK_LENGTH - pos; Stream_Write(data_out, data, chunkLength); data += chunkLength; dataSize -= chunkLength; status = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); while (status == CHANNEL_RC_OK && dataSize > 0) { data_out = Stream_New(NULL, CHANNEL_CHUNK_LENGTH); Stream_SetPosition(data_out, 1); cbChId = drdynvc_write_variable_uint(data_out, ChannelId); pos = Stream_GetPosition(data_out); Stream_SetPosition(data_out, 0); Stream_Write_UINT8(data_out, 0x30 | cbChId); Stream_SetPosition(data_out, pos); chunkLength = dataSize; if (chunkLength > CHANNEL_CHUNK_LENGTH - pos) chunkLength = CHANNEL_CHUNK_LENGTH - pos; Stream_Write(data_out, data, chunkLength); data += chunkLength; dataSize -= chunkLength; status = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); } } if (status != CHANNEL_RC_OK) { drdynvc->channel_error = status; DEBUG_WARN("VirtualChannelWrite failed %d", status); return 1; } return 0; }