Added support for a new virtual channel, lspci, which makes it

possible for the remote RDP server to enumerate the local PCI devices.


git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@1052 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Peter Åstrand 2006-03-02 15:22:25 +00:00
parent 0a716876be
commit 7b55ece8e4
7 changed files with 173 additions and 3 deletions

View File

@ -25,7 +25,7 @@ LDVNC = @LDVNC@
VNCLINK = @VNCLINK@
SOUNDOBJ = @SOUNDOBJ@
RDPOBJ = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o
RDPOBJ = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o
X11OBJ = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o
VNCOBJ = vnc/rdp2vnc.o vnc/vnc.o vnc/xkeymap.o vnc/x11stubs.o
@ -82,7 +82,7 @@ proto:
bitmap.c cache.c channels.c cliprdr.c disk.c mppc.c ewmhints.c \
iso.c licence.c mcs.c orders.c parallel.c printer.c printercache.c \
pstcache.c rdesktop.c rdp5.c rdp.c rdpdr.c rdpsnd.c rdpsnd_oss.c \
secure.c serial.c tcp.c xclip.c xkeymap.c xwin.c >> proto.h
secure.c serial.c tcp.c xclip.c xkeymap.c xwin.c lspci.c >> proto.h
cat proto.tail >> proto.h
.PHONY: clean

View File

@ -21,7 +21,7 @@
#include "rdesktop.h"
#define MAX_CHANNELS 4
#define MAX_CHANNELS 5
#define CHANNEL_CHUNK_LENGTH 1600
#define CHANNEL_FLAG_FIRST 0x01
#define CHANNEL_FLAG_LAST 0x02

39
doc/lspci-channel.txt Normal file
View File

@ -0,0 +1,39 @@
Protocol overview
=================
The lspci virtual channel makes it possible for the remote RDP server
to enumerate the local PCI devices. The protocol on this channel is
text based and line oriented: One single line per request or
response. UNIX-style LF line breaks are used. The maximum line length
is 1023, newline included.
rdesktop acts as a server, with only one request:
LSPCI
The response is several lines with this syntax:
<class>,<vendor>,<device>,<subvendor>,<subdevice>,<revision>,<progif>
After the last line, a line with a single dot is sent.
Example:
0300,102b,0525,102b,0338,04,00
0401,8086,24d5,1028,0174,02,8f
.
Usage
=====
To enable to lspci virtual channel, run rdesktop with "-r lspci".
References
==========
http://www.microsoft.com/msj/1099/terminal/terminal.aspx
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/termserv/termserv/terminal_services_virtual_channels.asp

View File

@ -186,6 +186,11 @@ Redirects sound generated on the server to the client. "remote" only has
any effect when you connect to the console with the -0 option. (Requires
Windows XP or newer).
.TP
.BR "-r lspci"
Activates the lspci channel, which allows the server to enumerate the
clients PCI devices. See the file lspci-channel.txt in the
documentation for more information.
.TP
.BR "-0"
Attach to the console of the server (requires Windows Server 2003
or newer).

View File

@ -117,6 +117,8 @@ void hexdump(unsigned char *p, unsigned int len);
char *next_arg(char *src, char needle);
void toupper_str(char *p);
BOOL str_startswith(const char *s, const char *prefix);
BOOL str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data);
BOOL subprocess(char *const argv[], str_handle_lines_t linehandler, void *data);
char *l_to_a(long N, int base);
int load_licence(unsigned char **data);
void save_licence(unsigned char *data, int length);
@ -269,6 +271,8 @@ void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy);
void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy);
void ui_begin_update(void);
void ui_end_update(void);
/* lspci.c */
BOOL lspci_init(void);
/* *INDENT-OFF* */
#ifdef __cplusplus

View File

@ -86,6 +86,7 @@ BOOL g_hide_decorations = False;
BOOL g_use_rdp5 = True;
BOOL g_console_session = False;
BOOL g_numlock_sync = False;
BOOL lspci_enabled = False;
BOOL g_owncolmap = False;
BOOL g_ownbackstore = True; /* We can't rely on external BackingStore */
uint32 g_embed_wnd;
@ -679,6 +680,10 @@ main(int argc, char *argv[])
{
serial_enum_devices(&g_num_devices, optarg + 7);
}
else if (str_startswith(optarg, "lspci"))
{
lspci_enabled = True;
}
else if (str_startswith(optarg, "lptport"))
{
parallel_enum_devices(&g_num_devices, optarg + 7);
@ -804,6 +809,10 @@ main(int argc, char *argv[])
if (g_rdpsnd)
rdpsnd_init();
#endif
if (lspci_enabled)
lspci_init();
rdpdr_init();
while (run_count < 2 && continue_connect) /* add support for Session Directory; only reconnect once */
@ -1178,6 +1187,117 @@ str_startswith(const char *s, const char *prefix)
}
/* Split input into lines, and call linehandler for each
line. Incomplete lines are saved in the rest variable, which should
initially point to NULL. When linehandler returns False, stop and
return False. Otherwise, return True. */
BOOL
str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data)
{
char *buf, *p;
char *oldrest;
size_t inputlen;
size_t buflen;
size_t restlen = 0;
BOOL ret = True;
/* Copy data to buffer */
inputlen = strlen(input);
if (*rest)
restlen = strlen(*rest);
buflen = restlen + inputlen + 1;
buf = (char *) xmalloc(buflen);
buf[0] = '\0';
if (*rest)
STRNCPY(buf, *rest, buflen);
strncat(buf, input, inputlen);
p = buf;
while (1)
{
char *newline = strchr(p, '\n');
if (newline)
{
*newline = '\0';
if (!linehandler(p, data))
{
p = newline + 1;
ret = False;
break;
}
p = newline + 1;
}
else
{
break;
}
}
/* Save in rest */
oldrest = *rest;
restlen = buf + buflen - p;
*rest = (char *) xmalloc(restlen);
STRNCPY((*rest), p, restlen);
xfree(oldrest);
xfree(buf);
return ret;
}
/* Execute the program specified by argv. For each line in
stdout/stderr output, call linehandler. Returns false on failure. */
BOOL
subprocess(char *const argv[], str_handle_lines_t linehandler, void *data)
{
pid_t child;
int fd[2];
int n = 1;
char output[256];
char *rest = NULL;
if (pipe(fd) < 0)
{
perror("pipe");
return False;
}
if ((child = fork()) < 0)
{
perror("fork");
return False;
}
/* Child */
if (child == 0)
{
/* Close read end */
close(fd[0]);
/* Redirect stdout and stderr to pipe */
dup2(fd[1], 1);
dup2(fd[1], 2);
/* Execute */
execvp(argv[0], argv);
perror("Error executing child");
_exit(128);
}
/* Parent. Close write end. */
close(fd[1]);
while (n > 0)
{
n = read(fd[0], output, 255);
output[n] = '\0';
str_handle_lines(output, &rest, linehandler, data);
}
xfree(rest);
return True;
}
/* not all clibs got ltoa */
#define LTOA_BUFSIZE (sizeof(long) * 8 + 1)

View File

@ -264,3 +264,5 @@ typedef struct fileinfo
uint32 info_class;
}
FILEINFO;
typedef BOOL(*str_handle_lines_t) (const char *line, void *data);