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 dev_redir_proc_device_iocompletion(struct stream *s) { FUSE_DATA *fuse_data = NULL; IRP *irp = NULL; tui32 DeviceId; tui32 CompletionId; tui32 IoStatus; tui32 Length; stream_rd_u32_le(s, DeviceId); stream_rd_u32_le(s, CompletionId); stream_rd_u32_le(s, IoStatus); /* LK_TODO need to check for IoStatus */ log_debug("entered: IoStatus=0x%x CompletionId=%d", IoStatus, CompletionId); if ((irp = dev_redir_irp_find(CompletionId)) == NULL) { log_error("IRP with completion ID %d not found", CompletionId); return; } switch (irp->completion_type) { case CID_CREATE_DIR_REQ: log_debug("got CID_CREATE_DIR_REQ"); if (IoStatus != NT_STATUS_SUCCESS) { /* we were trying to create a request to enumerate a dir */ /* that does not exist; let FUSE know */ fuse_data = dev_redir_fuse_data_dequeue(irp); if (fuse_data) { xfuse_devredir_cb_enum_dir_done(fuse_data->data_ptr, IoStatus); free(fuse_data); } dev_redir_irp_delete(irp); return; } stream_rd_u32_le(s, irp->FileId); log_debug("got CID_CREATE_DIR_REQ IoStatus=0x%x FileId=%d", IoStatus, irp->FileId); dev_redir_send_drive_dir_request(irp, DeviceId, 1, irp->pathname); break; case CID_CREATE_OPEN_REQ: stream_rd_u32_le(s, irp->FileId); log_debug("got CID_CREATE_OPEN_REQ IoStatus=0x%x FileId=%d", IoStatus, irp->FileId); fuse_data = dev_redir_fuse_data_dequeue(irp); xfuse_devredir_cb_open_file(fuse_data->data_ptr, DeviceId, irp->FileId); if (irp->type == S_IFDIR) dev_redir_irp_delete(irp); break; case CID_READ: log_debug("got CID_READ"); stream_rd_u32_le(s, Length); fuse_data = dev_redir_fuse_data_dequeue(irp); xfuse_devredir_cb_read_file(fuse_data->data_ptr, s->p, Length); break; case CID_WRITE: log_debug("got CID_WRITE"); stream_rd_u32_le(s, Length); fuse_data = dev_redir_fuse_data_dequeue(irp); xfuse_devredir_cb_write_file(fuse_data->data_ptr, s->p, Length); break; case CID_CLOSE: log_debug("got CID_CLOSE"); log_debug("deleting irp with completion_id=%d comp_type=%d", irp->completion_id, irp->completion_type); dev_redir_irp_delete(irp); break; case CID_FILE_CLOSE: log_debug("got CID_FILE_CLOSE"); fuse_data = dev_redir_fuse_data_dequeue(irp); xfuse_devredir_cb_file_close(fuse_data->data_ptr); dev_redir_irp_delete(irp); break; case CID_DIRECTORY_CONTROL: log_debug("got CID_DIRECTORY_CONTROL"); dev_redir_proc_query_dir_response(irp, s, DeviceId, CompletionId, IoStatus); break; case CID_RMDIR_OR_FILE: log_debug("got CID_RMDIR_OR_FILE"); stream_rd_u32_le(s, irp->FileId); devredir_proc_cid_rmdir_or_file(irp, IoStatus); return; break; case CID_RMDIR_OR_FILE_RESP: log_debug("got CID_RMDIR_OR_FILE_RESP"); devredir_proc_cid_rmdir_or_file_resp(irp, IoStatus); break; case CID_RENAME_FILE: log_debug("got CID_RENAME_FILE"); stream_rd_u32_le(s, irp->FileId); devredir_proc_cid_rename_file(irp, IoStatus); return; break; case CID_RENAME_FILE_RESP: log_debug("got CID_RENAME_FILE_RESP"); devredir_proc_cid_rename_file_resp(irp, IoStatus); break; default: log_error("got unknown CompletionID: DeviceId=0x%x " "CompletionId=0x%x IoStatus=0x%x", DeviceId, CompletionId, IoStatus); break; } if (fuse_data) free(fuse_data); log_debug("exiting"); }