Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
int dev_redir_send_drive_close_request(tui16 Component, tui16 PacketId,
                                       tui32 DeviceId,
                                       tui32 FileId,
                                       tui32 CompletionId,
                                       tui32 MajorFunction,
                                       tui32 MinorFunc,
                                       int pad_len)
{
    struct stream *s;
    int            bytes;

    xstream_new(s, 1024);

    devredir_insert_DeviceIoRequest(s, DeviceId, FileId, CompletionId,
                                    MajorFunction, MinorFunc);

    if (pad_len)
        xstream_seek(s, pad_len);

    /* send to client */
    bytes = xstream_len(s);
    send_channel_data(g_rdpdr_chan_id, s->data, bytes);

    xstream_free(s);
    log_debug("sent close request; expect CID_FILE_CLOSE");
    return 0;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
// 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);
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
void dev_redir_send_server_user_logged_on()
{
    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_USER_LOGGEDON);

    /* send to client */
    bytes = xstream_len(s);
    send_channel_data(g_rdpdr_chan_id, s->data, bytes);

    xstream_free(s);
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
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);
}
Ejemplo n.º 12
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);
}
Ejemplo n.º 13
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);
}
Ejemplo n.º 14
0
int APP_CC
dev_redir_data_in(struct stream *s, int chan_id, int chan_flags, int length,
                  int total_length)
{
    struct stream *ls;
    tui16          comp_type;
    tui16          pktID;
    tui16          minor_ver;
    int            rv = 0;

    /*
     * handle packet fragmentation
     */
    if ((chan_flags & 3) == 3)
    {
        /* all data contained in one packet */
        ls = s;
    }
    else
    {
        /* is this is the first packet? */
        if (chan_flags & 1)
            xstream_new(g_input_stream, total_length);

        xstream_copyin(g_input_stream, s->p, length);

        /* in last packet, chan_flags & 0x02 will be true */
        if ((chan_flags & 2) == 0)
            return 0;

        g_input_stream->p = g_input_stream->data;
        ls = g_input_stream;
    }

    /* read header from incoming data */
    xstream_rd_u16_le(ls, comp_type);
    xstream_rd_u16_le(ls, pktID);

    /* for now we only handle core type, not printers */
    if (comp_type != RDPDR_CTYP_CORE)
    {
        log_error("invalid component type in response; expected 0x%x got 0x%x",
                  RDPDR_CTYP_CORE, comp_type);

        rv = -1;
        goto done;
    }

    /* figure out what kind of response we have gotten */
    switch (pktID)
    {
        case PAKID_CORE_CLIENTID_CONFIRM:
            xstream_seek(ls, 2);  /* major version, we ignore it */
            xstream_rd_u16_le(ls, minor_ver);
            xstream_rd_u32_le(ls, g_clientID);

            g_client_rdp_version = minor_ver;

            switch (minor_ver)
            {
                case RDP_CLIENT_50:
                    break;

                case RDP_CLIENT_51:
                    break;

                case RDP_CLIENT_52:
                    break;

                case RDP_CLIENT_60_61:
                    break;
            }
            // LK_TODO dev_redir_send_server_clientID_confirm();
            break;

        case PAKID_CORE_CLIENT_NAME:
            /* client is telling us its computer name; do we even care? */

            /* let client know loggin was successful */
            dev_redir_send_server_user_logged_on();
            usleep(1000 * 100);

            /* let client know our capabilites */
            dev_redir_send_server_core_cap_req();

            /* send confirm clientID */
            dev_redir_send_server_clientID_confirm();
            break;

        case PAKID_CORE_CLIENT_CAPABILITY:
            dev_redir_proc_client_core_cap_resp(ls);
            break;

        case PAKID_CORE_DEVICELIST_ANNOUNCE:
            devredir_proc_client_devlist_announce_req(ls);
            break;

        case PAKID_CORE_DEVICE_IOCOMPLETION:
            dev_redir_proc_device_iocompletion(ls);
            break;

        default:
            log_error("got unknown response 0x%x", pktID);
            break;
    }

done:

    if (g_input_stream)
    {
        xstream_free(g_input_stream);
        g_input_stream = NULL;
    }

    return rv;
}
Ejemplo n.º 15
0
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
    */
}