38 |
#include <sys/time.h> |
#include <sys/time.h> |
39 |
#include <dirent.h> /* opendir, closedir, readdir */ |
#include <dirent.h> /* opendir, closedir, readdir */ |
40 |
#include <time.h> |
#include <time.h> |
41 |
|
#include <errno.h> |
42 |
#include "rdesktop.h" |
#include "rdesktop.h" |
43 |
|
|
44 |
#define IRP_MJ_CREATE 0x00 |
#define IRP_MJ_CREATE 0x00 |
55 |
#define IRP_MN_QUERY_DIRECTORY 0x01 |
#define IRP_MN_QUERY_DIRECTORY 0x01 |
56 |
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02 |
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x02 |
57 |
|
|
58 |
extern char hostname[16]; |
extern char g_hostname[16]; |
59 |
extern DEVICE_FNS serial_fns; |
extern DEVICE_FNS serial_fns; |
60 |
extern DEVICE_FNS printer_fns; |
extern DEVICE_FNS printer_fns; |
61 |
extern DEVICE_FNS parallel_fns; |
extern DEVICE_FNS parallel_fns; |
65 |
static VCHANNEL *rdpdr_channel; |
static VCHANNEL *rdpdr_channel; |
66 |
|
|
67 |
/* If select() times out, the request for the device with handle g_min_timeout_fd is aborted */ |
/* If select() times out, the request for the device with handle g_min_timeout_fd is aborted */ |
68 |
HANDLE g_min_timeout_fd; |
NTHANDLE g_min_timeout_fd; |
69 |
uint32 g_num_devices; |
uint32 g_num_devices; |
70 |
|
|
71 |
/* Table with information about rdpdr devices */ |
/* Table with information about rdpdr devices */ |
90 |
|
|
91 |
/* Return device_id for a given handle */ |
/* Return device_id for a given handle */ |
92 |
int |
int |
93 |
get_device_index(HANDLE handle) |
get_device_index(NTHANDLE handle) |
94 |
{ |
{ |
95 |
int i; |
int i; |
96 |
for (i = 0; i < RDPDR_MAX_DEVICES; i++) |
for (i = 0; i < RDPDR_MAX_DEVICES; i++) |
113 |
} |
} |
114 |
} |
} |
115 |
|
|
116 |
BOOL |
static BOOL |
117 |
rdpdr_handle_ok(int device, int handle) |
rdpdr_handle_ok(int device, int handle) |
118 |
{ |
{ |
119 |
switch (g_rdpdr_device[device].device_type) |
switch (g_rdpdr_device[device].device_type) |
134 |
} |
} |
135 |
|
|
136 |
/* Add a new io request to the table containing pending io requests so it won't block rdesktop */ |
/* Add a new io request to the table containing pending io requests so it won't block rdesktop */ |
137 |
BOOL |
static BOOL |
138 |
add_async_iorequest(uint32 device, uint32 file, uint32 id, uint32 major, uint32 length, |
add_async_iorequest(uint32 device, uint32 file, uint32 id, uint32 major, uint32 length, |
139 |
DEVICE_FNS * fns, uint32 total_timeout, uint32 interval_timeout, uint8 * buffer, |
DEVICE_FNS * fns, uint32 total_timeout, uint32 interval_timeout, uint8 * buffer, |
140 |
uint32 offset) |
uint32 offset) |
180 |
return True; |
return True; |
181 |
} |
} |
182 |
|
|
183 |
void |
static void |
184 |
rdpdr_send_connect(void) |
rdpdr_send_connect(void) |
185 |
{ |
{ |
186 |
uint8 magic[4] = "rDCC"; |
uint8 magic[4] = "rDCC"; |
196 |
} |
} |
197 |
|
|
198 |
|
|
199 |
void |
static void |
200 |
rdpdr_send_name(void) |
rdpdr_send_name(void) |
201 |
{ |
{ |
202 |
uint8 magic[4] = "rDNC"; |
uint8 magic[4] = "rDNC"; |
205 |
|
|
206 |
if (NULL == g_rdpdr_clientname) |
if (NULL == g_rdpdr_clientname) |
207 |
{ |
{ |
208 |
g_rdpdr_clientname = hostname; |
g_rdpdr_clientname = g_hostname; |
209 |
} |
} |
210 |
hostlen = (strlen(g_rdpdr_clientname) + 1) * 2; |
hostlen = (strlen(g_rdpdr_clientname) + 1) * 2; |
211 |
|
|
221 |
} |
} |
222 |
|
|
223 |
/* Returns the size of the payload of the announce packet */ |
/* Returns the size of the payload of the announce packet */ |
224 |
int |
static int |
225 |
announcedata_size() |
announcedata_size() |
226 |
{ |
{ |
227 |
int size, i; |
int size, i; |
248 |
return size; |
return size; |
249 |
} |
} |
250 |
|
|
251 |
void |
static void |
252 |
rdpdr_send_available(void) |
rdpdr_send_available(void) |
253 |
{ |
{ |
254 |
|
|
266 |
{ |
{ |
267 |
out_uint32_le(s, g_rdpdr_device[i].device_type); |
out_uint32_le(s, g_rdpdr_device[i].device_type); |
268 |
out_uint32_le(s, i); /* RDP Device ID */ |
out_uint32_le(s, i); /* RDP Device ID */ |
269 |
|
/* Is it possible to use share names longer than 8 chars? |
270 |
|
/astrand */ |
271 |
out_uint8p(s, g_rdpdr_device[i].name, 8); |
out_uint8p(s, g_rdpdr_device[i].name, 8); |
272 |
|
|
273 |
switch (g_rdpdr_device[i].device_type) |
switch (g_rdpdr_device[i].device_type) |
308 |
channel_send(s, rdpdr_channel); |
channel_send(s, rdpdr_channel); |
309 |
} |
} |
310 |
|
|
311 |
void |
static void |
312 |
rdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, uint8 * buffer, |
rdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, uint8 * buffer, |
313 |
uint32 length) |
uint32 length) |
314 |
{ |
{ |
694 |
buffer = NULL; |
buffer = NULL; |
695 |
} |
} |
696 |
|
|
697 |
void |
static void |
698 |
rdpdr_send_clientcapabilty(void) |
rdpdr_send_clientcapabilty(void) |
699 |
{ |
{ |
700 |
uint8 magic[4] = "rDPC"; |
uint8 magic[4] = "rDPC"; |
812 |
{ |
{ |
813 |
uint32 select_timeout = 0; // Timeout value to be used for select() (in millisecons). |
uint32 select_timeout = 0; // Timeout value to be used for select() (in millisecons). |
814 |
struct async_iorequest *iorq; |
struct async_iorequest *iorq; |
815 |
|
char c; |
816 |
|
|
817 |
iorq = g_iorequest; |
iorq = g_iorequest; |
818 |
while (iorq != NULL) |
while (iorq != NULL) |
822 |
switch (iorq->major) |
switch (iorq->major) |
823 |
{ |
{ |
824 |
case IRP_MJ_READ: |
case IRP_MJ_READ: |
825 |
|
/* Is this FD valid? FDs will |
826 |
|
be invalid when |
827 |
|
reconnecting. FIXME: Real |
828 |
|
support for reconnects. */ |
829 |
|
|
830 |
|
if ((read(iorq->fd, &c, 0) != 0) && (errno == EBADF)) |
831 |
|
break; |
832 |
|
|
833 |
FD_SET(iorq->fd, rfds); |
FD_SET(iorq->fd, rfds); |
834 |
|
*n = MAX(*n, iorq->fd); |
835 |
|
|
836 |
// Check if io request timeout is smaller than current (but not 0). |
// Check if io request timeout is smaller than current (but not 0). |
837 |
if (iorq->timeout |
if (iorq->timeout |
845 |
tv->tv_usec = (select_timeout % 1000) * 1000; |
tv->tv_usec = (select_timeout % 1000) * 1000; |
846 |
*timeout = True; |
*timeout = True; |
847 |
} |
} |
848 |
|
|
849 |
break; |
break; |
850 |
|
|
851 |
case IRP_MJ_WRITE: |
case IRP_MJ_WRITE: |
852 |
|
/* FD still valid? See above. */ |
853 |
|
if ((write(iorq->fd, &c, 0) != 0) && (errno == EBADF)) |
854 |
|
break; |
855 |
|
|
856 |
FD_SET(iorq->fd, wfds); |
FD_SET(iorq->fd, wfds); |
857 |
|
*n = MAX(*n, iorq->fd); |
858 |
break; |
break; |
859 |
|
|
860 |
} |
} |
861 |
*n = MAX(*n, iorq->fd); |
|
862 |
} |
} |
863 |
|
|
864 |
iorq = iorq->next; |
iorq = iorq->next; |
940 |
/* only delete link if all data has been transfered */ |
/* only delete link if all data has been transfered */ |
941 |
/* or if result was 0 and status success - EOF */ |
/* or if result was 0 and status success - EOF */ |
942 |
if ((iorq->partial_len == iorq->length) || |
if ((iorq->partial_len == iorq->length) || |
943 |
(result == 0)) |
(g_rdpdr_device[iorq->device].device_type == |
944 |
|
DEVICE_TYPE_SERIAL) || (result == 0)) |
945 |
{ |
{ |
946 |
#if WITH_DEBUG_RDP5 |
#if WITH_DEBUG_RDP5 |
947 |
DEBUG(("RDPDR: AIO total %u bytes read of %u\n", iorq->partial_len, iorq->length)); |
DEBUG(("RDPDR: AIO total %u bytes read of %u\n", iorq->partial_len, iorq->length)); |