Exemplo n.º 1
0
void devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus)
{
    FUSE_DATA *fuse_data;

    log_debug("entered");

    fuse_data = dev_redir_fuse_data_dequeue(irp);
    if (fuse_data)
    {
        xfuse_devredir_cb_rename_file(fuse_data->data_ptr, IoStatus);
        free(fuse_data);
    }

    if (IoStatus != NT_STATUS_SUCCESS)
    {
        devredir_irp_delete(irp);
        return;
    }

    irp->completion_type = CID_CLOSE;
    dev_redir_send_drive_close_request(RDPDR_CTYP_CORE,
                                       PAKID_CORE_DEVICE_IOREQUEST,
                                       irp->DeviceId,
                                       irp->FileId,
                                       irp->CompletionId,
                                       IRP_MJ_CLOSE, 0, 32);
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
void 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 = dev_redir_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;
    }

    xstream_new(s, 1024);

    irp->completion_type = CID_RENAME_FILE_RESP;
    devredir_insert_DeviceIoRequest(s, irp->DeviceId, irp->FileId,
                                    irp->CompletionId,
                                    IRP_MJ_SET_INFORMATION, 0);

    flen = strlen(irp->gen_buf) * 2 + 2;
    sblen = 6 + flen;

    xstream_wr_u32_le(s, FileRenameInformation);
    xstream_wr_u32_le(s, sblen);     /* Length          */
    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);
    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;
}
Exemplo n.º 4
0
void dev_redir_proc_query_dir_response(IRP *irp,
                                       struct stream *s_in,
                                       tui32 DeviceId,
                                       tui32 CompletionId,
                                       tui32 IoStatus)
{
    FUSE_DATA  *fuse_data = NULL;
    XRDP_INODE *xinode    = NULL;

    tui32 Length;
    tui32 NextEntryOffset;
    tui64 CreationTime;
    tui64 LastAccessTime;
    tui64 LastWriteTime;
    tui64 ChangeTime;
    tui64 EndOfFile;
    tui32 FileAttributes;
    tui32 FileNameLength;
    tui32 status;

#ifdef USE_SHORT_NAMES_IN_DIR_LISTING
    tui32 EaSize;
    tui8  ShortNameLength;
    tui8  Reserved;
#endif

    char  filename[256];
    int   i = 0;

    stream_rd_u32_le(s_in, Length);

    if ((IoStatus == NT_STATUS_UNSUCCESSFUL) ||
        (IoStatus == STATUS_NO_MORE_FILES))
    {
        status = (IoStatus == STATUS_NO_MORE_FILES) ? 0 : IoStatus;
        fuse_data = dev_redir_fuse_data_dequeue(irp);
        xfuse_devredir_cb_enum_dir_done(fuse_data->data_ptr, status);
        irp->completion_type = CID_CLOSE;
        dev_redir_send_drive_close_request(RDPDR_CTYP_CORE,
                                           PAKID_CORE_DEVICE_IOREQUEST,
                                           DeviceId,
                                           irp->FileId,
                                           irp->completion_id,
                                           IRP_MJ_CLOSE, 0, 32);
        free(fuse_data);
        return;
    }

    /* TODO check status for errors */

    /* process FILE_DIRECTORY_INFORMATION structures */
    while (i < Length)
    {
        log_debug("processing FILE_DIRECTORY_INFORMATION structs");

        stream_rd_u32_le(s_in, NextEntryOffset);
        stream_seek(s_in, 4);  /* FileIndex */
        stream_rd_u64_le(s_in, CreationTime);
        stream_rd_u64_le(s_in, LastAccessTime);
        stream_rd_u64_le(s_in, LastWriteTime);
        stream_rd_u64_le(s_in, ChangeTime);
        stream_rd_u64_le(s_in, EndOfFile);
        stream_seek(s_in, 8);  /* AllocationSize */
        stream_rd_u32_le(s_in, FileAttributes);
        stream_rd_u32_le(s_in, FileNameLength);

#ifdef USE_SHORT_NAMES_IN_DIR_LISTING
        stream_rd_u32_le(s_in, EaSize);
        stream_rd_u8(s_in, ShortNameLength);
        stream_rd_u8(s_in, Reserved);
        stream_seek(s_in, 23);  /* ShortName in Unicode */
#endif
        devredir_cvt_from_unicode_len(filename, s_in->p, FileNameLength);

#ifdef USE_SHORT_NAMES_IN_DIR_LISTING
        i += 70 + 23 + FileNameLength;
#else
        i += 64 + FileNameLength;
#endif
        //log_debug("NextEntryOffset:   0x%x", NextEntryOffset);
        //log_debug("CreationTime:      0x%llx", CreationTime);
        //log_debug("LastAccessTime:    0x%llx", LastAccessTime);
        //log_debug("LastWriteTime:     0x%llx", LastWriteTime);
        //log_debug("ChangeTime:        0x%llx", ChangeTime);
        //log_debug("EndOfFile:         %lld", EndOfFile);
        //log_debug("FileAttributes:    0x%x", FileAttributes);
#ifdef USE_SHORT_NAMES_IN_DIR_LISTING
        //log_debug("ShortNameLength:   %d", ShortNameLength);
#endif
        //log_debug("FileNameLength:    %d", FileNameLength);
        log_debug("FileName:          %s", filename);

        if ((xinode = calloc(1, sizeof(struct xrdp_inode))) == NULL)
        {
            log_error("system out of memory");
            fuse_data = dev_redir_fuse_data_peek(irp);
            xfuse_devredir_cb_enum_dir(fuse_data->data_ptr, NULL);
            return;
        }

        strcpy(xinode->name, filename);
        xinode->size = (size_t) EndOfFile;
        xinode->mode = WINDOWS_TO_LINUX_FILE_PERM(FileAttributes);
        xinode->atime = WINDOWS_TO_LINUX_TIME(LastAccessTime);
        xinode->mtime = WINDOWS_TO_LINUX_TIME(LastWriteTime);
        xinode->ctime = WINDOWS_TO_LINUX_TIME(CreationTime);

        /* add this entry to xrdp file system */
        fuse_data = dev_redir_fuse_data_peek(irp);
        xfuse_devredir_cb_enum_dir(fuse_data->data_ptr, xinode);
    }

    dev_redir_send_drive_dir_request(irp, DeviceId, 0, NULL);
}
Exemplo n.º 5
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");
}