a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* -*- c-basic-offset: 8 -*-
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdesktop: A Remote Desktop Protocol client.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Copyright 2004-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Copyright 2010-2014 Henrik Andersson <hean01@cendio.se> for Cendio AB
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync This program is free software: you can redistribute it and/or modify
a180a41bba1d50822df23fff0099e90b86638b89vboxsync it under the terms of the GNU General Public License as published by
a180a41bba1d50822df23fff0099e90b86638b89vboxsync the Free Software Foundation, either version 3 of the License, or
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (at your option) any later version.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync This program is distributed in the hope that it will be useful,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync but WITHOUT ANY WARRANTY; without even the implied warranty of
a180a41bba1d50822df23fff0099e90b86638b89vboxsync MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a180a41bba1d50822df23fff0099e90b86638b89vboxsync GNU General Public License for more details.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync You should have received a copy of the GNU General Public License
a180a41bba1d50822df23fff0099e90b86638b89vboxsync along with this program. If not, see <http://www.gnu.org/licenses/>.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync*/
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync/*
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * the General Public License version 2 (GPLv2) at this time for any software where
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * a choice of GPL license versions is made available with the language indicating
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * that GPLv2 or any later version may be used, or where a choice of which version
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * of the GPL is applied is otherwise unspecified.
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync */
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/*
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Here are some resources, for your IRP hacking pleasure:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync http://cvs.sourceforge.net/viewcvs.py/mingw/w32api/include/ddk/winddk.h?view=markup
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync http://win32.mvps.org/ntfs/streams.cpp
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync http://www.acc.umu.se/~bosse/ntifs.h
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync http://us1.samba.org/samba/ftp/specs/smb-nt01.txt
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync http://www.osronline.com/
a180a41bba1d50822df23fff0099e90b86638b89vboxsync*/
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#include <unistd.h>
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#include <sys/types.h>
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#include <sys/time.h>
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#include <dirent.h> /* opendir, closedir, readdir */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#include <time.h>
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#include <errno.h>
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#include "rdesktop.h"
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MJ_CREATE 0x00
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MJ_CLOSE 0x02
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MJ_READ 0x03
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MJ_WRITE 0x04
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MJ_QUERY_INFORMATION 0x05
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MJ_SET_INFORMATION 0x06
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MJ_DIRECTORY_CONTROL 0x0c
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MJ_DEVICE_CONTROL 0x0e
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MJ_LOCK_CONTROL 0x11
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MN_QUERY_DIRECTORY 0x01
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncextern char g_hostname[16];
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncextern DEVICE_FNS serial_fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncextern DEVICE_FNS printer_fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncextern DEVICE_FNS parallel_fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncextern DEVICE_FNS disk_fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#ifdef WITH_SCARD
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncextern DEVICE_FNS scard_fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncextern FILEINFO g_fileinfo[];
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncextern RD_BOOL g_notify_stamp;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic VCHANNEL *rdpdr_channel;
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic uint32 g_epoch;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* If select() times out, the request for the device with handle g_min_timeout_fd is aborted */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncRD_NTHANDLE g_min_timeout_fd;
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncuint32 g_num_devices;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncuint32 g_client_id;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Table with information about rdpdr devices */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncRDPDR_DEVICE g_rdpdr_device[RDPDR_MAX_DEVICES];
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncchar *g_rdpdr_clientname = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Used to store incoming io request, until they are ready to be completed */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* using a linked list ensures that they are processed in the right order, */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* if multiple ios are being done on the same fd */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstruct async_iorequest
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 fd, major, minor, offset, device, id, length, partial_len;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync long timeout, /* Total timeout */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync itv_timeout; /* Interval timeout (between serial characters) */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 *buffer;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEVICE_FNS *fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync struct async_iorequest *next; /* next element in list */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync};
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstruct async_iorequest *g_iorequest;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Return device_id for a given handle */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncint
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncget_device_index(RD_NTHANDLE handle)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int i;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync for (i = 0; i < RDPDR_MAX_DEVICES; i++)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_rdpdr_device[i].handle == handle)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return i;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return -1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Converts a windows path to a unix path */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncvoid
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncconvert_to_unix_filename(char *filename)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync char *p;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while ((p = strchr(filename, '\\')))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync *p = '/';
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic RD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_handle_ok(int device, int handle)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (g_rdpdr_device[device].device_type)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case DEVICE_TYPE_PARALLEL:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case DEVICE_TYPE_SERIAL:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case DEVICE_TYPE_PRINTER:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case DEVICE_TYPE_SCARD:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_rdpdr_device[device].handle != handle)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case DEVICE_TYPE_DISK:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_fileinfo[handle].device_id != device)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Add a new io request to the table containing pending io requests so it won't block rdesktop */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic RD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncadd_async_iorequest(uint32 device, uint32 file, uint32 id, uint32 major, uint32 length,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEVICE_FNS * fns, uint32 total_timeout, uint32 interval_timeout, uint8 * buffer,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 offset)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync struct async_iorequest *iorq;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_iorequest == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_iorequest = (struct async_iorequest *) xmalloc(sizeof(struct async_iorequest));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!g_iorequest)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_iorequest->fd = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_iorequest->next = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = g_iorequest;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (iorq->fd != 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* create new element if needed */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iorq->next == NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->next =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (struct async_iorequest *) xmalloc(sizeof(struct async_iorequest));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!iorq->next)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->next->fd = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->next->next = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = iorq->next;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->device = device;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->fd = file;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->id = id;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->major = major;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->length = length;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->partial_len = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->fns = fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->timeout = total_timeout;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->itv_timeout = interval_timeout;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->buffer = buffer;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->offset = offset;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic void
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_send_client_announce_reply(void)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* DR_CORE_CLIENT_ANNOUNCE_RSP */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync STREAM s;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s = channel_init(rdpdr_channel, 12);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, RDPDR_CTYP_CORE);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, PAKID_CORE_CLIENTID_CONFIRM);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 1); /* VersionMajor, MUST be set to 0x1 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 5); /* VersionMinor */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_be(s, g_client_id); /* ClientID */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s_mark_end(s);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync channel_send(s, rdpdr_channel);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic void
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_send_client_name_request(void)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* DR_CORE_CLIENT_NAME_REQ */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync STREAM s;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 hostlen;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (NULL == g_rdpdr_clientname)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_rdpdr_clientname = g_hostname;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync hostlen = (strlen(g_rdpdr_clientname) + 1) * 2;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s = channel_init(rdpdr_channel, 16 + hostlen);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, RDPDR_CTYP_CORE);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, PAKID_CORE_CLIENT_NAME);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 1); /* UnicodeFlag */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 0); /* CodePage */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, hostlen); /* ComputerNameLen */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_out_unistr(s, g_rdpdr_clientname, hostlen - 2);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s_mark_end(s);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync channel_send(s, rdpdr_channel);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Returns the size of the payload of the announce packet */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic int
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncannouncedata_size()
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int size, i;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync PRINTER *printerinfo;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync size = 8; /* static announce size */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync size += g_num_devices * 0x14;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync for (i = 0; i < g_num_devices; i++)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_rdpdr_device[i].device_type == DEVICE_TYPE_PRINTER)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync printerinfo = (PRINTER *) g_rdpdr_device[i].pdevice_data;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync printerinfo->bloblen =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync printercache_load_blob(printerinfo->printer, &(printerinfo->blob));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync size += 0x18;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync size += 2 * strlen(printerinfo->driver) + 2;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync size += 2 * strlen(printerinfo->printer) + 2;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync size += printerinfo->bloblen;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return size;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic void
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_send_client_device_list_announce(void)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* DR_CORE_CLIENT_ANNOUNCE_RSP */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 driverlen, printerlen, bloblen;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int i;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync STREAM s;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync PRINTER *printerinfo;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s = channel_init(rdpdr_channel, announcedata_size());
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, RDPDR_CTYP_CORE);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, PAKID_CORE_DEVICE_LIST_ANNOUNCE);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, g_num_devices);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync for (i = 0; i < g_num_devices; i++)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, g_rdpdr_device[i].device_type);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, i); /* RDP Device ID */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Is it possible to use share names longer than 8 chars?
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /astrand */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint8p(s, g_rdpdr_device[i].name, 8);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (g_rdpdr_device[i].device_type)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case DEVICE_TYPE_PRINTER:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync printerinfo = (PRINTER *) g_rdpdr_device[i].pdevice_data;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync driverlen = 2 * strlen(printerinfo->driver) + 2;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync printerlen = 2 * strlen(printerinfo->printer) + 2;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bloblen = printerinfo->bloblen;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 24 + driverlen + printerlen + bloblen); /* length of extra info */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, printerinfo->default_printer ? 2 : 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint8s(s, 8); /* unknown */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, driverlen);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, printerlen);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, bloblen);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_out_unistr(s, printerinfo->driver, driverlen - 2);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_out_unistr(s, printerinfo->printer, printerlen - 2);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint8a(s, printerinfo->blob, bloblen);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (printerinfo->blob)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync xfree(printerinfo->blob); /* Blob is sent twice if reconnecting */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32(s, 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s_mark_end(s);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync channel_send(s, rdpdr_channel);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncvoid
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, uint8 * buffer,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 length)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync STREAM s;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#ifdef WITH_SCARD
a180a41bba1d50822df23fff0099e90b86638b89vboxsync scard_lock(SCARD_LOCK_RDPDR);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s = channel_init(rdpdr_channel, 20 + length);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, RDPDR_CTYP_CORE);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, PAKID_CORE_DEVICE_IOCOMPLETION);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, device);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, id);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, status);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, result);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint8p(s, buffer, length);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s_mark_end(s);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* JIF */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#ifdef WITH_DEBUG_RDP5
a180a41bba1d50822df23fff0099e90b86638b89vboxsync printf("--> rdpdr_send_completion\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8); */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync channel_send(s, rdpdr_channel);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#ifdef WITH_SCARD
a180a41bba1d50822df23fff0099e90b86638b89vboxsync scard_unlock(SCARD_LOCK_RDPDR);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic void
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_process_irp(STREAM s)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 result = 0,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync length = 0,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync desired_access = 0,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync request,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync file,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync info_level,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer_len,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync id,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync major,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync minor,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync device,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync offset,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bytes_in,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync bytes_out,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync error_mode,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync share_mode, disposition, total_timeout, interval_timeout, flags_and_attributes = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync char *filename;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 filename_len;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 *buffer, *pst_buf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync struct stream out;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEVICE_FNS *fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync RD_BOOL rw_blocking = True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync RD_NTSTATUS status = RD_STATUS_INVALID_DEVICE_REQUEST;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, device);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, file);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, id);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, major);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, minor);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync filename = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer_len = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer = (uint8 *) xmalloc(1024);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer[0] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (device >= RDPDR_MAX_DEVICES)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync error("invalid irp device 0x%lx file 0x%lx id 0x%lx major 0x%lx minor 0x%lx\n",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync device, file, id, major, minor);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync xfree(buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (g_rdpdr_device[device].device_type)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case DEVICE_TYPE_SERIAL:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fns = &serial_fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rw_blocking = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case DEVICE_TYPE_PARALLEL:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fns = &parallel_fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rw_blocking = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case DEVICE_TYPE_PRINTER:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fns = &printer_fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case DEVICE_TYPE_DISK:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fns = &disk_fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rw_blocking = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case DEVICE_TYPE_SCARD:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#ifdef WITH_SCARD
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fns = &scard_fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rw_blocking = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync error("IRP for bad device %ld\n", device);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync xfree(buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (major)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_CREATE:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_be(s, desired_access);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint8s(s, 0x08); /* unknown */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, error_mode);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, share_mode);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, disposition);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, flags_and_attributes);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, length);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (length && (length / 2) < 256)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_in_unistr(s, length, &filename, &filename_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (filename)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync convert_to_unix_filename(filename);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!fns->create)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_NOT_SUPPORTED;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync free(filename);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = fns->create(device, desired_access, share_mode, disposition,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync flags_and_attributes, filename, &result);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync free(filename);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer_len = 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_CLOSE:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!fns->close)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_NOT_SUPPORTED;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = fns->close(file);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_READ:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!fns->read)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_NOT_SUPPORTED;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, length);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, offset);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if WITH_DEBUG_RDP5
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("RDPDR IRP Read (length: %d, offset: %d)\n", length, offset));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!rdpdr_handle_ok(device, file))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_INVALID_HANDLE;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (rw_blocking) /* Complete read immediately */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer = (uint8 *) xrealloc((void *) buffer, length);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!buffer)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_CANCELLED;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = fns->read(file, buffer, length, offset, &result);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer_len = result;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Add request to table */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync pst_buf = (uint8 *) xmalloc(length);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!pst_buf)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_CANCELLED;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync serial_get_timeout(file, length, &total_timeout, &interval_timeout);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (add_async_iorequest
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (device, file, id, major, length, fns, total_timeout, interval_timeout,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync pst_buf, offset))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_PENDING;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_CANCELLED;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_WRITE:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer_len = 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!fns->write)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_NOT_SUPPORTED;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, length);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, offset);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint8s(s, 0x18);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if WITH_DEBUG_RDP5
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("RDPDR IRP Write (length: %d)\n", result));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!rdpdr_handle_ok(device, file))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_INVALID_HANDLE;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (rw_blocking) /* Complete immediately */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = fns->write(file, s->p, length, offset, &result);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Add to table */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync pst_buf = (uint8 *) xmalloc(length);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!pst_buf)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_CANCELLED;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint8a(s, pst_buf, length);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (add_async_iorequest
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (device, file, id, major, length, fns, 0, 0, pst_buf, offset))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_PENDING;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_CANCELLED;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_QUERY_INFORMATION:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_rdpdr_device[device].device_type != DEVICE_TYPE_DISK)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_INVALID_HANDLE;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, info_level);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.data = out.p = buffer;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.size = sizeof(buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = disk_query_information(file, info_level, &out);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync result = buffer_len = out.p - out.data;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_SET_INFORMATION:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_rdpdr_device[device].device_type != DEVICE_TYPE_DISK)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_INVALID_HANDLE;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, info_level);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.data = out.p = buffer;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.size = sizeof(buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = disk_set_information(file, info_level, s, &out);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync result = buffer_len = out.p - out.data;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_QUERY_VOLUME_INFORMATION:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_rdpdr_device[device].device_type != DEVICE_TYPE_DISK)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_INVALID_HANDLE;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, info_level);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.data = out.p = buffer;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.size = sizeof(buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = disk_query_volume_information(file, info_level, &out);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync result = buffer_len = out.p - out.data;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_DIRECTORY_CONTROL:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_rdpdr_device[device].device_type != DEVICE_TYPE_DISK)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_INVALID_HANDLE;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (minor)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MN_QUERY_DIRECTORY:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, info_level);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint8s(s, 1);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, length);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint8s(s, 0x17);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (length && length < 2 * 255)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_in_unistr(s, length, &filename, &filename_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (filename)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync convert_to_unix_filename(filename);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.data = out.p = buffer;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.size = sizeof(buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = disk_query_directory(file, info_level, filename,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync &out);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync result = buffer_len = out.p - out.data;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!buffer_len)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer_len++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync free(filename);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* JIF
a180a41bba1d50822df23fff0099e90b86638b89vboxsync unimpl("IRP major=0x%x minor=0x%x: IRP_MN_NOTIFY_CHANGE_DIRECTORY\n", major, minor); */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, info_level); /* notify mask */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = disk_create_notify(file, info_level);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync result = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (status == RD_STATUS_PENDING)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync add_async_iorequest(device, file, id, major, length,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fns, 0, 0, NULL, 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_INVALID_PARAMETER;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* JIF */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync unimpl("IRP major=0x%x minor=0x%x\n", major, minor);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_DEVICE_CONTROL:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!fns->device_control)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_NOT_SUPPORTED;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, bytes_out);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, bytes_in);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, request);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint8s(s, 0x14);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer = (uint8 *) xrealloc((void *) buffer, bytes_out + 0x14);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!buffer)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_CANCELLED;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.data = out.p = buffer;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.size = sizeof(buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#ifdef WITH_SCARD
a180a41bba1d50822df23fff0099e90b86638b89vboxsync scardSetInfo(g_epoch, device, id, bytes_out + 0x14);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = fns->device_control(file, request, s, &out);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync result = buffer_len = out.p - out.data;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Serial SERIAL_WAIT_ON_MASK */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (status == RD_STATUS_PENDING)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (add_async_iorequest
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (device, file, id, major, length, fns, 0, 0, NULL, 0))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_PENDING;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#ifdef WITH_SCARD
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else if (status == (RD_STATUS_PENDING | 0xC0000000))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_PENDING;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_LOCK_CONTROL:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_rdpdr_device[device].device_type != DEVICE_TYPE_DISK)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_INVALID_HANDLE;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, info_level);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.data = out.p = buffer;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.size = sizeof(buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* FIXME: Perhaps consider actually *do*
a180a41bba1d50822df23fff0099e90b86638b89vboxsync something here :-) */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_SUCCESS;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync result = buffer_len = out.p - out.data;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync unimpl("IRP major=0x%x minor=0x%x\n", major, minor);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (status != RD_STATUS_PENDING)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_send_completion(device, id, status, result, buffer, buffer_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (buffer)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync xfree(buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic void
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_send_client_capability_response(void)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* DR_CORE_CAPABILITY_RSP */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync STREAM s;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s = channel_init(rdpdr_channel, 0x50);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, RDPDR_CTYP_CORE);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, PAKID_CORE_CLIENT_CAPABILITY);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 5); /* count */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 1); /* first */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 0x28); /* length */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 1);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 2);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 2);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 5);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 1);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 5);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 0xFFFF);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 3);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 2); /* second */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 8); /* length */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 1);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 3); /* third */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 8); /* length */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 1);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 4); /* fourth */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 8); /* length */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 1);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 5); /* fifth */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 8); /* length */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 1);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s_mark_end(s);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync channel_send(s, rdpdr_channel);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic void
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_process(STREAM s)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 handle;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint16 vmin;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint16 component;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint16 pakid;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if WITH_DEBUG_RDP5
a180a41bba1d50822df23fff0099e90b86638b89vboxsync printf("--- rdpdr_process ---\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync hexdump(s->p, s->end - s->p);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint16(s, component);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint16(s, pakid);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (component == RDPDR_CTYP_CORE)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (pakid)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case PAKID_CORE_DEVICE_IOREQUEST:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_process_irp(s);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case PAKID_CORE_SERVER_ANNOUNCE:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* DR_CORE_SERVER_ANNOUNCE_REQ */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint8s(s, 2); /* skip versionMajor */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint16_le(s, vmin); /* VersionMinor */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32_le(s, g_client_id); /* ClientID */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* The RDP client is responsibility to provide a random client id
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if server version is < 12 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (vmin < 0x000c)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_client_id = 0x815ed39d; /* IP address (use 127.0.0.1) 0x815ed39d */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_epoch++;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_send_client_announce_reply();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_send_client_name_request();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case PAKID_CORE_CLIENTID_CONFIRM:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_send_client_device_list_announce();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case PAKID_CORE_DEVICE_REPLY:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint32(s, handle);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if WITH_DEBUG_RDP5
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("RDPDR: Server connected to resource %d\n", handle));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case PAKID_CORE_SERVER_CAPABILITY:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_send_client_capability_response();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync default:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync unimpl("RDPDR pakid 0x%x of component 0x%x\n", pakid, component);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else if (component == RDPDR_CTYP_PRN)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (pakid == PAKID_PRN_CACHE_DATA)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync printercache_process(s);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync unimpl("RDPDR component 0x%x\n", component);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncRD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_init()
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_channel =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync channel_register("rdpdr",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_COMPRESS_RDP,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_process);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return (rdpdr_channel != NULL);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Add file descriptors of pending io request to select() */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncvoid
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv, RD_BOOL * timeout)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 select_timeout = 0; /* Timeout value to be used for select() (in millisecons). */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync struct async_iorequest *iorq;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync char c;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = g_iorequest;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (iorq != NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iorq->fd != 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (iorq->major)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_READ:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Is this FD valid? FDs will
a180a41bba1d50822df23fff0099e90b86638b89vboxsync be invalid when
a180a41bba1d50822df23fff0099e90b86638b89vboxsync reconnecting. FIXME: Real
a180a41bba1d50822df23fff0099e90b86638b89vboxsync support for reconnects. */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync FD_SET(iorq->fd, rfds);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync *n = MAX(*n, iorq->fd);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Check if io request timeout is smaller than current (but not 0). */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iorq->timeout
a180a41bba1d50822df23fff0099e90b86638b89vboxsync && (select_timeout == 0
a180a41bba1d50822df23fff0099e90b86638b89vboxsync || iorq->timeout < select_timeout))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Set new timeout */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync select_timeout = iorq->timeout;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_min_timeout_fd = iorq->fd; /* Remember fd */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync tv->tv_sec = select_timeout / 1000;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync tv->tv_usec = (select_timeout % 1000) * 1000;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync *timeout = True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iorq->itv_timeout && iorq->partial_len > 0
a180a41bba1d50822df23fff0099e90b86638b89vboxsync && (select_timeout == 0
a180a41bba1d50822df23fff0099e90b86638b89vboxsync || iorq->itv_timeout < select_timeout))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Set new timeout */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync select_timeout = iorq->itv_timeout;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_min_timeout_fd = iorq->fd; /* Remember fd */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync tv->tv_sec = select_timeout / 1000;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync tv->tv_usec = (select_timeout % 1000) * 1000;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync *timeout = True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_WRITE:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* FD still valid? See above. */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((write(iorq->fd, &c, 0) != 0) && (errno == EBADF))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync FD_SET(iorq->fd, wfds);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync *n = MAX(*n, iorq->fd);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_DEVICE_CONTROL:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (select_timeout > 5)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync select_timeout = 5; /* serial event queue */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = iorq->next;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstruct async_iorequest *
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_remove_iorequest(struct async_iorequest *prev, struct async_iorequest *iorq)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!iorq)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iorq->buffer)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync xfree(iorq->buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (prev)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prev->next = iorq->next;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync xfree(iorq);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = prev->next;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Even if NULL */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_iorequest = iorq->next;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync xfree(iorq);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return iorq;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Check if select() returned with one of the rdpdr file descriptors, and complete io if it did */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic void
a180a41bba1d50822df23fff0099e90b86638b89vboxsync_rdpdr_check_fds(fd_set * rfds, fd_set * wfds, RD_BOOL timed_out)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync RD_NTSTATUS status;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 result = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEVICE_FNS *fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync struct async_iorequest *iorq;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync struct async_iorequest *prev;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 req_size = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 buffer_len;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync struct stream out;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint8 *buffer = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (timed_out)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* check serial iv_timeout */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = g_iorequest;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prev = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (iorq != NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iorq->fd == g_min_timeout_fd)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((iorq->partial_len > 0) &&
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (g_rdpdr_device[iorq->device].device_type ==
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEVICE_TYPE_SERIAL))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* iv_timeout between 2 chars, send partial_len */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /*printf("RDPDR: IVT total %u bytes read of %u\n", iorq->partial_len, iorq->length); */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_send_completion(iorq->device,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->id, RD_STATUS_SUCCESS,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->partial_len,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->buffer, iorq->partial_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = rdpdr_remove_iorequest(prev, iorq);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prev = iorq;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iorq)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = iorq->next;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_abort_io(g_min_timeout_fd, 0, RD_STATUS_TIMEOUT);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = g_iorequest;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prev = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (iorq != NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iorq->fd != 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (iorq->major)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_READ:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (FD_ISSET(iorq->fd, rfds))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Read the data */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fns = iorq->fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync req_size =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (iorq->length - iorq->partial_len) >
a180a41bba1d50822df23fff0099e90b86638b89vboxsync 8192 ? 8192 : (iorq->length -
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->partial_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* never read larger chunks than 8k - chances are that it will block */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = fns->read(iorq->fd,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->buffer + iorq->partial_len,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync req_size, iorq->offset, &result);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((long) result > 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->partial_len += result;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->offset += result;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if WITH_DEBUG_RDP5
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("RDPDR: %d bytes of data read\n", result));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* only delete link if all data has been transfered */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* or if result was 0 and status success - EOF */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((iorq->partial_len == iorq->length) ||
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (result == 0))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if WITH_DEBUG_RDP5
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("RDPDR: AIO total %u bytes read of %u\n", iorq->partial_len, iorq->length));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_send_completion(iorq->device,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->id, status,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->partial_len,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->buffer,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->partial_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = rdpdr_remove_iorequest(prev, iorq);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_WRITE:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (FD_ISSET(iorq->fd, wfds))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Write data. */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fns = iorq->fns;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync req_size =
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (iorq->length - iorq->partial_len) >
a180a41bba1d50822df23fff0099e90b86638b89vboxsync 8192 ? 8192 : (iorq->length -
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->partial_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* never write larger chunks than 8k - chances are that it will block */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = fns->write(iorq->fd,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->buffer +
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->partial_len, req_size,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->offset, &result);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((long) result > 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->partial_len += result;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->offset += result;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if WITH_DEBUG_RDP5
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("RDPDR: %d bytes of data written\n",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync result));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* only delete link if all data has been transfered */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* or we couldn't write */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((iorq->partial_len == iorq->length)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync || (result == 0))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if WITH_DEBUG_RDP5
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("RDPDR: AIO total %u bytes written of %u\n", iorq->partial_len, iorq->length));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_send_completion(iorq->device,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->id, status,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->partial_len,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (uint8 *) "", 1);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = rdpdr_remove_iorequest(prev, iorq);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_DEVICE_CONTROL:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (serial_get_event(iorq->fd, &result))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer = (uint8 *) xrealloc((void *) buffer, 0x14);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.data = out.p = buffer;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out.size = sizeof(buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(&out, result);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync result = buffer_len = out.p - out.data;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = RD_STATUS_SUCCESS;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_send_completion(iorq->device, iorq->id,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status, result, buffer,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync buffer_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync xfree(buffer);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = rdpdr_remove_iorequest(prev, iorq);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prev = iorq;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iorq)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = iorq->next;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Check notify */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = g_iorequest;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prev = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (iorq != NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iorq->fd != 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync switch (iorq->major)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case IRP_MJ_DIRECTORY_CONTROL:
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_rdpdr_device[iorq->device].device_type ==
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEVICE_TYPE_DISK)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_notify_stamp)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_notify_stamp = False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status = disk_check_notify(iorq->fd);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (status != RD_STATUS_PENDING)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_send_completion(iorq->device,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq->id,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync status, 0,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync NULL, 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = rdpdr_remove_iorequest(prev,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync break;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prev = iorq;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iorq)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = iorq->next;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncvoid
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_check_fds(fd_set * rfds, fd_set * wfds, RD_BOOL timed_out)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fd_set dummy;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync FD_ZERO(&dummy);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* fist check event queue only,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync any serial wait event must be done before read block will be sent
a180a41bba1d50822df23fff0099e90b86638b89vboxsync */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync _rdpdr_check_fds(&dummy, &dummy, False);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync _rdpdr_check_fds(rfds, wfds, timed_out);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Abort a pending io request for a given handle and major */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncRD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdpdr_abort_io(uint32 fd, uint32 major, RD_NTSTATUS status)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 result;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync struct async_iorequest *iorq;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync struct async_iorequest *prev;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = g_iorequest;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prev = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (iorq != NULL)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Only remove from table when major is not set, or when correct major is supplied.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Abort read should not abort a write io request. */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((iorq->fd == fd) && (major == 0 || iorq->major == major))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync result = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpdr_send_completion(iorq->device, iorq->id, status, result, (uint8 *) "",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync 1);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = rdpdr_remove_iorequest(prev, iorq);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync prev = iorq;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync iorq = iorq->next;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}