rdpusb.c revision dff7b61dd3fdc4026a02236298516db1d8ac6516
/** @file
*
* Remote Desktop Protocol client:
* USB Channel Process Functions
*
*/
/*
* Copyright (C) 2006-2007 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "../rdesktop.h"
#include "vrdpusb.h"
#include "USBProxyDevice.h"
#include "USBGetDevices.h"
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#define RDPUSB_REQ_OPEN (0)
#define RDPUSB_REQ_CLOSE (1)
#define RDPUSB_REQ_RESET (2)
#define RDPUSB_REQ_SET_CONFIG (3)
#define RDPUSB_REQ_CLAIM_INTERFACE (4)
#define RDPUSB_REQ_RELEASE_INTERFACE (5)
#define RDPUSB_REQ_INTERFACE_SETTING (6)
#define RDPUSB_REQ_QUEUE_URB (7)
#define RDPUSB_REQ_REAP_URB (8)
#define RDPUSB_REQ_CLEAR_HALTED_EP (9)
#define RDPUSB_REQ_CANCEL_URB (10)
#define RDPUSB_REQ_DEVICE_LIST (11)
#define RDPUSB_REQ_NEGOTIATE (12)
static VCHANNEL *rdpusb_channel;
/** Well-known locations for the Linux Usbfs virtual file system */
static const struct
{
/** Expected mount location for Usbfs */
const char *pcszRoot;
/** Expected location of the "devices" file */
const char *pcszDevices;
} g_usbfsPaths[] =
{
};
/** Location at which the USB device tree was found. NULL means not
* found. */
static const char *g_pcszDevicesRoot = NULL;
static bool g_fUseSysfs = false;
/* A device list entry */
#pragma pack (1)
typedef struct _DevListEntry
{
} DevListEntry;
#pragma pack ()
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
/** Count the USB devices in a linked list of PUSBDEVICE structures. */
{
unsigned i;
return i;
}
enum {
/** The space we set aside for the USB strings. Should always be enough,
* as a USB device contains up to 256 characters of UTF-16 string data. */
MAX_STRINGS_LEN = 1024,
/** The space we reserve for each wire format device entry */
};
/**
* Add a string to the end of a wire format device entry.
* @param pBuf the start of the buffer containing the entry
* @param iBuf the index into the buffer to add the string at
* @param pcsz the string to add - optional
* @param piString where to write back @a iBuf or zero if there is no string
* @param piNext where to write back the index where the next string may
* start
*/
{
*piString = 0;
if (!pcsz)
return;
return;
}
/** Fill in a device list entry in wire format from a PUSBDEVICE and return an
* index to where the next string should start */
{
}
/** Allocate (and return) a buffer for a device list in VRDP wire format,
* and populate from a PUSBDEVICE linked list. @a pLen takes the length of
* the new list. */
{
char *pBuf;
return pBuf;
}
/** Build a list of the usable USB devices currently connected to the client
* system using the VRDP wire protocol. The structure returned must be freed
* using free(3) when it is no longer needed; returns NULL and sets *pLen to
* zero on failure. */
static void *build_device_list (int *pLen)
{
void *pvDeviceList;
Log(("RDPUSB build_device_list"));
*pLen = 0;
if (g_pUsbDevices)
if (!g_pUsbDevices)
return NULL;
return pvDeviceList;
}
static STREAM
{
STREAM s;
return s;
}
static void
{
#ifdef RDPUSB_DEBUG
Log(("RDPUSB send:\n"));
#endif
}
static void
{
out_uint32_le(s, devid);
s_mark_end(s);
rdpusb_send(s);
}
static void
{
}
static inline int
{
{
return VRDP_USB_STATUS_DEVICE_REMOVED;
}
return VRDP_USB_STATUS_SUCCESS;
}
static PUSBPROXYDEV
{
{
}
return proxy;
}
static void
rdpusb_reap_urbs (void)
{
STREAM s;
while (proxy)
{
if (pUrb)
{
int datalen = 0;
{
}
if (datalen)
{
}
s_mark_end(s);
rdpusb_send(s);
{
/* Remove the URB from list. */
{
}
else
{
}
{
}
}
#ifdef RDPUSB_DEBUG
#endif
#ifdef RDPUSB_DEBUG
#endif
}
}
return;
}
static void
{
int rc;
#ifdef RDPUSB_DEBUG
Log(("RDPUSB recv:\n"));
#endif
in_uint32_le (s, len);
{
return;
}
switch (code)
{
case RDPUSB_REQ_OPEN:
{
in_uint32_le(s, devid);
break;
if (rc != VINF_SUCCESS)
{
}
else
{
if (g_proxies)
{
}
}
} break;
case RDPUSB_REQ_CLOSE:
{
in_uint32_le(s, devid);
if (proxy)
{
{
}
else
{
}
{
}
}
/* No reply. */
} break;
case RDPUSB_REQ_RESET:
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (rc != VINF_SUCCESS)
{
}
} break;
case RDPUSB_REQ_SET_CONFIG:
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (!rc)
{
}
} break;
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (!rc)
{
}
} break;
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (!rc)
{
}
} break;
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (!rc)
{
}
} break;
case RDPUSB_REQ_QUEUE_URB:
{
in_uint32_le(s, devid);
if (!proxy)
{
/* No reply. */
break;
}
/* Allocate a single block for URB description and data buffer */
);
if (datalen)
{
}
/* No reply required. */
if (rc)
{
{
}
}
else
{
}
} break;
case RDPUSB_REQ_REAP_URB:
{
rdpusb_reap_urbs ();
} break;
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
if (!rc)
{
}
} break;
case RDPUSB_REQ_CANCEL_URB:
{
in_uint32_le(s, devid);
if (!proxy)
{
break;
}
in_uint32_le(s, handle);
{
}
if (pUrb)
{
/* No reply required. */
/* Remove URB from list. */
{
}
else
{
}
{
}
// xfree (pUrb);
}
} break;
case RDPUSB_REQ_DEVICE_LIST:
{
int len = 0;
if (len)
{
}
else
{
out_uint16_le(s, 0);
}
s_mark_end(s);
rdpusb_send(s);
if (buf)
{
}
} break;
case RDPUSB_REQ_NEGOTIATE:
{
s_mark_end(s);
rdpusb_send(s);
} break;
default:
break;
}
}
void
{
// Log(("RDPUSB: rdpusb_add_fds: begin *n = %d\n", *n));
while (proxy)
{
if (fd != -1)
{
// Log(("RDPUSB: rdpusb_add_fds: adding %d\n", proxy->priv.File));
}
}
// Log(("RDPUSB: rdpusb_add_fds: end *n = %d\n", *n));
return;
}
void
{
unsigned found = 0;
while (proxy)
{
if (fd != -1)
{
found = 1;
found = 1;
}
}
// Log(("RDPUSB: rdpusb_check_fds: begin\n"));
if (found)
rdpusb_reap_urbs ();
// Log(("RDPUSB: rdpusb_check_fds: end\n"));
return;
}
rdpusb_init(void)
{
return (rdpusb_channel != NULL);
}
void
rdpusb_close (void)
{
while (proxy)
{
}
return;
}