예제 #1
0
파일: devredir.c 프로젝트: speidy/xrdp
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;
}
예제 #2
0
파일: devredir.c 프로젝트: lxqiong/xrdp
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");
}