void devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus) { struct stream *s; int bytes; if (IoStatus != NT_STATUS_SUCCESS) { FUSE_DATA *fuse_data = dev_redir_fuse_data_dequeue(irp); if (fuse_data) { xfuse_devredir_cb_rmdir_or_file(fuse_data->data_ptr, IoStatus); free(fuse_data); } devredir_irp_delete(irp); return; } xstream_new(s, 1024); irp->completion_type = CID_RMDIR_OR_FILE_RESP; devredir_insert_DeviceIoRequest(s, irp->DeviceId, irp->FileId, irp->CompletionId, IRP_MJ_SET_INFORMATION, 0); xstream_wr_u32_le(s, FileDispositionInformation); xstream_wr_u32_le(s, 0); /* length is zero */ xstream_seek(s, 24); /* padding */ /* send to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); return; }
// LK_TODO Path needs to be Unicode void dev_redir_send_drive_dir_request(IRP *irp, tui32 device_id, tui32 InitialQuery, char *Path) { struct stream *s; int bytes; char upath[4096]; // LK_TODO need to malloc this int path_len = 0; /* during Initial Query, Path cannot be NULL */ if (InitialQuery) { if (Path == NULL) { return; } /* Path in unicode needs this much space */ path_len = ((g_mbstowcs(NULL, Path, 0) * sizeof(twchar)) / 2) + 2; devredir_cvt_to_unicode(upath, Path); } xstream_new(s, 1024 + path_len); irp->completion_type = CID_DIRECTORY_CONTROL; devredir_insert_DeviceIoRequest(s, device_id, irp->FileId, irp->CompletionId, IRP_MJ_DIRECTORY_CONTROL, IRP_MN_QUERY_DIRECTORY); #ifdef USE_SHORT_NAMES_IN_DIR_LISTING xstream_wr_u32_le(s, FileBothDirectoryInformation); /* FsInformationClass */ #else xstream_wr_u32_le(s, FileDirectoryInformation); /* FsInformationClass */ #endif xstream_wr_u8(s, InitialQuery); /* InitialQuery */ if (!InitialQuery) { xstream_wr_u32_le(s, 0); /* PathLength */ xstream_seek(s, 23); } else { xstream_wr_u32_le(s, path_len); /* PathLength */ xstream_seek(s, 23); /* Padding */ xstream_wr_string(s, upath, path_len); } /* send to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); }
void APP_CC devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus) { struct stream *s; int bytes; int sblen; /* SetBuffer length */ int flen; /* FileNameLength */ if (IoStatus != NT_STATUS_SUCCESS) { log_debug("rename returned with IoStatus=0x%x", IoStatus); FUSE_DATA *fuse_data = devredir_fuse_data_dequeue(irp); if (fuse_data) { xfuse_devredir_cb_rename_file(fuse_data->data_ptr, IoStatus); free(fuse_data); } devredir_irp_delete(irp); return; } /* Path in unicode needs this much space */ flen = ((g_mbstowcs(NULL, irp->gen_buf, 0) * sizeof(twchar)) / 2) + 2; sblen = 6 + flen; xstream_new(s, 1024 + flen); irp->completion_type = CID_RENAME_FILE_RESP; devredir_insert_DeviceIoRequest(s, irp->DeviceId, irp->FileId, irp->CompletionId, IRP_MJ_SET_INFORMATION, 0); xstream_wr_u32_le(s, FileRenameInformation); xstream_wr_u32_le(s, sblen); /* number of bytes after padding */ xstream_seek(s, 24); /* padding */ xstream_wr_u8(s, 1); /* ReplaceIfExists */ xstream_wr_u8(s, 0); /* RootDirectory */ xstream_wr_u32_le(s, flen); /* FileNameLength */ /* filename in unicode */ devredir_cvt_to_unicode(s->p, irp->gen_buf); /* UNICODE_TODO */ xstream_seek(s, flen); /* send to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); return; }
static struct stream * APP_CC scard_make_new_ioctl(IRP *irp, tui32 ioctl) { /* * format of device control request * * DeviceIoRequest * u16 RDPDR_CTYP_CORE * u16 PAKID_CORE_DEVICE_IOREQUEST * u32 DeviceId * u32 FileId * u32 CompletionId * u32 MajorFunction * u32 MinorFunction * * u32 OutputBufferLength SHOULD be 2048 * u32 InputBufferLength * u32 IoControlCode * 20 bytes padding * xx bytes InputBuffer (variable) */ struct stream *s; xstream_new(s, 1024 * 3); if (s == NULL) { log_error("system out of memory"); return s; } devredir_insert_DeviceIoRequest(s, irp->DeviceId, irp->FileId, irp->CompletionId, IRP_MJ_DEVICE_CONTROL, 0); xstream_wr_u32_le(s, 2048); /* OutputBufferLength */ xstream_wr_u32_le(s, 0); /* InputBufferLength - insert later */ xstream_wr_u32_le(s, ioctl); /* Ioctl Code */ xstream_seek(s, 20); /* padding */ /* [MS-RPCE] 2.2.6.1 */ xstream_wr_u32_le(s, 0x00081001); /* len 8, LE, v1 */ xstream_wr_u32_le(s, 0xcccccccc); /* filler */ return s; }
void devredir_insert_DeviceIoRequest(struct stream *s, tui32 DeviceId, tui32 FileId, tui32 CompletionId, tui32 MajorFunction, tui32 MinorFunction) { /* setup DR_DEVICE_IOREQUEST header */ xstream_wr_u16_le(s, RDPDR_CTYP_CORE); xstream_wr_u16_le(s, PAKID_CORE_DEVICE_IOREQUEST); xstream_wr_u32_le(s, DeviceId); xstream_wr_u32_le(s, FileId); xstream_wr_u32_le(s, CompletionId); xstream_wr_u32_le(s, MajorFunction); xstream_wr_u32_le(s, MinorFunction); }
int APP_CC dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId, const char *buf, int Length, tui64 Offset) { struct stream *s; IRP *irp; IRP *new_irp; int bytes; log_debug("DeviceId=%d FileId=%d Length=%d Offset=%lld", DeviceId, FileId, Length, Offset); xstream_new(s, 1024 + Length); if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL) { log_error("no IRP found with FileId = %d", FileId); xfuse_devredir_cb_write_file(fusep, NULL, 0); xstream_free(s); return -1; } /* create a new IRP for this request */ if ((new_irp = devredir_irp_clone(irp)) == NULL) { /* system out of memory */ xfuse_devredir_cb_write_file(fusep, NULL, 0); xstream_free(s); return -1; } new_irp->FileId = 0; new_irp->completion_type = CID_WRITE; new_irp->CompletionId = g_completion_id++; devredir_fuse_data_enqueue(new_irp, fusep); devredir_insert_DeviceIoRequest(s, DeviceId, FileId, new_irp->CompletionId, IRP_MJ_WRITE, 0); xstream_wr_u32_le(s, Length); xstream_wr_u64_le(s, Offset); xstream_seek(s, 20); /* padding */ /* now insert real data */ xstream_copyin(s, buf, Length); /* send to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); return 0; }
void devredir_send_server_device_announce_resp(tui32 device_id) { struct stream *s; int bytes; xstream_new(s, 1024); /* setup stream */ xstream_wr_u16_le(s, RDPDR_CTYP_CORE); xstream_wr_u16_le(s, PAKID_CORE_DEVICE_REPLY); xstream_wr_u32_le(s, device_id); xstream_wr_u32_le(s, 0); /* ResultCode */ /* send to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); }
int APP_CC devredir_file_read(void *fusep, tui32 DeviceId, tui32 FileId, tui32 Length, tui64 Offset) { struct stream *s; IRP *irp; IRP *new_irp; int bytes; xstream_new(s, 1024); if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL) { log_error("no IRP found with FileId = %d", FileId); xfuse_devredir_cb_read_file(fusep, NULL, 0); xstream_free(s); return -1; } /* create a new IRP for this request */ if ((new_irp = devredir_irp_clone(irp)) == NULL) { /* system out of memory */ xfuse_devredir_cb_read_file(fusep, NULL, 0); xstream_free(s); return -1; } new_irp->FileId = 0; new_irp->completion_type = CID_READ; new_irp->CompletionId = g_completion_id++; devredir_fuse_data_enqueue(new_irp, fusep); devredir_insert_DeviceIoRequest(s, DeviceId, FileId, new_irp->CompletionId, IRP_MJ_READ, 0); xstream_wr_u32_le(s, Length); xstream_wr_u64_le(s, Offset); xstream_seek(s, 20); /* send to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); return 0; }
static void APP_CC scard_send_EstablishContext(IRP *irp) { struct stream *s; int bytes; if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_ESTABLISH_CONTEXT)) == NULL) return; xstream_wr_u32_le(s, 0x08); /* len */ xstream_wr_u32_le(s, 0); /* unused */ xstream_wr_u32_le(s, SCARD_SCOPE_SYSTEM); /* Ioctl specific data */ xstream_wr_u32_le(s, 0); /* don't know what this is, */ /* but Win7 is sending it */ /* get stream len */ bytes = xstream_len(s); /* InputBufferLength is number of bytes AFTER 20 byte padding */ *(s->data + 28) = bytes - 56; /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); }
int dev_redir_send_drive_create_request(tui32 device_id, const char *path, tui32 DesiredAccess, tui32 CreateOptions, tui32 CreateDisposition, tui32 completion_id) { struct stream *s; int bytes; int len; log_debug("DesiredAccess=0x%x CreateDisposition=0x%x CreateOptions=0x%x", DesiredAccess, CreateDisposition, CreateOptions); /* path in unicode needs this much space */ len = ((g_mbstowcs(NULL, path, 0) * sizeof(twchar)) / 2) + 2; xstream_new(s, 1024 + len); devredir_insert_DeviceIoRequest(s, device_id, 0, completion_id, IRP_MJ_CREATE, 0); xstream_wr_u32_le(s, DesiredAccess); /* DesiredAccess */ xstream_wr_u32_le(s, 0); /* AllocationSize high unused */ xstream_wr_u32_le(s, 0); /* AllocationSize low unused */ xstream_wr_u32_le(s, 0); /* FileAttributes */ xstream_wr_u32_le(s, 3); /* SharedAccess LK_TODO */ xstream_wr_u32_le(s, CreateDisposition); /* CreateDisposition */ xstream_wr_u32_le(s, CreateOptions); /* CreateOptions */ xstream_wr_u32_le(s, len); /* PathLength */ devredir_cvt_to_unicode(s->p, path); /* path in unicode */ xstream_seek(s, len); /* send to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); return 0; }
int APP_CC dev_redir_init(void) { struct stream *s; int bytes; int fd; union _u { tui32 clientID; char buf[4]; } u; /* get a random number that will act as a unique clientID */ if ((fd = open("/dev/urandom", O_RDONLY)) != -1) { if (read(fd, u.buf, 4) != 4) { } close(fd); } else { /* /dev/urandom did not work - use address of struct s */ tui64 u64 = (tui64) (tintptr) &s; u.clientID = (tui32) u64; } /* setup stream */ xstream_new(s, 1024); /* initiate drive redirection protocol by sending Server Announce Req */ xstream_wr_u16_le(s, RDPDR_CTYP_CORE); xstream_wr_u16_le(s, PAKID_CORE_SERVER_ANNOUNCE); xstream_wr_u16_le(s, 0x0001); /* server major ver */ xstream_wr_u16_le(s, 0x000C); /* server minor ver - pretend 2 b Win 7 */ xstream_wr_u32_le(s, u.clientID); /* unique ClientID */ /* send data to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); return 0; }
void dev_redir_send_server_clientID_confirm() { struct stream *s; int bytes; xstream_new(s, 1024); /* setup stream */ xstream_wr_u16_le(s, RDPDR_CTYP_CORE); xstream_wr_u16_le(s, PAKID_CORE_CLIENTID_CONFIRM); xstream_wr_u16_le(s, 0x0001); xstream_wr_u16_le(s, g_client_rdp_version); xstream_wr_u32_le(s, g_clientID); /* send to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); }
void dev_redir_send_server_core_cap_req() { struct stream *s; int bytes; xstream_new(s, 1024); /* setup header */ xstream_wr_u16_le(s, RDPDR_CTYP_CORE); xstream_wr_u16_le(s, PAKID_CORE_SERVER_CAPABILITY); xstream_wr_u16_le(s, 5); /* num of caps we are sending */ xstream_wr_u16_le(s, 0x0000); /* padding */ /* setup general capability */ xstream_wr_u16_le(s, CAP_GENERAL_TYPE); /* CapabilityType */ xstream_wr_u16_le(s, 44); /* CapabilityLength - len of this */ /* CAPABILITY_SET in bytes, inc */ /* the header */ xstream_wr_u32_le(s, 2); /* Version */ xstream_wr_u32_le(s, 2); /* O.S type */ xstream_wr_u32_le(s, 0); /* O.S version */ xstream_wr_u16_le(s, 1); /* protocol major version */ xstream_wr_u16_le(s, g_client_rdp_version); /* protocol minor version */ xstream_wr_u32_le(s, 0xffff); /* I/O code 1 */ xstream_wr_u32_le(s, 0); /* I/O code 2 */ xstream_wr_u32_le(s, 7); /* Extended PDU */ xstream_wr_u32_le(s, 0); /* extra flags 1 */ xstream_wr_u32_le(s, 0); /* extra flags 2 */ xstream_wr_u32_le(s, 2); /* special type device cap */ /* setup printer capability */ xstream_wr_u16_le(s, CAP_PRINTER_TYPE); xstream_wr_u16_le(s, 8); xstream_wr_u32_le(s, 1); /* setup serial port capability */ xstream_wr_u16_le(s, CAP_PORT_TYPE); xstream_wr_u16_le(s, 8); xstream_wr_u32_le(s, 1); /* setup file system capability */ xstream_wr_u16_le(s, CAP_DRIVE_TYPE); /* CapabilityType */ xstream_wr_u16_le(s, 8); /* CapabilityLength - len of this */ /* CAPABILITY_SET in bytes, inc */ /* the header */ xstream_wr_u32_le(s, 2); /* Version */ /* setup smart card capability */ xstream_wr_u16_le(s, CAP_SMARTCARD_TYPE); xstream_wr_u16_le(s, 8); xstream_wr_u32_le(s, 1); /* send to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); }
static void APP_CC scard_send_ListReaders(IRP *irp, int wide) { /* see [MS-RDPESC] 2.2.2.4 */ SMARTCARD *sc; struct stream *s; int bytes; tui32 ioctl; if ((sc = smartcards[irp->scard_index]) == NULL) { log_error("smartcards[%d] is NULL", irp->scard_index); return; } ioctl = (wide > 0) ? SCARD_IOCTL_LIST_READERS_W : SCARD_IOCTL_LIST_READERS_A; if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL) return; xstream_wr_u32_le(s, 72); /* number of bytes to follow */ xstream_seek(s, 0x1c); /* freerdp does not use this */ /* insert context */ xstream_wr_u32_le(s, sc->Context_len); xstream_copyin(s, sc->Context, sc->Context_len); xstream_wr_u32_le(s, 36); /* length of mszGroups */ xstream_wr_u16_le(s, 0x0053); xstream_wr_u16_le(s, 0x0043); xstream_wr_u16_le(s, 0x0061); xstream_wr_u16_le(s, 0x0072); xstream_wr_u16_le(s, 0x0064); xstream_wr_u16_le(s, 0x0024); xstream_wr_u16_le(s, 0x0041); xstream_wr_u16_le(s, 0x006c); xstream_wr_u16_le(s, 0x006c); xstream_wr_u16_le(s, 0x0052); xstream_wr_u16_le(s, 0x0065); xstream_wr_u16_le(s, 0x0061); xstream_wr_u16_le(s, 0x0064); xstream_wr_u16_le(s, 0x0065); xstream_wr_u16_le(s, 0x0072); xstream_wr_u16_le(s, 0x0073); xstream_wr_u32_le(s, 0x00); /* get stream len */ bytes = xstream_len(s); /* InputBufferLength is number of bytes AFTER 20 byte padding */ *(s->data + 28) = bytes - 56; /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); /* scard_device_control: dumping 120 bytes of data 0000 00 08 00 00 58 00 00 00 2c 00 09 00 00 00 00 00 ....X...,....... 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 0020 01 10 08 00 cc cc cc cc 48 00 00 00 00 00 00 00 ........H....... 0030 04 00 00 00 00 00 02 00 24 00 00 00 04 00 02 00 ........$....... 0040 00 00 00 00 ff ff ff ff 04 00 00 00 84 db 03 01 ................ 0050 24 00 00 00 53 00 43 00 61 00 72 00 64 00 24 00 $...S.C.a.r.d.$. 0060 41 00 6c 00 6c 00 52 00 65 00 61 00 64 00 65 00 A.l.l.R.e.a.d.e. 0070 72 00 73 00 00 00 00 00 r.s..... scard_device_control: output_len=2048 input_len=88 ioctl_code=0x9002c */ /* scard_device_control: dumping 120 bytes of data 0000 00 08 00 00 80 00 00 00 14 00 09 00 00 00 00 00 ................ 0010 2e 2e 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................ 0020 01 10 08 00 cc cc cc cc 48 00 00 00 00 00 00 00 ........H....... 0030 02 00 00 00 00 00 00 00 72 64 00 00 00 00 00 00 ........rd...... 0040 81 27 00 00 00 00 00 00 04 00 00 00 84 b3 03 01 .'.............. 0050 24 00 00 00 53 00 43 00 61 00 72 00 64 00 24 00 $...S.C.a.r.d.$. 0060 41 00 6c 00 6c 00 52 00 65 00 61 00 64 00 65 00 A.l.l.R.e.a.d.e. 0070 72 00 73 00 00 00 00 00 r.s..... scard_device_control: output_len=2048 input_len=128 ioctl_code=0x90014 */ }