/* header is not removed from data in this function */ static int thread_process_message_wave(rdpsndPlugin * plugin, char * data, int data_size) { int size; int wTimeStamp; char * out_data; plugin->expectingWave = 0; memcpy(data, plugin->waveData, 4); if (data_size != plugin->waveDataSize) { LLOGLN(0, ("thread_process_message_wave: " "size error")); } if (plugin->device_plugin) plugin->device_plugin->play(plugin->device_plugin, data, data_size, &plugin->delay_ms); size = 8; out_data = (char *) malloc(size); SET_UINT8(out_data, 0, SNDC_WAVECONFIRM); SET_UINT8(out_data, 1, 0); SET_UINT16(out_data, 2, size - 4); LLOGLN(10, ("thread_process_message_wave: " "data_size %d delay %d local_time %u", data_size, plugin->delay_ms, plugin->local_time_stamp)); wTimeStamp = plugin->wTimeStamp + plugin->delay_ms; SET_UINT16(out_data, 4, wTimeStamp); SET_UINT8(out_data, 6, plugin->cBlockNo); SET_UINT8(out_data, 7, 0); plugin->data_out = out_data; plugin->data_out_size = size; queue_data_out(plugin); return 0; }
static int set_variable_uint(uint32 val, char * data, uint32 * pos) { int cb; if (val <= 0xFF) { cb = 0; SET_UINT8(data, *pos, val); *pos += 1; } else if (val <= 0xFFFF) { cb = 1; SET_UINT16(data, *pos, val); *pos += 2; } else { cb = 3; SET_UINT32(data, *pos, val); *pos += 4; } return cb; }
static int audin_send_incoming_data_pdu(IWTSVirtualChannelCallback * pChannelCallback) { AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback; char out_data[1]; SET_UINT8(out_data, 0, MSG_SNDIN_DATA_INCOMING); return callback->channel->Write(callback->channel, 1, out_data, NULL); }
static int audin_send_open_reply_pdu(IWTSVirtualChannelCallback * pChannelCallback, uint32 Result) { AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback; char out_data[5]; SET_UINT8(out_data, 0, MSG_SNDIN_OPEN_REPLY); SET_UINT32(out_data, 1, Result); return callback->channel->Write(callback->channel, 5, out_data, NULL); }
static int audin_send_format_change_pdu(IWTSVirtualChannelCallback * pChannelCallback, uint32 NewFormat) { AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback; char out_data[5]; SET_UINT8(out_data, 0, MSG_SNDIN_FORMATCHANGE); SET_UINT32(out_data, 1, NewFormat); return callback->channel->Write(callback->channel, 5, out_data, NULL); }
/* called by worker thread server is getting a feel of the round trip time */ static int thread_process_message_training(rdpsndPlugin * plugin, char * data, int data_size) { int wTimeStamp; int wPackSize; int size; char * out_data; uint32 error; wTimeStamp = GET_UINT16(data, 0); wPackSize = GET_UINT16(data, 2); if (wPackSize != 0) { if ((wPackSize - 4) != data_size) { LLOGLN(0, ("thread_process_message_training: size error " "wPackSize %d data_size %d", wPackSize, data_size)); return 1; } } size = 8; out_data = (char *) malloc(size); SET_UINT8(out_data, 0, SNDC_TRAINING); SET_UINT8(out_data, 1, 0); SET_UINT16(out_data, 2, size - 4); SET_UINT16(out_data, 4, wTimeStamp); SET_UINT16(out_data, 6, wPackSize); error = plugin->ep.pVirtualChannelWrite(plugin->open_handle, out_data, size, out_data); if (error != CHANNEL_RC_OK) { LLOGLN(0, ("thread_process_message_training: VirtualChannelWrite " "failed %d", error)); return 1; } return 0; }
Std_ReturnType Xcp_CmdProgramStart(uint8 pid, void* data, int len) { DEBUG(DEBUG_HIGH, "Received program_start\n"); FIFO_GET_WRITE(Xcp_FifoTx, e) { SET_UINT8 (e->data, 0, XCP_PID_RES); SET_UINT8 (e->data, 1, 0); /* RESERVED */ SET_UINT8 (e->data, 2, (!!XCP_FEATURE_BLOCKMODE) << 0 /* MASTER_BLOCK_MODE */ | 0 << 1 /* INTERLEAVED_MODE */ | (!!XCP_FEATURE_BLOCKMODE) << 6 /* SLAVE_BLOCK_MODE */); SET_UINT8 (e->data, 3, XCP_MAX_CTO); /* MAX_CTO_PGM */ SET_UINT8 (e->data, 4, XCP_MAX_RXTX_QUEUE-1); /* MAX_BS_PGM */ SET_UINT8 (e->data, 5, 0); /* MIN_ST_PGM [100 microseconds] */ SET_UINT8 (e->data, 6, XCP_MAX_RXTX_QUEUE-1); /* QUEUE_SIZE_PGM */ e->len = 7; }
static int process_CREATE_REQUEST_PDU(drdynvcPlugin * plugin, int Sp, int cbChId, char * data, int data_size) { int pos; int error; int size; char * out_data; uint32 ChannelId; pos = 1; ChannelId = get_variable_uint(cbChId, data, &pos); LLOGLN(10, ("process_CREATE_REQUEST_PDU: ChannelId=%d ChannelName=%s", ChannelId, data + pos)); size = pos + 4; out_data = (char *) malloc(size); SET_UINT8(out_data, 0, 0x10 | cbChId); memcpy(out_data + 1, data + 1, pos - 1); error = dvcman_create_channel(plugin->channel_mgr, ChannelId, data + pos); if (error == 0) { LLOGLN(10, ("process_CREATE_REQUEST_PDU: channel created")); SET_UINT32(out_data, pos, 0); } else { LLOGLN(10, ("process_CREATE_REQUEST_PDU: no listener")); SET_UINT32(out_data, pos, (uint32)(-1)); } hexdump(out_data, size); error = plugin->ep.pVirtualChannelWrite(plugin->open_handle, out_data, size, out_data); if (error != CHANNEL_RC_OK) { LLOGLN(0, ("process_CREATE_REQUEST_PDU: " "VirtualChannelWrite " "failed %d", error)); return 1; } return 0; }
static int audin_receive_wave_data(char * wave_data, int size, void * user_data) { AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) user_data; int out_size; char * out_data; int error; error = audin_send_incoming_data_pdu((IWTSVirtualChannelCallback *) callback); if (error != 0) return error; out_size = size + 1; out_data = (char *) malloc(out_size); SET_UINT8(out_data, 0, MSG_SNDIN_DATA); memcpy(out_data + 1, wave_data, size); error = callback->channel->Write(callback->channel, out_size, out_data, NULL); free(out_data); return error; }
static int audin_process_version(IWTSVirtualChannelCallback * pChannelCallback, char * data, uint32 data_size) { AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback; uint32 Version; uint32 out_size; char * out_data; int error; Version = GET_UINT32(data, 0); LLOGLN(10, ("audin_process_version: Version=%d", Version)); out_size = 5; out_data = (char *) malloc(out_size); memset(out_data, 0, out_size); SET_UINT8(out_data, 0, MSG_SNDIN_VERSION); SET_UINT32(out_data, 1, Version); error = callback->channel->Write(callback->channel, out_size, out_data, NULL); free(out_data); return error; }
static uint32 serial_control(IRP * irp) { int flush_mask, purge_mask; uint32 result, modemstate; uint8 immediate; int size = 0, ret = RD_STATUS_SUCCESS; SERIAL_DEVICE_INFO *info = (SERIAL_DEVICE_INFO *) irp->dev->info; char *inbuf = irp->inputBuffer; char *outbuf = NULL; /* the server commands, we obbey */ switch (irp->ioControlCode) { case IOCTL_SERIAL_SET_BAUD_RATE: info->baud_rate = GET_UINT32(inbuf, 0); set_termios(info); LLOGLN(10, ("serial_ioctl -> SERIAL_SET_BAUD_RATE %d", info->baud_rate)); break; case IOCTL_SERIAL_GET_BAUD_RATE: size = 4; outbuf = malloc(size); SET_UINT32(outbuf, 0, info->baud_rate); LLOGLN(10, ("serial_ioctl -> SERIAL_GET_BAUD_RATE %d", info->baud_rate)); break; case IOCTL_SERIAL_SET_QUEUE_SIZE: info->queue_in_size = GET_UINT32(inbuf, 0); info->queue_out_size = GET_UINT32(inbuf, 4); LLOGLN(10, ("serial_ioctl -> SERIAL_SET_QUEUE_SIZE in %d out %d", info->queue_in_size, info->queue_out_size)); break; case IOCTL_SERIAL_SET_LINE_CONTROL: info->stop_bits = GET_UINT8(inbuf, 0); info->parity = GET_UINT8(inbuf, 1); info->word_length = GET_UINT8(inbuf, 2); set_termios(info); LLOGLN(10, ("serial_ioctl -> SERIAL_SET_LINE_CONTROL stop %d parity %d word %d", info->stop_bits, info->parity, info->word_length)); break; case IOCTL_SERIAL_GET_LINE_CONTROL: LLOGLN(10, ("serial_ioctl -> SERIAL_GET_LINE_CONTROL")); size = 3; outbuf = malloc(size); SET_UINT8(outbuf, 0, info->stop_bits); SET_UINT8(outbuf, 1, info->parity); SET_UINT8(outbuf, 2, info->word_length); break; case IOCTL_SERIAL_IMMEDIATE_CHAR: LLOGLN(10, ("serial_ioctl -> SERIAL_IMMEDIATE_CHAR")); immediate = GET_UINT8(inbuf, 0); serial_write_data(irp, &immediate, 1); break; case IOCTL_SERIAL_CONFIG_SIZE: LLOGLN(10, ("serial_ioctl -> SERIAL_CONFIG_SIZE")); size = 4; outbuf = malloc(size); SET_UINT32(outbuf, 0, 0); break; case IOCTL_SERIAL_GET_CHARS: LLOGLN(10, ("serial_ioctl -> SERIAL_GET_CHARS")); size = 6; outbuf = malloc(size); memcpy(outbuf, info->chars, size); break; case IOCTL_SERIAL_SET_CHARS: LLOGLN(10, ("serial_ioctl -> SERIAL_SET_CHARS")); memcpy(info->chars, inbuf, 6); set_termios(info); break; case IOCTL_SERIAL_GET_HANDFLOW: LLOGLN(10, ("serial_ioctl -> IOCTL_SERIAL_GET_HANDFLOW")); size = 16; outbuf = malloc(size); get_termios(info); SET_UINT32(outbuf, 0, info->control); SET_UINT32(outbuf, 4, info->xonoff); SET_UINT32(outbuf, 8, info->onlimit); SET_UINT32(outbuf, 12, info->offlimit); break; case IOCTL_SERIAL_SET_HANDFLOW: info->control = GET_UINT32(inbuf, 0); info->xonoff = GET_UINT32(inbuf, 4); info->onlimit = GET_UINT32(inbuf, 8); info->offlimit = GET_UINT32(inbuf, 12); LLOGLN(10, ("serial_ioctl -> IOCTL_SERIAL_SET_HANDFLOW %x %x %x %x", info->control, info->xonoff, info->onlimit, info->onlimit)); set_termios(info); break; case IOCTL_SERIAL_SET_TIMEOUTS: info->read_interval_timeout = GET_UINT32(inbuf, 0); info->read_total_timeout_multiplier = GET_UINT32(inbuf, 4); info->read_total_timeout_constant = GET_UINT32(inbuf, 8); info->write_total_timeout_multiplier = GET_UINT32(inbuf, 12); info->write_total_timeout_constant = GET_UINT32(inbuf, 16); /* http://www.codeproject.com/KB/system/chaiyasit_t.aspx, see 'ReadIntervalTimeout' section http://msdn.microsoft.com/en-us/library/ms885171.aspx */ if (info->read_interval_timeout == SERIAL_TIMEOUT_MAX) { info->read_interval_timeout = 0; info->read_total_timeout_multiplier = 0; } LLOGLN(10, ("serial_ioctl -> SERIAL_SET_TIMEOUTS read timeout %d %d %d", info->read_interval_timeout, info->read_total_timeout_multiplier, info->read_total_timeout_constant)); break; case IOCTL_SERIAL_GET_TIMEOUTS: LLOGLN(10, ("serial_ioctl -> SERIAL_GET_TIMEOUTS read timeout %d %d %d", info->read_interval_timeout, info->read_total_timeout_multiplier, info->read_total_timeout_constant)); size = 20; outbuf = malloc(size); SET_UINT32(outbuf, 0, info->read_interval_timeout); SET_UINT32(outbuf, 4, info->read_total_timeout_multiplier); SET_UINT32(outbuf, 8, info->read_total_timeout_constant); SET_UINT32(outbuf, 12, info->write_total_timeout_multiplier); SET_UINT32(outbuf, 16, info->write_total_timeout_constant); break; case IOCTL_SERIAL_GET_WAIT_MASK: LLOGLN(10, ("serial_ioctl -> SERIAL_GET_WAIT_MASK %X", info->wait_mask)); size = 4; outbuf = malloc(size); SET_UINT32(outbuf, 0, info->wait_mask); break; case IOCTL_SERIAL_SET_WAIT_MASK: info->wait_mask = GET_UINT32(inbuf, 0); LLOGLN(10, ("serial_ioctl -> SERIAL_SET_WAIT_MASK %X", info->wait_mask)); break; case IOCTL_SERIAL_SET_DTR: LLOGLN(10, ("serial_ioctl -> SERIAL_SET_DTR")); ioctl(info->file, TIOCMGET, &result); result |= TIOCM_DTR; ioctl(info->file, TIOCMSET, &result); info->dtr = 1; break; case IOCTL_SERIAL_CLR_DTR: LLOGLN(10, ("serial_ioctl -> SERIAL_CLR_DTR")); ioctl(info->file, TIOCMGET, &result); result &= ~TIOCM_DTR; ioctl(info->file, TIOCMSET, &result); info->dtr = 0; break; case IOCTL_SERIAL_SET_RTS: LLOGLN(10, ("serial_ioctl -> SERIAL_SET_RTS")); ioctl(info->file, TIOCMGET, &result); result |= TIOCM_RTS; ioctl(info->file, TIOCMSET, &result); info->rts = 1; break; case IOCTL_SERIAL_CLR_RTS: LLOGLN(10, ("serial_ioctl -> SERIAL_CLR_RTS")); ioctl(info->file, TIOCMGET, &result); result &= ~TIOCM_RTS; ioctl(info->file, TIOCMSET, &result); info->rts = 0; break; case IOCTL_SERIAL_GET_MODEMSTATUS: modemstate = 0; #ifdef TIOCMGET ioctl(info->file, TIOCMGET, &result); if (result & TIOCM_CTS) modemstate |= SERIAL_MS_CTS; if (result & TIOCM_DSR) modemstate |= SERIAL_MS_DSR; if (result & TIOCM_RNG) modemstate |= SERIAL_MS_RNG; if (result & TIOCM_CAR) modemstate |= SERIAL_MS_CAR; if (result & TIOCM_DTR) modemstate |= SERIAL_MS_DTR; if (result & TIOCM_RTS) modemstate |= SERIAL_MS_RTS; #endif LLOGLN(10, ("serial_ioctl -> SERIAL_GET_MODEMSTATUS %X", modemstate)); size = 4; outbuf = malloc(size); SET_UINT32(outbuf, 0, modemstate); break; case IOCTL_SERIAL_GET_COMMSTATUS: size = 18; outbuf = malloc(size); SET_UINT32(outbuf, 0, 0); /* Errors */ SET_UINT32(outbuf, 4, 0); /* Hold reasons */ result = 0; #ifdef TIOCINQ ioctl(info->file, TIOCINQ, &result); #endif SET_UINT32(outbuf, 8, result); /* Amount in in queue */ if (result) LLOGLN(10, ("serial_ioctl -> SERIAL_GET_COMMSTATUS in queue %d", result)); result = 0; #ifdef TIOCOUTQ ioctl(info->file, TIOCOUTQ, &result); #endif SET_UINT32(outbuf, 12, result); /* Amount in out queue */ LLOGLN(10, ("serial_ioctl -> SERIAL_GET_COMMSTATUS out queue %d", result)); SET_UINT8(outbuf, 16, 0); /* EofReceived */ SET_UINT8(outbuf, 17, 0); /* WaitForImmediate */ break; case IOCTL_SERIAL_PURGE: purge_mask = GET_UINT32(inbuf, 0); LLOGLN(10, ("serial_ioctl -> SERIAL_PURGE purge_mask %X", purge_mask)); flush_mask = 0; if (purge_mask & SERIAL_PURGE_TXCLEAR) flush_mask |= TCOFLUSH; if (purge_mask & SERIAL_PURGE_RXCLEAR) flush_mask |= TCIFLUSH; if (flush_mask != 0) tcflush(info->file, flush_mask); if (purge_mask & SERIAL_PURGE_TXABORT) irp->abortIO |= RDPDR_ABORT_IO_WRITE; if(purge_mask & SERIAL_PURGE_RXABORT) irp->abortIO |= RDPDR_ABORT_IO_READ; break; case IOCTL_SERIAL_WAIT_ON_MASK: LLOGLN(10, ("serial_ioctl -> SERIAL_WAIT_ON_MASK %X", info->wait_mask)); info->event_pending = 1; if (serial_get_event(irp, &result)) { size = 4; outbuf = malloc(size); LLOGLN(10, ("WAIT end event = %x", result)); SET_UINT32(outbuf, 0, result); break; } irp->outputBufferLength = 4; ret = RD_STATUS_PENDING; break; case IOCTL_SERIAL_SET_BREAK_ON: LLOGLN(10, ("serial_ioctl -> SERIAL_SET_BREAK_ON")); tcsendbreak(info->file, 0); break; case IOCTL_SERIAL_RESET_DEVICE: LLOGLN(10, ("serial_ioctl -> SERIAL_RESET_DEVICE")); break; case IOCTL_SERIAL_SET_BREAK_OFF: LLOGLN(10, ("serial_ioctl -> SERIAL_SET_BREAK_OFF")); break; case IOCTL_SERIAL_SET_XOFF: LLOGLN(10, ("serial_ioctl -> SERIAL_SET_XOFF")); break; case IOCTL_SERIAL_SET_XON: LLOGLN(10, ("serial_ioctl -> SERIAL_SET_XON")); tcflow(info->file, TCION); break; default: LLOGLN(10, ("NOT FOUND IoControlCode SERIAL IOCTL %d", irp->ioControlCode)); return RD_STATUS_INVALID_PARAMETER; } irp->outputBuffer = outbuf; irp->outputBufferLength = size; return ret; }
/* called by worker thread receives a list of server supported formats and returns a list of client supported formats */ static int thread_process_message_formats(rdpsndPlugin * plugin, char * data, int data_size) { int index; int format_count; int out_format_count; int out_format_size; int size; int flags; int version; char * ldata; char * out_data; char * out_formats; char * lout_formats; uint32 error; /* skip: dwFlags (4 bytes), dwVolume (4 bytes), dwPitch (4 bytes), wDGramPort (2 bytes) */ format_count = GET_UINT16(data, 14); /* wNumberOfFormats */ if ((format_count < 1) || (format_count > 1000)) { LLOGLN(0, ("thread_process_message_formats: bad format_count %d", format_count)); return 1; } plugin->cBlockNo = GET_UINT8(data, 16); /* cLastBlockConfirmed */ version = GET_UINT16(data, 17); /* wVersion */ if (version < 2) { LLOGLN(0, ("thread_process_message_formats: warning, old server")); } LLOGLN(0, ("thread_process_message_formats: version %d", version)); /* skip: bPad (1 byte) */ /* setup output buffer */ size = 32 + data_size; out_data = (char *) malloc(size); out_formats = out_data + 24; lout_formats = out_formats; /* remainder is sndFormats (variable) */ ldata = data + 20; out_format_count = 0; for (index = 0; index < format_count; index++) { size = 18 + GET_UINT16(ldata, 16); if (plugin->device_plugin && plugin->device_plugin->format_supported(plugin->device_plugin, ldata, size)) { memcpy(lout_formats, ldata, size); lout_formats += size; out_format_count++; } ldata += size; } out_format_size = (int) (lout_formats - out_formats); if ((out_format_size > 0) && (out_format_count > 0)) { plugin->supported_formats = (char *) malloc(out_format_size); memcpy(plugin->supported_formats, out_formats, out_format_size); plugin->supported_formats_size = out_format_size; } else { LLOGLN(0, ("thread_process_message_formats: error, " "no formats supported")); } size = 24 + out_format_size; SET_UINT8(out_data, 0, SNDC_FORMATS); /* Header (4 bytes) */ SET_UINT8(out_data, 1, 0); SET_UINT16(out_data, 2, size - 4); flags = TSSNDCAPS_ALIVE | TSSNDCAPS_VOLUME; SET_UINT32(out_data, 4, flags); /* dwFlags */ SET_UINT32(out_data, 8, 0xffffffff); /* dwVolume */ SET_UINT32(out_data, 12, 0); /* dwPitch */ SET_UINT16(out_data, 16, 0); /* wDGramPort */ SET_UINT16(out_data, 18, out_format_count); /* wNumberOfFormats */ SET_UINT8(out_data, 20, 0); /* cLastBlockConfirmed */ SET_UINT16(out_data, 21, 2); /* wVersion */ SET_UINT8(out_data, 23, 0); /* bPad */ error = plugin->ep.pVirtualChannelWrite(plugin->open_handle, out_data, size, out_data); if (error != CHANNEL_RC_OK) { LLOGLN(0, ("thread_process_message_formats: " "VirtualChannelWrite " "failed %d", error)); return 1; } if (version >= 6) { size = 8; out_data = (char *) malloc(size); SET_UINT8(out_data, 0, SNDC_QUALITYMODE); /* Header (4 bytes) */ SET_UINT8(out_data, 1, 0); SET_UINT16(out_data, 2, size - 4); SET_UINT16(out_data, 4, 2); /* HIGH_QUALITY */ SET_UINT16(out_data, 6, 0); /* Reserved (2 bytes) */ error = plugin->ep.pVirtualChannelWrite(plugin->open_handle, out_data, size, out_data); if (error != CHANNEL_RC_OK) { LLOGLN(0, ("thread_process_message_formats: " "VirtualChannelWrite " "failed %d", error)); return 1; } } return 0; }
static uint32 disk_query_directory(IRP * irp, uint8 initialQuery, const char * path) { DISK_DEVICE_INFO * info; FILE_INFO * finfo; char * p; uint32 status; char * buf; int size; int len; struct dirent * pdirent; struct stat file_stat; uint32 attr; LLOGLN(10, ("disk_query_directory: class=%d id=%d init=%d path=%s", irp->infoClass, irp->fileID, initialQuery, path)); finfo = disk_get_file_info(irp->dev, irp->fileID); if (finfo == NULL || finfo->dir == NULL) { LLOGLN(0, ("disk_query_directory: invalid file id")); return RD_STATUS_INVALID_HANDLE; } info = (DISK_DEVICE_INFO *) irp->dev->info; if (initialQuery) { if (finfo->pattern) free(finfo->pattern); p = strrchr(path, '\\'); p = (p ? p + 1 : (char *)path); finfo->pattern = malloc(strlen(p) + 1); strcpy(finfo->pattern, p); rewinddir(finfo->dir); } status = RD_STATUS_SUCCESS; buf = NULL; size = 0; pdirent = readdir(finfo->dir); while (pdirent && finfo->pattern[0] && fnmatch(finfo->pattern, pdirent->d_name, 0) != 0) pdirent = readdir(finfo->dir); if (pdirent == NULL) { return RD_STATUS_NO_MORE_FILES; } memset(&file_stat, 0, sizeof(struct stat)); p = malloc(strlen(finfo->fullpath) + strlen(pdirent->d_name) + 2); sprintf(p, "%s/%s", finfo->fullpath, pdirent->d_name); if (stat(p, &file_stat) != 0) { LLOGLN(0, ("disk_query_directory: stat %s failed (%i)\n", p, errno)); } free(p); attr = get_file_attribute(pdirent->d_name, &file_stat); switch (irp->infoClass) { case FileBothDirectoryInformation: size = 93 + strlen(pdirent->d_name) * 2; buf = malloc(size); memset(buf, 0, size); SET_UINT32(buf, 0, 0); /* NextEntryOffset */ SET_UINT32(buf, 4, 0); /* FileIndex */ SET_UINT64(buf, 8, get_rdp_filetime(file_stat.st_ctime < file_stat.st_mtime ? file_stat.st_ctime : file_stat.st_mtime)); /* CreationTime */ SET_UINT64(buf, 16, get_rdp_filetime(file_stat.st_atime)); /* LastAccessTime */ SET_UINT64(buf, 24, get_rdp_filetime(file_stat.st_mtime)); /* LastWriteTime */ SET_UINT64(buf, 32, get_rdp_filetime(file_stat.st_ctime)); /* ChangeTime */ SET_UINT64(buf, 40, file_stat.st_size); /* EndOfFile */ SET_UINT64(buf, 48, file_stat.st_size); /* AllocationSize */ SET_UINT32(buf, 56, attr); /* FileAttributes */ SET_UINT32(buf, 64, 0); /* EaSize */ SET_UINT8(buf, 68, 0); /* ShortNameLength */ /* [MS-FSCC] has one byte padding here but RDP does not! */ //SET_UINT8(buf, 69, 0); /* Reserved */ /* ShortName 24 bytes */ len = freerdp_set_wstr(buf + 93, size - 93, pdirent->d_name, strlen(pdirent->d_name)); SET_UINT32(buf, 60, len); /* FileNameLength */ size = 93 + len; break; case FileFullDirectoryInformation: size = 68 + strlen(pdirent->d_name) * 2; buf = malloc(size); memset(buf, 0, size); SET_UINT32(buf, 0, 0); /* NextEntryOffset */ SET_UINT32(buf, 4, 0); /* FileIndex */ SET_UINT64(buf, 8, get_rdp_filetime(file_stat.st_ctime < file_stat.st_mtime ? file_stat.st_ctime : file_stat.st_mtime)); /* CreationTime */ SET_UINT64(buf, 16, get_rdp_filetime(file_stat.st_atime)); /* LastAccessTime */ SET_UINT64(buf, 24, get_rdp_filetime(file_stat.st_mtime)); /* LastWriteTime */ SET_UINT64(buf, 32, get_rdp_filetime(file_stat.st_ctime)); /* ChangeTime */ SET_UINT64(buf, 40, file_stat.st_size); /* EndOfFile */ SET_UINT64(buf, 48, file_stat.st_size); /* AllocationSize */ SET_UINT32(buf, 56, attr); /* FileAttributes */ SET_UINT32(buf, 64, 0); /* EaSize */ len = freerdp_set_wstr(buf + 68, size - 68, pdirent->d_name, strlen(pdirent->d_name)); SET_UINT32(buf, 60, len); /* FileNameLength */ size = 68 + len; break; default: LLOGLN(0, ("disk_query_directory: invalid info class")); status = RD_STATUS_NOT_SUPPORTED; break; } irp->outputBuffer = buf; irp->outputBufferLength = size; return status; }
static uint32 disk_query_info(IRP * irp) { FILE_INFO *finfo; uint32 status; int size; char * buf; LLOGLN(10, ("disk_query_info: class=%d id=%d", irp->infoClass, irp->fileID)); finfo = disk_get_file_info(irp->dev, irp->fileID); if (finfo == NULL) { LLOGLN(0, ("disk_query_info: invalid file id")); return RD_STATUS_INVALID_HANDLE; } size = 256; buf = malloc(size); memset(buf, 0, size); status = RD_STATUS_SUCCESS; switch (irp->infoClass) { case FileBasicInformation: SET_UINT64(buf, 0, get_rdp_filetime(finfo->file_stat.st_ctime < finfo->file_stat.st_mtime ? finfo->file_stat.st_ctime : finfo->file_stat.st_mtime)); /* CreationTime */ SET_UINT64(buf, 8, get_rdp_filetime(finfo->file_stat.st_atime)); /* LastAccessTime */ SET_UINT64(buf, 16, get_rdp_filetime(finfo->file_stat.st_mtime)); /* LastWriteTime */ SET_UINT64(buf, 24, get_rdp_filetime(finfo->file_stat.st_ctime)); /* ChangeTime */ SET_UINT32(buf, 32, finfo->file_attr); /* FileAttributes */ size = 36; break; case FileStandardInformation: SET_UINT64(buf, 0, finfo->file_stat.st_size); /* AllocationSize */ SET_UINT64(buf, 8, finfo->file_stat.st_size); /* EndOfFile */ SET_UINT32(buf, 16, finfo->file_stat.st_nlink); /* NumberOfLinks */ SET_UINT8(buf, 20, 0); /* DeletePending */ SET_UINT8(buf, 21, finfo->is_dir); /* Directory */ size = 22; break; case FileObjectIdInformation: SET_UINT32(buf, 0, finfo->file_attr); /* FileAttributes */ SET_UINT32(buf, 4, 0); /* ReparseTag */ size = 8; break; default: LLOGLN(0, ("disk_query_info: invalid info class")); size = 0; status = RD_STATUS_NOT_SUPPORTED; break; } irp->outputBuffer = buf; irp->outputBufferLength = size; return status; }
int drdynvc_write_data(drdynvcPlugin * plugin, uint32 ChannelId, char * data, uint32 data_size) { uint32 pos; uint32 t; int cbChId; int cbLen; char * out_data = NULL; int error; uint32 data_pos; LLOGLN(10, ("drdynvc_write_data: ChannelId=%d size=%d", ChannelId, data_size)); out_data = (char *) malloc(CHANNEL_CHUNK_LENGTH); memset(out_data, 0, CHANNEL_CHUNK_LENGTH); pos = 1; cbChId = set_variable_uint(ChannelId, out_data, &pos); if (data_size <= CHANNEL_CHUNK_LENGTH - pos) { SET_UINT8(out_data, 0, 0x30 | cbChId); memcpy(out_data + pos, data, data_size); hexdump(out_data, data_size + pos); error = plugin->ep.pVirtualChannelWrite(plugin->open_handle, out_data, data_size + pos, out_data); } else { /* Fragment the data */ cbLen = set_variable_uint(data_size, out_data, &pos); SET_UINT8(out_data, 0, 0x20 | cbChId | (cbLen << 2)); data_pos = CHANNEL_CHUNK_LENGTH - pos; memcpy(out_data + pos, data, data_pos); hexdump(out_data, CHANNEL_CHUNK_LENGTH); error = plugin->ep.pVirtualChannelWrite(plugin->open_handle, out_data, CHANNEL_CHUNK_LENGTH, out_data); while (error == CHANNEL_RC_OK && data_pos < data_size) { out_data = (char *) malloc(CHANNEL_CHUNK_LENGTH); memset(out_data, 0, CHANNEL_CHUNK_LENGTH); pos = 1; cbChId = set_variable_uint(ChannelId, out_data, &pos); SET_UINT8(out_data, 0, 0x30 | cbChId); t = data_size - data_pos; if (t > CHANNEL_CHUNK_LENGTH - pos) t = CHANNEL_CHUNK_LENGTH - pos; memcpy(out_data + pos, data + data_pos, t); data_pos += t; hexdump(out_data, t + pos); error = plugin->ep.pVirtualChannelWrite(plugin->open_handle, out_data, t + pos, out_data); } } if (error != CHANNEL_RC_OK) { if (out_data) free(out_data); LLOGLN(0, ("drdynvc_write_data: " "VirtualChannelWrite " "failed %d", error)); return 1; } return 0; }
static int audin_process_formats(IWTSVirtualChannelCallback * pChannelCallback, char * data, uint32 data_size) { AUDIN_CHANNEL_CALLBACK * callback = (AUDIN_CHANNEL_CALLBACK *) pChannelCallback; uint32 NumFormats; uint32 i; int size; int out_size; char * ldata; char * out_data; char * lout_formats; int out_format_count; int error; NumFormats = GET_UINT32(data, 0); if ((NumFormats < 1) || (NumFormats > 1000)) { LLOGLN(0, ("audin_process_formats: bad NumFormats %d", NumFormats)); return 1; } /* Ignore cbSizeFormatsPacket */ size = sizeof(char *) * (NumFormats + 1); callback->formats_data = (char **) malloc(size); memset(callback->formats_data, 0, size); out_size = data_size + 1; out_data = (char *) malloc(out_size); memset(out_data, 0, out_size); lout_formats = out_data + 9; /* remainder is sndFormats (variable) */ ldata = data + 8; out_format_count = 0; for (i = 0; i < NumFormats; i++) { size = 18 + GET_UINT16(ldata, 16); if (wave_in_format_supported(callback->device_data, ldata, size)) { /* Store the agreed format in the corresponding index */ callback->formats_data[out_format_count] = (char *) malloc(size); memcpy(callback->formats_data[out_format_count], ldata, size); /* Put the format to output buffer */ memcpy(lout_formats, ldata, size); lout_formats += size; out_format_count++; } ldata += size; } callback->formats_count = out_format_count; audin_send_incoming_data_pdu(pChannelCallback); /* cbSizeFormatsPacket: the size of the entire PDU minus the size of ExtraData */ size = lout_formats - out_data; SET_UINT8(out_data, 0, MSG_SNDIN_FORMATS); SET_UINT32(out_data, 1, out_format_count); SET_UINT32(out_data, 5, size); error = callback->channel->Write(callback->channel, size, out_data, NULL); free(out_data); return error; }
int msg_parse_in(Logger *log, MSIMessage *dest, const uint8_t *data, uint16_t length) { /* Parse raw data received from socket into MSIMessage struct */ #define CHECK_SIZE(bytes, constraint, size) \ if ((constraint -= (2 + size)) < 1) { LOGGER_ERROR(log, "Read over length!"); return -1; } \ if (bytes[1] != size) { LOGGER_ERROR(log, "Invalid data size!"); return -1; } #define CHECK_ENUM_HIGH(bytes, enum_high) /* Assumes size == 1 */ \ if (bytes[2] > enum_high) { LOGGER_ERROR(log, "Failed enum high limit!"); return -1; } #define SET_UINT8(type, bytes, header) do { \ header.value = (type)bytes[2]; \ header.exists = true; \ bytes += 3; \ } while(0) #define SET_UINT16(bytes, header) do { \ memcpy(&header.value, bytes + 2, 2);\ header.exists = true; \ bytes += 4; \ } while(0) assert(dest); if (length == 0 || data[length - 1]) { /* End byte must have value 0 */ LOGGER_ERROR(log, "Invalid end byte"); return -1; } memset(dest, 0, sizeof(*dest)); const uint8_t *it = data; int size_constraint = length; while (*it) {/* until end byte is hit */ switch (*it) { case IDRequest: CHECK_SIZE(it, size_constraint, 1); CHECK_ENUM_HIGH(it, requ_pop); SET_UINT8(MSIRequest, it, dest->request); break; case IDError: CHECK_SIZE(it, size_constraint, 1); CHECK_ENUM_HIGH(it, msi_EUndisclosed); SET_UINT8(MSIError, it, dest->error); break; case IDCapabilities: CHECK_SIZE(it, size_constraint, 1); SET_UINT8(uint8_t, it, dest->capabilities); break; default: LOGGER_ERROR(log, "Invalid id byte"); return -1; } } if (dest->request.exists == false) { LOGGER_ERROR(log, "Invalid request field!"); return -1; } return 0; #undef CHECK_SIZE #undef CHECK_ENUM_HIGH #undef SET_UINT8 #undef SET_UINT16 }
static uint32 disk_query_volume_info(IRP * irp) { FILE_INFO * finfo; struct STATFS_T stat_fs; uint32 status; int size; char * buf; int len; LLOGLN(10, ("disk_query_volume_info: class=%d id=%d", irp->infoClass, irp->fileID)); finfo = disk_get_file_info(irp->dev, irp->fileID); if (finfo == NULL) { LLOGLN(0, ("disk_query_volume_info: invalid file id")); return RD_STATUS_INVALID_HANDLE; } if (STATFS_FN(finfo->fullpath, &stat_fs) != 0) { LLOGLN(0, ("disk_query_volume_info: statfs failed")); return RD_STATUS_ACCESS_DENIED; } size = 0; buf = NULL; status = RD_STATUS_SUCCESS; switch (irp->infoClass) { case FileFsVolumeInformation: buf = malloc(256); memset(buf, 0, 256); SET_UINT64(buf, 0, 0); /* VolumeCreationTime */ SET_UINT32(buf, 8, 0); /* VolumeSerialNumber */ len = freerdp_set_wstr(buf + 17, size - 17, "FREERDP", strlen("FREERDP") + 1); SET_UINT32(buf, 12, len); /* VolumeLabelLength */ SET_UINT8(buf, 16, 0); /* SupportsObjects */ size = 17 + len; break; case FileFsSizeInformation: size = 24; buf = malloc(size); memset(buf, 0, size); SET_UINT64(buf, 0, stat_fs.f_blocks); /* TotalAllocationUnits */ SET_UINT64(buf, 8, stat_fs.f_bfree); /* AvailableAllocationUnits */ SET_UINT32(buf, 16, stat_fs.f_bsize / 0x200); /* SectorsPerAllocationUnit */ SET_UINT32(buf, 20, 0x200); /* BytesPerSector */ break; case FileFsAttributeInformation: buf = malloc(256); memset(buf, 0, 256); SET_UINT32(buf, 0, FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ SET_UINT32(buf, 4, F_NAMELEN(stat_fs)); /* MaximumComponentNameLength */ len = freerdp_set_wstr(buf + 12, 256 - 12, "FREERDP", 8); SET_UINT32(buf, 8, len); /* FileSystemNameLength */ size = 12 + len; break; case FileFsFullSizeInformation: size = 32; buf = malloc(size); memset(buf, 0, size); SET_UINT64(buf, 0, stat_fs.f_blocks); /* TotalAllocationUnits */ SET_UINT64(buf, 8, stat_fs.f_bfree); /* CallerAvailableAllocationUnits */ SET_UINT64(buf, 16, stat_fs.f_bfree); /* ActualAvailableAllocationUnits */ SET_UINT32(buf, 24, stat_fs.f_bsize / 0x200); /* SectorsPerAllocationUnit */ SET_UINT32(buf, 28, 0x200); /* BytesPerSector */ break; case FileFsDeviceInformation: size = 8; buf = malloc(size); memset(buf, 0, size); SET_UINT32(buf, 0, FILE_DEVICE_DISK); /* DeviceType */ SET_UINT32(buf, 4, 0); /* BytesPerSector */ break; default: LLOGLN(0, ("disk_query_volume_info: invalid info class")); status = RD_STATUS_NOT_SUPPORTED; break; } irp->outputBuffer = buf; irp->outputBufferLength = size; return status; }