1 |
#include <unistd.h> |
#include <unistd.h> |
2 |
#include <sys/types.h> |
#include <sys/types.h> |
3 |
#include <sys/time.h> |
#include <sys/time.h> |
4 |
|
#include <dirent.h> /* opendir, closedir, readdir */ |
5 |
#include <time.h> |
#include <time.h> |
6 |
#include "rdesktop.h" |
#include "rdesktop.h" |
7 |
|
|
29 |
extern DEVICE_FNS printer_fns; |
extern DEVICE_FNS printer_fns; |
30 |
extern DEVICE_FNS parallel_fns; |
extern DEVICE_FNS parallel_fns; |
31 |
extern DEVICE_FNS disk_fns; |
extern DEVICE_FNS disk_fns; |
32 |
|
extern FILEINFO g_fileinfo[]; |
33 |
|
|
34 |
static VCHANNEL *rdpdr_channel; |
static VCHANNEL *rdpdr_channel; |
35 |
|
|
81 |
} |
} |
82 |
} |
} |
83 |
|
|
84 |
|
BOOL |
85 |
|
rdpdr_handle_ok(int device, int handle) |
86 |
|
{ |
87 |
|
switch (g_rdpdr_device[device].device_type) |
88 |
|
{ |
89 |
|
case DEVICE_TYPE_PARALLEL: |
90 |
|
case DEVICE_TYPE_SERIAL: |
91 |
|
case DEVICE_TYPE_PRINTER: |
92 |
|
case DEVICE_TYPE_SCARD: |
93 |
|
if (g_rdpdr_device[device].handle != handle) |
94 |
|
return False; |
95 |
|
break; |
96 |
|
case DEVICE_TYPE_DISK: |
97 |
|
if (g_fileinfo[handle].device_id != device) |
98 |
|
return False; |
99 |
|
break; |
100 |
|
} |
101 |
|
return True; |
102 |
|
} |
103 |
|
|
104 |
/* 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 */ |
105 |
BOOL |
BOOL |
106 |
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, |
413 |
#if WITH_DEBUG_RDP5 |
#if WITH_DEBUG_RDP5 |
414 |
DEBUG(("RDPDR IRP Read (length: %d, offset: %d)\n", length, offset)); |
DEBUG(("RDPDR IRP Read (length: %d, offset: %d)\n", length, offset)); |
415 |
#endif |
#endif |
416 |
|
if (!rdpdr_handle_ok(device, file)) |
417 |
|
{ |
418 |
|
status = STATUS_INVALID_HANDLE; |
419 |
|
break; |
420 |
|
} |
421 |
|
|
422 |
if (rw_blocking) // Complete read immediately |
if (rw_blocking) // Complete read immediately |
423 |
{ |
{ |
424 |
buffer = (uint8 *) xrealloc((void *) buffer, length); |
buffer = (uint8 *) xrealloc((void *) buffer, length); |
466 |
#if WITH_DEBUG_RDP5 |
#if WITH_DEBUG_RDP5 |
467 |
DEBUG(("RDPDR IRP Write (length: %d)\n", result)); |
DEBUG(("RDPDR IRP Write (length: %d)\n", result)); |
468 |
#endif |
#endif |
469 |
|
if (!rdpdr_handle_ok(device, file)) |
470 |
|
{ |
471 |
|
status = STATUS_INVALID_HANDLE; |
472 |
|
break; |
473 |
|
} |
474 |
|
|
475 |
if (rw_blocking) // Complete immediately |
if (rw_blocking) // Complete immediately |
476 |
{ |
{ |
477 |
status = fns->write(file, s->p, length, offset, &result); |
status = fns->write(file, s->p, length, offset, &result); |
791 |
} |
} |
792 |
} |
} |
793 |
|
|
794 |
|
struct async_iorequest * |
795 |
|
rdpdr_remove_iorequest(struct async_iorequest *prev, struct async_iorequest *iorq) |
796 |
|
{ |
797 |
|
if (!iorq) |
798 |
|
return NULL; |
799 |
|
|
800 |
|
if (iorq->buffer) |
801 |
|
xfree(iorq->buffer); |
802 |
|
if (prev) |
803 |
|
{ |
804 |
|
prev->next = iorq->next; |
805 |
|
xfree(iorq); |
806 |
|
iorq = prev->next; |
807 |
|
} |
808 |
|
else |
809 |
|
{ |
810 |
|
// Even if NULL |
811 |
|
g_iorequest = iorq->next; |
812 |
|
xfree(iorq); |
813 |
|
iorq = NULL; |
814 |
|
} |
815 |
|
return iorq; |
816 |
|
} |
817 |
|
|
818 |
/* Check if select() returned with one of the rdpdr file descriptors, and complete io if it did */ |
/* Check if select() returned with one of the rdpdr file descriptors, and complete io if it did */ |
819 |
void |
void |
854 |
status = fns->read(iorq->fd, |
status = fns->read(iorq->fd, |
855 |
iorq->buffer + iorq->partial_len, |
iorq->buffer + iorq->partial_len, |
856 |
req_size, iorq->offset, &result); |
req_size, iorq->offset, &result); |
|
iorq->partial_len += result; |
|
|
iorq->offset += result; |
|
857 |
|
|
858 |
|
if (result > 0) |
859 |
|
{ |
860 |
|
iorq->partial_len += result; |
861 |
|
iorq->offset += result; |
862 |
|
} |
863 |
#if WITH_DEBUG_RDP5 |
#if WITH_DEBUG_RDP5 |
864 |
DEBUG(("RDPDR: %d bytes of data read\n", result)); |
DEBUG(("RDPDR: %d bytes of data read\n", result)); |
865 |
#endif |
#endif |
871 |
#if WITH_DEBUG_RDP5 |
#if WITH_DEBUG_RDP5 |
872 |
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)); |
873 |
#endif |
#endif |
|
/* send the data */ |
|
|
status = STATUS_SUCCESS; |
|
874 |
rdpdr_send_completion(iorq->device, |
rdpdr_send_completion(iorq->device, |
875 |
iorq->id, status, |
iorq->id, status, |
876 |
iorq->partial_len, |
iorq->partial_len, |
877 |
iorq->buffer, |
iorq->buffer, |
878 |
iorq->partial_len); |
iorq->partial_len); |
879 |
xfree(iorq->buffer); |
iorq = rdpdr_remove_iorequest(prev, iorq); |
|
iorq->fd = 0; |
|
|
if (prev != NULL) |
|
|
{ |
|
|
prev->next = iorq->next; |
|
|
xfree(iorq); |
|
|
iorq = prev->next; |
|
|
} |
|
|
else |
|
|
{ |
|
|
// Even if NULL |
|
|
g_iorequest = iorq->next; |
|
|
xfree(iorq); |
|
|
iorq = NULL; |
|
|
} |
|
880 |
} |
} |
881 |
} |
} |
882 |
break; |
break; |
896 |
iorq->buffer + |
iorq->buffer + |
897 |
iorq->partial_len, req_size, |
iorq->partial_len, req_size, |
898 |
iorq->offset, &result); |
iorq->offset, &result); |
899 |
iorq->partial_len += result; |
|
900 |
iorq->offset += result; |
if (result > 0) |
901 |
|
{ |
902 |
|
iorq->partial_len += result; |
903 |
|
iorq->offset += result; |
904 |
|
} |
905 |
|
|
906 |
#if WITH_DEBUG_RDP5 |
#if WITH_DEBUG_RDP5 |
907 |
DEBUG(("RDPDR: %d bytes of data written\n", |
DEBUG(("RDPDR: %d bytes of data written\n", |
908 |
result)); |
result)); |
915 |
#if WITH_DEBUG_RDP5 |
#if WITH_DEBUG_RDP5 |
916 |
DEBUG(("RDPDR: AIO total %u bytes written of %u\n", iorq->partial_len, iorq->length)); |
DEBUG(("RDPDR: AIO total %u bytes written of %u\n", iorq->partial_len, iorq->length)); |
917 |
#endif |
#endif |
|
/* send a status success */ |
|
|
status = STATUS_SUCCESS; |
|
918 |
rdpdr_send_completion(iorq->device, |
rdpdr_send_completion(iorq->device, |
919 |
iorq->id, status, |
iorq->id, status, |
920 |
iorq->partial_len, |
iorq->partial_len, |
921 |
(uint8 *) "", 1); |
(uint8 *) "", 1); |
922 |
|
|
923 |
xfree(iorq->buffer); |
iorq = rdpdr_remove_iorequest(prev, iorq); |
|
iorq->fd = 0; |
|
|
if (prev != NULL) |
|
|
{ |
|
|
prev->next = iorq->next; |
|
|
xfree(iorq); |
|
|
iorq = prev->next; |
|
|
} |
|
|
else |
|
|
{ |
|
|
// Even if NULL |
|
|
g_iorequest = iorq->next; |
|
|
xfree(iorq); |
|
|
iorq = NULL; |
|
|
} |
|
924 |
} |
} |
925 |
} |
} |
926 |
break; |
break; |
953 |
result = 0; |
result = 0; |
954 |
rdpdr_send_completion(iorq->device, iorq->id, status, result, (uint8 *) "", |
rdpdr_send_completion(iorq->device, iorq->id, status, result, (uint8 *) "", |
955 |
1); |
1); |
956 |
xfree(iorq->buffer); |
|
957 |
iorq->fd = 0; |
iorq = rdpdr_remove_iorequest(prev, iorq); |
|
if (prev != NULL) |
|
|
{ |
|
|
prev->next = iorq->next; |
|
|
xfree(iorq); |
|
|
} |
|
|
else |
|
|
{ |
|
|
// Even if NULL |
|
|
g_iorequest = iorq->next; |
|
|
xfree(iorq); |
|
|
} |
|
958 |
return True; |
return True; |
959 |
} |
} |
960 |
|
|