ReactOS 0.4.15-dev-7958-gcd0bb1a
rdpdr.c File Reference
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <dirent.h>
#include <time.h>
#include <errno.h>
#include "rdesktop.h"
Include dependency graph for rdpdr.c:

Go to the source code of this file.

Macros

#define IRP_MJ_CREATE   0x00
 
#define IRP_MJ_CLOSE   0x02
 
#define IRP_MJ_READ   0x03
 
#define IRP_MJ_WRITE   0x04
 
#define IRP_MJ_QUERY_INFORMATION   0x05
 
#define IRP_MJ_SET_INFORMATION   0x06
 
#define IRP_MJ_QUERY_VOLUME_INFORMATION   0x0a
 
#define IRP_MJ_DIRECTORY_CONTROL   0x0c
 
#define IRP_MJ_DEVICE_CONTROL   0x0e
 
#define IRP_MJ_LOCK_CONTROL   0x11
 
#define IRP_MN_QUERY_DIRECTORY   0x01
 
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY   0x02
 

Functions

int get_device_index (RDPCLIENT *This, NTHANDLE handle)
 
void convert_to_unix_filename (char *filename)
 
static BOOL rdpdr_handle_ok (RDPCLIENT *This, int device, int handle)
 
static BOOL add_async_iorequest (RDPCLIENT *This, uint32 device, uint32 file, uint32 id, uint32 major, uint32 length, DEVICE_FNS *fns, uint32 total_timeout, uint32 interval_timeout, uint8 *buffer, uint32 offset)
 
static void rdpdr_send_connect (RDPCLIENT *This)
 
static void rdpdr_send_name (RDPCLIENT *This)
 
static int announcedata_size (RDPCLIENT *This)
 
static void rdpdr_send_available (RDPCLIENT *This)
 
static void rdpdr_send_completion (RDPCLIENT *This, uint32 device, uint32 id, uint32 status, uint32 result, uint8 *buffer, uint32 length)
 
static void rdpdr_process_irp (RDPCLIENT *This, STREAM s)
 
static void rdpdr_send_clientcapabilty (RDPCLIENT *This)
 
static void rdpdr_process (RDPCLIENT *This, STREAM s)
 
BOOL rdpdr_init (RDPCLIENT *This)
 
void rdpdr_add_fds (RDPCLIENT *This, int *n, fd_set *rfds, fd_set *wfds, struct timeval *tv, BOOL *timeout)
 
struct async_iorequest * rdpdr_remove_iorequest (RDPCLIENT *This, struct async_iorequest *prev, struct async_iorequest *iorq)
 
static void _rdpdr_check_fds (RDPCLIENT *This, fd_set *rfds, fd_set *wfds, BOOL timed_out)
 
void rdpdr_check_fds (RDPCLIENT *This, fd_set *rfds, fd_set *wfds, BOOL timed_out)
 
BOOL rdpdr_abort_io (RDPCLIENT *This, uint32 fd, uint32 major, NTSTATUS status)
 

Variables

DEVICE_FNS serial_fns
 
DEVICE_FNS printer_fns
 
DEVICE_FNS parallel_fns
 
DEVICE_FNS disk_fns
 

Macro Definition Documentation

◆ IRP_MJ_CLOSE

#define IRP_MJ_CLOSE   0x02

Definition at line 45 of file rdpdr.c.

◆ IRP_MJ_CREATE

#define IRP_MJ_CREATE   0x00

Definition at line 44 of file rdpdr.c.

◆ IRP_MJ_DEVICE_CONTROL

#define IRP_MJ_DEVICE_CONTROL   0x0e

Definition at line 52 of file rdpdr.c.

◆ IRP_MJ_DIRECTORY_CONTROL

#define IRP_MJ_DIRECTORY_CONTROL   0x0c

Definition at line 51 of file rdpdr.c.

◆ IRP_MJ_LOCK_CONTROL

#define IRP_MJ_LOCK_CONTROL   0x11

Definition at line 53 of file rdpdr.c.

◆ IRP_MJ_QUERY_INFORMATION

#define IRP_MJ_QUERY_INFORMATION   0x05

Definition at line 48 of file rdpdr.c.

◆ IRP_MJ_QUERY_VOLUME_INFORMATION

#define IRP_MJ_QUERY_VOLUME_INFORMATION   0x0a

Definition at line 50 of file rdpdr.c.

◆ IRP_MJ_READ

#define IRP_MJ_READ   0x03

Definition at line 46 of file rdpdr.c.

◆ IRP_MJ_SET_INFORMATION

#define IRP_MJ_SET_INFORMATION   0x06

Definition at line 49 of file rdpdr.c.

◆ IRP_MJ_WRITE

#define IRP_MJ_WRITE   0x04

Definition at line 47 of file rdpdr.c.

◆ IRP_MN_NOTIFY_CHANGE_DIRECTORY

#define IRP_MN_NOTIFY_CHANGE_DIRECTORY   0x02

Definition at line 56 of file rdpdr.c.

◆ IRP_MN_QUERY_DIRECTORY

#define IRP_MN_QUERY_DIRECTORY   0x01

Definition at line 55 of file rdpdr.c.

Function Documentation

◆ _rdpdr_check_fds()

static void _rdpdr_check_fds ( RDPCLIENT This,
fd_set rfds,
fd_set wfds,
BOOL  timed_out 
)
static

Definition at line 904 of file rdpdr.c.

905{
907 uint32 result = 0;
908 DEVICE_FNS *fns;
909 struct async_iorequest *iorq;
910 struct async_iorequest *prev;
911 uint32 req_size = 0;
912 uint32 buffer_len;
913 struct stream out;
914 uint8 *buffer = NULL;
915
916
917 if (timed_out)
918 {
919 /* check serial iv_timeout */
920
921 iorq = This->iorequest;
922 prev = NULL;
923 while (iorq != NULL)
924 {
925 if (iorq->fd == This->min_timeout_fd)
926 {
927 if ((iorq->partial_len > 0) &&
928 (This->rdpdr_device[iorq->device].device_type ==
930 {
931
932 /* iv_timeout between 2 chars, send partial_len */
933 /*printf("RDPDR: IVT total %u bytes read of %u\n", iorq->partial_len, iorq->length); */
934 rdpdr_send_completion(This, iorq->device,
935 iorq->id, STATUS_SUCCESS,
936 iorq->partial_len,
937 iorq->buffer, iorq->partial_len);
938 iorq = rdpdr_remove_iorequest(This, prev, iorq);
939 return;
940 }
941 else
942 {
943 break;
944 }
945
946 }
947 else
948 {
949 break;
950 }
951
952
953 prev = iorq;
954 if (iorq)
955 iorq = iorq->next;
956
957 }
958
959 rdpdr_abort_io(This, This->min_timeout_fd, 0, STATUS_TIMEOUT);
960 return;
961 }
962
963 iorq = This->iorequest;
964 prev = NULL;
965 while (iorq != NULL)
966 {
967 if (iorq->fd != 0)
968 {
969 switch (iorq->major)
970 {
971 case IRP_MJ_READ:
972 if (FD_ISSET(iorq->fd, rfds))
973 {
974 /* Read the data */
975 fns = iorq->fns;
976
977 req_size =
978 (iorq->length - iorq->partial_len) >
979 8192 ? 8192 : (iorq->length -
980 iorq->partial_len);
981 /* never read larger chunks than 8k - chances are that it will block */
982 status = fns->read(This, iorq->fd,
983 iorq->buffer + iorq->partial_len,
984 req_size, iorq->offset, &result);
985
986 if ((long) result > 0)
987 {
988 iorq->partial_len += result;
989 iorq->offset += result;
990 }
991#if WITH_DEBUG_RDP5
992 DEBUG(("RDPDR: %d bytes of data read\n", result));
993#endif
994 /* only delete link if all data has been transfered */
995 /* or if result was 0 and status success - EOF */
996 if ((iorq->partial_len == iorq->length) ||
997 (result == 0))
998 {
999#if WITH_DEBUG_RDP5
1000 DEBUG(("RDPDR: AIO total %u bytes read of %u\n", iorq->partial_len, iorq->length));
1001#endif
1002 rdpdr_send_completion(This, iorq->device,
1003 iorq->id, status,
1004 iorq->partial_len,
1005 iorq->buffer,
1006 iorq->partial_len);
1007 iorq = rdpdr_remove_iorequest(This, prev, iorq);
1008 }
1009 }
1010 break;
1011 case IRP_MJ_WRITE:
1012 if (FD_ISSET(iorq->fd, wfds))
1013 {
1014 /* Write data. */
1015 fns = iorq->fns;
1016
1017 req_size =
1018 (iorq->length - iorq->partial_len) >
1019 8192 ? 8192 : (iorq->length -
1020 iorq->partial_len);
1021
1022 /* never write larger chunks than 8k - chances are that it will block */
1023 status = fns->write(This, iorq->fd,
1024 iorq->buffer +
1025 iorq->partial_len, req_size,
1026 iorq->offset, &result);
1027
1028 if ((long) result > 0)
1029 {
1030 iorq->partial_len += result;
1031 iorq->offset += result;
1032 }
1033
1034#if WITH_DEBUG_RDP5
1035 DEBUG(("RDPDR: %d bytes of data written\n",
1036 result));
1037#endif
1038 /* only delete link if all data has been transfered */
1039 /* or we couldn't write */
1040 if ((iorq->partial_len == iorq->length)
1041 || (result == 0))
1042 {
1043#if WITH_DEBUG_RDP5
1044 DEBUG(("RDPDR: AIO total %u bytes written of %u\n", iorq->partial_len, iorq->length));
1045#endif
1046 rdpdr_send_completion(This, iorq->device,
1047 iorq->id, status,
1048 iorq->partial_len,
1049 (uint8 *) "", 1);
1050
1051 iorq = rdpdr_remove_iorequest(This, prev, iorq);
1052 }
1053 }
1054 break;
1056 if (serial_get_event(This, iorq->fd, &result))
1057 {
1058 buffer = (uint8 *) xrealloc((void *) buffer, 0x14);
1059 out.data = out.p = buffer;
1060 out.size = sizeof(buffer);
1062 result = buffer_len = out.p - out.data;
1064 rdpdr_send_completion(This, iorq->device, iorq->id,
1066 buffer_len);
1067 xfree(buffer);
1068 iorq = rdpdr_remove_iorequest(This, prev, iorq);
1069 }
1070
1071 break;
1072 }
1073
1074 }
1075 prev = iorq;
1076 if (iorq)
1077 iorq = iorq->next;
1078 }
1079
1080 /* Check notify */
1081 iorq = This->iorequest;
1082 prev = NULL;
1083 while (iorq != NULL)
1084 {
1085 if (iorq->fd != 0)
1086 {
1087 switch (iorq->major)
1088 {
1089
1091 if (This->rdpdr_device[iorq->device].device_type ==
1093 {
1094
1095 if (This->notify_stamp)
1096 {
1097 This->notify_stamp = False;
1098 status = disk_check_notify(This, iorq->fd);
1099 if (status != STATUS_PENDING)
1100 {
1101 rdpdr_send_completion(This, iorq->device,
1102 iorq->id,
1103 status, 0,
1104 NULL, 0);
1105 iorq = rdpdr_remove_iorequest(This, prev,
1106 iorq);
1107 }
1108 }
1109 }
1110 break;
1111
1112
1113
1114 }
1115 }
1116
1117 prev = iorq;
1118 if (iorq)
1119 iorq = iorq->next;
1120 }
1121
1122}
LONG NTSTATUS
Definition: precomp.h:26
#define DEVICE_TYPE_DISK
Definition: constants.h:488
#define DEVICE_TYPE_SERIAL
Definition: constants.h:485
#define out_uint32_le(s, v)
Definition: parse.h:59
void xfree(void *mem)
Definition: uimain.c:758
RD_NTSTATUS disk_check_notify(RD_NTHANDLE handle)
void * xrealloc(void *oldmem, size_t size)
Definition: uimain.c:736
RD_BOOL serial_get_event(RD_NTHANDLE handle, uint32 *result)
#define DEBUG(args)
Definition: rdesktop.h:129
unsigned int uint32
Definition: types.h:32
#define False
Definition: types.h:25
unsigned char uint8
Definition: types.h:28
#define NULL
Definition: types.h:112
GLuint buffer
Definition: glext.h:5915
GLuint64EXT * result
Definition: glext.h:11304
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
BOOL rdpdr_abort_io(RDPCLIENT *This, uint32 fd, uint32 major, NTSTATUS status)
Definition: rdpdr.c:1144
static void rdpdr_send_completion(RDPCLIENT *This, uint32 device, uint32 id, uint32 status, uint32 result, uint8 *buffer, uint32 length)
Definition: rdpdr.c:284
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
struct async_iorequest * rdpdr_remove_iorequest(RDPCLIENT *This, struct async_iorequest *prev, struct async_iorequest *iorq)
Definition: rdpdr.c:879
static FILE * out
Definition: regtests2xml.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
RD_NTSTATUS(* read)(RD_NTHANDLE handle, uint8 *data, uint32 length, uint32 offset, uint32 *result)
Definition: types.h:206
RD_NTSTATUS(* write)(RD_NTHANDLE handle, uint8 *data, uint32 length, uint32 offset, uint32 *result)
Definition: types.h:208
Definition: ps.c:97
Definition: parse.h:23
#define FD_ISSET(fd, set)
Definition: winsock.h:100

Referenced by rdpdr_check_fds().

◆ add_async_iorequest()

static BOOL add_async_iorequest ( RDPCLIENT This,
uint32  device,
uint32  file,
uint32  id,
uint32  major,
uint32  length,
DEVICE_FNS fns,
uint32  total_timeout,
uint32  interval_timeout,
uint8 buffer,
uint32  offset 
)
static

Definition at line 110 of file rdpdr.c.

113{
114 struct async_iorequest *iorq;
115
116 if (This->iorequest == NULL)
117 {
118 This->iorequest = (struct async_iorequest *) xmalloc(sizeof(struct async_iorequest));
119 if (!This->iorequest)
120 return False;
121 This->iorequest->fd = 0;
122 This->iorequest->next = NULL;
123 }
124
125 iorq = This->iorequest;
126
127 while (iorq->fd != 0)
128 {
129 /* create new element if needed */
130 if (iorq->next == NULL)
131 {
132 iorq->next =
133 (struct async_iorequest *) xmalloc(sizeof(struct async_iorequest));
134 if (!iorq->next)
135 return False;
136 iorq->next->fd = 0;
137 iorq->next->next = NULL;
138 }
139 iorq = iorq->next;
140 }
141 iorq->device = device;
142 iorq->fd = file;
143 iorq->id = id;
144 iorq->major = major;
145 iorq->length = length;
146 iorq->partial_len = 0;
147 iorq->fns = fns;
148 iorq->timeout = total_timeout;
149 iorq->itv_timeout = interval_timeout;
150 iorq->buffer = buffer;
151 iorq->offset = offset;
152 return True;
153}
void * xmalloc(int size)
Definition: uimain.c:747
#define True
Definition: types.h:24
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint id
Definition: glext.h:5910
GLintptr offset
Definition: glext.h:5920
#define major(rdev)
Definition: propsheet.cpp:928
struct define * next
Definition: compiler.c:65
Definition: devices.h:37
Definition: fci.c:127

Referenced by rdpdr_process_irp().

◆ announcedata_size()

static int announcedata_size ( RDPCLIENT This)
static

Definition at line 197 of file rdpdr.c.

198{
199 int size, i;
200 PRINTER *printerinfo;
201
202 size = 8; /* static announce size */
203 size += This->num_devices * 0x14;
204
205 for (i = 0; i < This->num_devices; i++)
206 {
207 if (This->rdpdr_device[i].device_type == DEVICE_TYPE_PRINTER)
208 {
209 printerinfo = (PRINTER *) This->rdpdr_device[i].pdevice_data;
210 printerinfo->bloblen =
211 printercache_load_blob(printerinfo->printer, &(printerinfo->blob));
212
213 size += 0x18;
214 size += 2 * strlen(printerinfo->driver) + 2;
215 size += 2 * strlen(printerinfo->printer) + 2;
216 size += printerinfo->bloblen;
217 }
218 }
219
220 return size;
221}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define DEVICE_TYPE_PRINTER
Definition: constants.h:487
int printercache_load_blob(char *printer_name, uint8 **data)
Definition: printercache.c:154
GLsizeiptr size
Definition: glext.h:5919
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
char * printer
Definition: types.h:263
char * driver
Definition: types.h:263
uint32 bloblen
Definition: types.h:264
uint8 * blob
Definition: types.h:265

Referenced by rdpdr_send_available().

◆ convert_to_unix_filename()

void convert_to_unix_filename ( char filename)

Definition at line 78 of file rdpdr.c.

79{
80 char *p;
81
82 while ((p = strchr(filename, '\\')))
83 {
84 *p = '/';
85 }
86}
char * strchr(const char *String, int ch)
Definition: utclib.c:501
GLfloat GLfloat p
Definition: glext.h:8902
const char * filename
Definition: ioapi.h:137

Referenced by disk_set_information(), and rdpdr_process_irp().

◆ get_device_index()

int get_device_index ( RDPCLIENT This,
NTHANDLE  handle 
)

Definition at line 65 of file rdpdr.c.

66{
67 int i;
68 for (i = 0; i < RDPDR_MAX_DEVICES; i++)
69 {
70 if (This->rdpdr_device[i].handle == handle)
71 return i;
72 }
73 return -1;
74}
#define RDPDR_MAX_DEVICES
Definition: constants.h:484

◆ rdpdr_abort_io()

BOOL rdpdr_abort_io ( RDPCLIENT This,
uint32  fd,
uint32  major,
NTSTATUS  status 
)

Definition at line 1144 of file rdpdr.c.

1145{
1146 uint32 result;
1147 struct async_iorequest *iorq;
1148 struct async_iorequest *prev;
1149
1150 iorq = This->iorequest;
1151 prev = NULL;
1152 while (iorq != NULL)
1153 {
1154 /* Only remove from table when major is not set, or when correct major is supplied.
1155 Abort read should not abort a write io request. */
1156 if ((iorq->fd == fd) && (major == 0 || iorq->major == major))
1157 {
1158 result = 0;
1159 rdpdr_send_completion(This, iorq->device, iorq->id, status, result, (uint8 *) "",
1160 1);
1161
1162 iorq = rdpdr_remove_iorequest(This, prev, iorq);
1163 return True;
1164 }
1165
1166 prev = iorq;
1167 iorq = iorq->next;
1168 }
1169
1170 return False;
1171}
static int fd
Definition: io.c:51

Referenced by _rdpdr_check_fds().

◆ rdpdr_add_fds()

void rdpdr_add_fds ( RDPCLIENT This,
int n,
fd_set rfds,
fd_set wfds,
struct timeval tv,
BOOL timeout 
)

Definition at line 807 of file rdpdr.c.

808{
809 uint32 select_timeout = 0; /* Timeout value to be used for select() (in millisecons). */
810 struct async_iorequest *iorq;
811 char c;
812
813 iorq = This->iorequest;
814 while (iorq != NULL)
815 {
816 if (iorq->fd != 0)
817 {
818 switch (iorq->major)
819 {
820 case IRP_MJ_READ:
821 /* Is this FD valid? FDs will
822 be invalid when
823 reconnecting. FIXME: Real
824 support for reconnects. */
825
826 FD_SET(iorq->fd, rfds);
827 *n = MAX(*n, iorq->fd);
828
829 /* Check if io request timeout is smaller than current (but not 0). */
830 if (iorq->timeout
831 && (select_timeout == 0
832 || iorq->timeout < select_timeout))
833 {
834 /* Set new timeout */
835 select_timeout = iorq->timeout;
836 This->min_timeout_fd = iorq->fd; /* Remember fd */
837 tv->tv_sec = select_timeout / 1000;
838 tv->tv_usec = (select_timeout % 1000) * 1000;
839 *timeout = True;
840 break;
841 }
842 if (iorq->itv_timeout && iorq->partial_len > 0
843 && (select_timeout == 0
844 || iorq->itv_timeout < select_timeout))
845 {
846 /* Set new timeout */
847 select_timeout = iorq->itv_timeout;
848 This->min_timeout_fd = iorq->fd; /* Remember fd */
849 tv->tv_sec = select_timeout / 1000;
850 tv->tv_usec = (select_timeout % 1000) * 1000;
851 *timeout = True;
852 break;
853 }
854 break;
855
856 case IRP_MJ_WRITE:
857 /* FD still valid? See above. */
858 if ((write(iorq->fd, &c, 0) != 0) && (errno == EBADF))
859 break;
860
861 FD_SET(iorq->fd, wfds);
862 *n = MAX(*n, iorq->fd);
863 break;
864
866 if (select_timeout > 5)
867 select_timeout = 5; /* serial event queue */
868 break;
869
870 }
871
872 }
873
874 iorq = iorq->next;
875 }
876}
#define EBADF
Definition: acclib.h:82
#define write
Definition: acwin.h:97
#define MAX(x, y)
Definition: rdesktop.h:175
GLdouble n
Definition: glext.h:7729
const GLubyte * c
Definition: glext.h:8905
#define c
Definition: ke_i.h:80
#define errno
Definition: errno.h:18
Definition: dhcpd.h:245
unsigned long tv_sec
Definition: linux.h:1738
unsigned long tv_usec
Definition: linux.h:1739
#define FD_SET(fd, set)
Definition: winsock.h:89

◆ rdpdr_check_fds()

void rdpdr_check_fds ( RDPCLIENT This,
fd_set rfds,
fd_set wfds,
BOOL  timed_out 
)

Definition at line 1125 of file rdpdr.c.

1126{
1127 fd_set dummy;
1128
1129
1130 FD_ZERO(&dummy);
1131
1132
1133 /* fist check event queue only,
1134 any serial wait event must be done before read block will be sent
1135 */
1136
1138 _rdpdr_check_fds(This, rfds, wfds, timed_out);
1139}
static void _rdpdr_check_fds(RDPCLIENT *This, fd_set *rfds, fd_set *wfds, BOOL timed_out)
Definition: rdpdr.c:904
Definition: winsock.h:66
#define FD_ZERO(set)
Definition: winsock.h:96

◆ rdpdr_handle_ok()

static BOOL rdpdr_handle_ok ( RDPCLIENT This,
int  device,
int  handle 
)
static

Definition at line 89 of file rdpdr.c.

90{
91 switch (This->rdpdr_device[device].device_type)
92 {
97 if (This->rdpdr_device[device].handle != handle)
98 return False;
99 break;
100 case DEVICE_TYPE_DISK:
101 if (This->fileinfo[handle].device_id != device)
102 return False;
103 break;
104 }
105 return True;
106}
#define DEVICE_TYPE_SCARD
Definition: constants.h:489
#define DEVICE_TYPE_PARALLEL
Definition: constants.h:486

Referenced by rdpdr_process_irp().

◆ rdpdr_init()

BOOL rdpdr_init ( RDPCLIENT This)

Definition at line 792 of file rdpdr.c.

793{
794 if (This->num_devices > 0)
795 {
796 This->rdpdr.channel =
797 channel_register(This, "rdpdr",
800 }
801
802 return (This->rdpdr.channel != NULL);
803}
VCHANNEL * channel_register(char *name, uint32 flags, void(*callback)(STREAM))
Definition: channels.c:46
#define CHANNEL_OPTION_INITIALIZED
Definition: constants.h:431
#define CHANNEL_OPTION_COMPRESS_RDP
Definition: constants.h:433
static void rdpdr_process(RDPCLIENT *This, STREAM s)
Definition: rdpdr.c:734

◆ rdpdr_process()

static void rdpdr_process ( RDPCLIENT This,
STREAM  s 
)
static

Definition at line 734 of file rdpdr.c.

735{
737 uint8 *magic;
738
739#if WITH_DEBUG_RDP5
740 printf("--- rdpdr_process ---\n");
741 hexdump(s->p, s->end - s->p);
742#endif
743 in_uint8p(s, magic, 4);
744
745 if ((magic[0] == 'r') && (magic[1] == 'D'))
746 {
747 if ((magic[2] == 'R') && (magic[3] == 'I'))
748 {
750 return;
751 }
752 if ((magic[2] == 'n') && (magic[3] == 'I'))
753 {
756 return;
757 }
758 if ((magic[2] == 'C') && (magic[3] == 'C'))
759 {
760 /* connect from server */
763 return;
764 }
765 if ((magic[2] == 'r') && (magic[3] == 'd'))
766 {
767 /* connect to a specific resource */
769#if WITH_DEBUG_RDP5
770 DEBUG(("RDPDR: Server connected to resource %d\n", handle));
771#endif
772 return;
773 }
774 if ((magic[2] == 'P') && (magic[3] == 'S'))
775 {
776 /* server capability */
777 return;
778 }
779 }
780 if ((magic[0] == 'R') && (magic[1] == 'P'))
781 {
782 if ((magic[2] == 'C') && (magic[3] == 'P'))
783 {
785 return;
786 }
787 }
788 unimpl("RDPDR packet type %c%c%c%c\n", magic[0], magic[1], magic[2], magic[3]);
789}
#define in_uint32(s, v)
Definition: parse.h:83
#define in_uint8p(s, v, n)
Definition: parse.h:89
void printercache_process(STREAM s)
void unimpl(char *format,...)
Definition: uimain.c:801
void hexdump(unsigned char *p, unsigned int len)
Definition: shimdbg.c:234
#define printf
Definition: freeldr.h:97
GLdouble s
Definition: gl.h:2039
u32_t magic(void)
static void rdpdr_send_connect(RDPCLIENT *This)
Definition: rdpdr.c:156
static void rdpdr_send_available(RDPCLIENT *This)
Definition: rdpdr.c:224
static void rdpdr_send_clientcapabilty(RDPCLIENT *This)
Definition: rdpdr.c:694
static void rdpdr_send_name(RDPCLIENT *This)
Definition: rdpdr.c:172
static void rdpdr_process_irp(RDPCLIENT *This, STREAM s)
Definition: rdpdr.c:307

Referenced by rdpdr_init().

◆ rdpdr_process_irp()

static void rdpdr_process_irp ( RDPCLIENT This,
STREAM  s 
)
static

Definition at line 307 of file rdpdr.c.

308{
309 uint32 result = 0,
310 length = 0,
311 desired_access = 0,
312 request,
313 file,
314 info_level,
315 buffer_len,
316 id,
317 major,
318 minor,
319 device,
320 offset,
321 bytes_in,
322 bytes_out,
323 error_mode,
324 share_mode, disposition, total_timeout, interval_timeout, flags_and_attributes = 0;
325
326 char filename[PATH_MAX];
327 uint8 *buffer, *pst_buf;
328 struct stream out;
329 DEVICE_FNS *fns;
330 BOOL rw_blocking = True;
332
335 in_uint32_le(s, id);
338
339 buffer_len = 0;
340 buffer = (uint8 *) xmalloc(1024);
341 buffer[0] = 0;
342
343 switch (This->rdpdr_device[device].device_type)
344 {
346
347 fns = &serial_fns;
348 rw_blocking = False;
349 break;
350
352
353 fns = &parallel_fns;
354 rw_blocking = False;
355 break;
356
358
359 fns = &printer_fns;
360 break;
361
362 case DEVICE_TYPE_DISK:
363
364 fns = &disk_fns;
365 rw_blocking = False;
366 break;
367
369 default:
370
371 error("IRP for bad device %ld\n", device);
372 return;
373 }
374
375 switch (major)
376 {
377 case IRP_MJ_CREATE:
378
379 in_uint32_be(s, desired_access);
380 in_uint8s(s, 0x08); /* unknown */
381 in_uint32_le(s, error_mode);
382 in_uint32_le(s, share_mode);
383 in_uint32_le(s, disposition);
384 in_uint32_le(s, flags_and_attributes);
386
387 if (length && (length / 2) < 256)
388 {
391 }
392 else
393 {
394 filename[0] = 0;
395 }
396
397 if (!fns->create)
398 {
400 break;
401 }
402
403 status = fns->create(This, device, desired_access, share_mode, disposition,
404 flags_and_attributes, filename, &result);
405 buffer_len = 1;
406 break;
407
408 case IRP_MJ_CLOSE:
409 if (!fns->close)
410 {
412 break;
413 }
414
415 status = fns->close(This, file);
416 break;
417
418 case IRP_MJ_READ:
419
420 if (!fns->read)
421 {
423 break;
424 }
425
428#if WITH_DEBUG_RDP5
429 DEBUG(("RDPDR IRP Read (length: %d, offset: %d)\n", length, offset));
430#endif
432 {
434 break;
435 }
436
437 if (rw_blocking) /* Complete read immediately */
438 {
439 buffer = (uint8 *) xrealloc((void *) buffer, length);
440 if (!buffer)
441 {
443 break;
444 }
445 status = fns->read(This, file, buffer, length, offset, &result);
446 buffer_len = result;
447 break;
448 }
449
450 /* Add request to table */
451 pst_buf = (uint8 *) xmalloc(length);
452 if (!pst_buf)
453 {
455 break;
456 }
457 serial_get_timeout(This, file, length, &total_timeout, &interval_timeout);
459 (This, device, file, id, major, length, fns, total_timeout, interval_timeout,
460 pst_buf, offset))
461 {
463 break;
464 }
465
467 break;
468 case IRP_MJ_WRITE:
469
470 buffer_len = 1;
471
472 if (!fns->write)
473 {
475 break;
476 }
477
480 in_uint8s(s, 0x18);
481#if WITH_DEBUG_RDP5
482 DEBUG(("RDPDR IRP Write (length: %d)\n", result));
483#endif
485 {
487 break;
488 }
489
490 if (rw_blocking) /* Complete immediately */
491 {
492 status = fns->write(This, file, s->p, length, offset, &result);
493 break;
494 }
495
496 /* Add to table */
497 pst_buf = (uint8 *) xmalloc(length);
498 if (!pst_buf)
499 {
501 break;
502 }
503
504 in_uint8a(s, pst_buf, length);
505
507 (This, device, file, id, major, length, fns, 0, 0, pst_buf, offset))
508 {
510 break;
511 }
512
514 break;
515
517
518 if (This->rdpdr_device[device].device_type != DEVICE_TYPE_DISK)
519 {
521 break;
522 }
523 in_uint32_le(s, info_level);
524
525 out.data = out.p = buffer;
526 out.size = sizeof(buffer);
527 status = disk_query_information(This, file, info_level, &out);
528 result = buffer_len = out.p - out.data;
529
530 break;
531
533
534 if (This->rdpdr_device[device].device_type != DEVICE_TYPE_DISK)
535 {
537 break;
538 }
539
540 in_uint32_le(s, info_level);
541
542 out.data = out.p = buffer;
543 out.size = sizeof(buffer);
544 status = disk_set_information(This, file, info_level, s, &out);
545 result = buffer_len = out.p - out.data;
546 break;
547
549
550 if (This->rdpdr_device[device].device_type != DEVICE_TYPE_DISK)
551 {
553 break;
554 }
555
556 in_uint32_le(s, info_level);
557
558 out.data = out.p = buffer;
559 out.size = sizeof(buffer);
561 result = buffer_len = out.p - out.data;
562 break;
563
565
566 if (This->rdpdr_device[device].device_type != DEVICE_TYPE_DISK)
567 {
569 break;
570 }
571
572 switch (minor)
573 {
575
576 in_uint32_le(s, info_level);
577 in_uint8s(s, 1);
579 in_uint8s(s, 0x17);
580 if (length && length < 2 * 255)
581 {
584 }
585 else
586 {
587 filename[0] = 0;
588 }
589 out.data = out.p = buffer;
590 out.size = sizeof(buffer);
592 &out);
593 result = buffer_len = out.p - out.data;
594 if (!buffer_len)
595 buffer_len++;
596 break;
597
599
600 /* JIF
601 unimpl("IRP major=0x%x minor=0x%x: IRP_MN_NOTIFY_CHANGE_DIRECTORY\n", major, minor); */
602
603 in_uint32_le(s, info_level); /* notify mask */
604
605 This->notify_stamp = True;
606
607 status = disk_create_notify(This, file, info_level);
608 result = 0;
609
610 if (status == STATUS_PENDING)
612 fns, 0, 0, NULL, 0);
613 break;
614
615 default:
616
618 /* JIF */
619 unimpl("IRP major=0x%x minor=0x%x\n", major, minor);
620 }
621 break;
622
624
625 if (!fns->device_control)
626 {
628 break;
629 }
630
631 in_uint32_le(s, bytes_out);
632 in_uint32_le(s, bytes_in);
634 in_uint8s(s, 0x14);
635
636 buffer = (uint8 *) xrealloc((void *) buffer, bytes_out + 0x14);
637 if (!buffer)
638 {
640 break;
641 }
642
643 out.data = out.p = buffer;
644 out.size = sizeof(buffer);
645 status = fns->device_control(This, file, request, s, &out);
646 result = buffer_len = out.p - out.data;
647
648 /* Serial SERIAL_WAIT_ON_MASK */
649 if (status == STATUS_PENDING)
650 {
652 (This, device, file, id, major, length, fns, 0, 0, NULL, 0))
653 {
655 break;
656 }
657 }
658 break;
659
660
662
663 if (This->rdpdr_device[device].device_type != DEVICE_TYPE_DISK)
664 {
666 break;
667 }
668
669 in_uint32_le(s, info_level);
670
671 out.data = out.p = buffer;
672 out.size = sizeof(buffer);
673 /* FIXME: Perhaps consider actually *do*
674 something here :-) */
676 result = buffer_len = out.p - out.data;
677 break;
678
679 default:
680 unimpl("IRP major=0x%x minor=0x%x\n", major, minor);
681 break;
682 }
683
684 if (status != STATUS_PENDING)
685 {
687 }
688 if (buffer)
689 xfree(buffer);
690 buffer = NULL;
691}
#define in_uint32_be(s, v)
Definition: parse.h:76
#define in_uint8a(s, v, n)
Definition: parse.h:90
#define in_uint8s(s, n)
Definition: parse.h:91
#define in_uint32_le(s, v)
Definition: parse.h:56
RD_NTSTATUS disk_query_volume_information(RD_NTHANDLE handle, uint32 info_class, STREAM out)
RD_BOOL serial_get_timeout(RD_NTHANDLE handle, uint32 length, uint32 *timeout, uint32 *itv_timeout)
RD_NTSTATUS disk_set_information(RD_NTHANDLE handle, uint32 info_class, STREAM in, STREAM out)
RD_NTSTATUS disk_query_directory(RD_NTHANDLE handle, uint32 info_class, char *pattern, STREAM out)
void rdp_in_unistr(STREAM s, int in_len, char **string, uint32 *str_size)
Definition: rdp.c:265
RD_NTSTATUS disk_create_notify(RD_NTHANDLE handle, uint32 info_class)
RD_NTSTATUS disk_query_information(RD_NTHANDLE handle, uint32 info_class, STREAM out)
#define PATH_MAX
Definition: types.h:280
unsigned int BOOL
Definition: ntddk_ex.h:94
#define error(str)
Definition: mkdosfs.c:1605
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define minor(rdev)
Definition: propsheet.cpp:929
void convert_to_unix_filename(char *filename)
Definition: rdpdr.c:78
DEVICE_FNS parallel_fns
Definition: parallel.c:181
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
DEVICE_FNS serial_fns
Definition: serial.c:1068
static BOOL rdpdr_handle_ok(RDPCLIENT *This, int device, int handle)
Definition: rdpdr.c:89
DEVICE_FNS printer_fns
Definition: printer.c:156
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
static BOOL add_async_iorequest(RDPCLIENT *This, uint32 device, uint32 file, uint32 id, uint32 major, uint32 length, DEVICE_FNS *fns, uint32 total_timeout, uint32 interval_timeout, uint8 *buffer, uint32 offset)
Definition: rdpdr.c:110
DEVICE_FNS disk_fns
Definition: disk.c:1240
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
Definition: tftpd.h:86
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_CANCELLED
Definition: udferr_usr.h:170

Referenced by rdpdr_process().

◆ rdpdr_remove_iorequest()

struct async_iorequest * rdpdr_remove_iorequest ( RDPCLIENT This,
struct async_iorequest *  prev,
struct async_iorequest *  iorq 
)

Definition at line 879 of file rdpdr.c.

880{
881 if (!iorq)
882 return NULL;
883
884 if (iorq->buffer)
885 xfree(iorq->buffer);
886 if (prev)
887 {
888 prev->next = iorq->next;
889 xfree(iorq);
890 iorq = prev->next;
891 }
892 else
893 {
894 /* Even if NULL */
895 This->iorequest = iorq->next;
896 xfree(iorq);
897 iorq = NULL;
898 }
899 return iorq;
900}

Referenced by _rdpdr_check_fds(), and rdpdr_abort_io().

◆ rdpdr_send_available()

static void rdpdr_send_available ( RDPCLIENT This)
static

Definition at line 224 of file rdpdr.c.

225{
226
227 uint8 magic[4] = "rDAD";
228 uint32 driverlen, printerlen, bloblen;
229 int i;
230 STREAM s;
231 PRINTER *printerinfo;
232
233 s = channel_init(This, This->rdpdr.channel, announcedata_size(This));
234 out_uint8a(s, magic, 4);
235 out_uint32_le(s, This->num_devices);
236
237 for (i = 0; i < This->num_devices; i++)
238 {
239 out_uint32_le(s, This->rdpdr_device[i].device_type);
240 out_uint32_le(s, i); /* RDP Device ID */
241 /* Is it possible to use share names longer than 8 chars?
242 /astrand */
243 out_uint8p(s, This->rdpdr_device[i].name, 8);
244
245 switch (This->rdpdr_device[i].device_type)
246 {
248 printerinfo = (PRINTER *) This->rdpdr_device[i].pdevice_data;
249
250 driverlen = 2 * strlen(printerinfo->driver) + 2;
251 printerlen = 2 * strlen(printerinfo->printer) + 2;
252 bloblen = printerinfo->bloblen;
253
254 out_uint32_le(s, 24 + driverlen + printerlen + bloblen); /* length of extra info */
255 out_uint32_le(s, printerinfo->default_printer ? 2 : 0);
256 out_uint8s(s, 8); /* unknown */
257 out_uint32_le(s, driverlen);
258 out_uint32_le(s, printerlen);
259 out_uint32_le(s, bloblen);
260 rdp_out_unistr(This, s, printerinfo->driver, driverlen - 2);
261 rdp_out_unistr(This, s, printerinfo->printer, printerlen - 2);
262 out_uint8a(s, printerinfo->blob, bloblen);
263
264 if (printerinfo->blob)
265 xfree(printerinfo->blob); /* Blob is sent twice if reconnecting */
266 break;
267 default:
268 out_uint32(s, 0);
269 }
270 }
271#if 0
272 out_uint32_le(s, 0x20); /* Device type 0x20 - smart card */
273 out_uint32_le(s, 0);
274 out_uint8p(s, "SCARD", 5);
275 out_uint8s(s, 3);
276 out_uint32(s, 0);
277#endif
278
279 s_mark_end(s);
280 channel_send(This, s, This->rdpdr.channel);
281}
STREAM channel_init(VCHANNEL *channel, uint32 length)
Definition: channels.c:69
void channel_send(STREAM s, VCHANNEL *channel)
Definition: channels.c:79
#define s_mark_end(s)
Definition: parse.h:41
#define out_uint8s(s, n)
Definition: parse.h:95
#define out_uint8p(s, v, n)
Definition: parse.h:93
#define out_uint32(s, v)
Definition: parse.h:85
#define out_uint8a(s, v, n)
Definition: parse.h:94
void rdp_out_unistr(STREAM s, char *string, int len)
Definition: rdp.c:188
static int announcedata_size(RDPCLIENT *This)
Definition: rdpdr.c:197
RD_BOOL default_printer
Definition: types.h:266

Referenced by rdpdr_process().

◆ rdpdr_send_clientcapabilty()

static void rdpdr_send_clientcapabilty ( RDPCLIENT This)
static

Definition at line 694 of file rdpdr.c.

695{
696 uint8 magic[4] = "rDPC";
697 STREAM s;
698
699 s = channel_init(This, This->rdpdr.channel, 0x50);
700 out_uint8a(s, magic, 4);
701 out_uint32_le(s, 5); /* count */
702 out_uint16_le(s, 1); /* first */
703 out_uint16_le(s, 0x28); /* length */
704 out_uint32_le(s, 1);
705 out_uint32_le(s, 2);
706 out_uint16_le(s, 2);
707 out_uint16_le(s, 5);
708 out_uint16_le(s, 1);
709 out_uint16_le(s, 5);
710 out_uint16_le(s, 0xFFFF);
711 out_uint16_le(s, 0);
712 out_uint32_le(s, 0);
713 out_uint32_le(s, 3);
714 out_uint32_le(s, 0);
715 out_uint32_le(s, 0);
716 out_uint16_le(s, 2); /* second */
717 out_uint16_le(s, 8); /* length */
718 out_uint32_le(s, 1);
719 out_uint16_le(s, 3); /* third */
720 out_uint16_le(s, 8); /* length */
721 out_uint32_le(s, 1);
722 out_uint16_le(s, 4); /* fourth */
723 out_uint16_le(s, 8); /* length */
724 out_uint32_le(s, 1);
725 out_uint16_le(s, 5); /* fifth */
726 out_uint16_le(s, 8); /* length */
727 out_uint32_le(s, 1);
728
729 s_mark_end(s);
730 channel_send(This, s, This->rdpdr.channel);
731}
#define out_uint16_le(s, v)
Definition: parse.h:58

Referenced by rdpdr_process().

◆ rdpdr_send_completion()

static void rdpdr_send_completion ( RDPCLIENT This,
uint32  device,
uint32  id,
uint32  status,
uint32  result,
uint8 buffer,
uint32  length 
)
static

Definition at line 284 of file rdpdr.c.

286{
287 uint8 magic[4] = "rDCI";
288 STREAM s;
289
290 s = channel_init(This, This->rdpdr.channel, 20 + length);
291 out_uint8a(s, magic, 4);
293 out_uint32_le(s, id);
297 s_mark_end(s);
298 /* JIF */
299#ifdef WITH_DEBUG_RDP5
300 printf("--> rdpdr_send_completion\n");
301 /* hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8); */
302#endif
303 channel_send(This, s, This->rdpdr.channel);
304}

Referenced by _rdpdr_check_fds(), rdpdr_abort_io(), and rdpdr_process_irp().

◆ rdpdr_send_connect()

static void rdpdr_send_connect ( RDPCLIENT This)
static

Definition at line 156 of file rdpdr.c.

157{
158 uint8 magic[4] = "rDCC";
159 STREAM s;
160
161 s = channel_init(This, This->rdpdr.channel, 12);
162 out_uint8a(s, magic, 4);
163 out_uint16_le(s, 1); /* unknown */
164 out_uint16_le(s, 5);
165 out_uint32_be(s, 0x815ed39d); /* IP address (use 127.0.0.1) 0x815ed39d */
166 s_mark_end(s);
167 channel_send(This, s, This->rdpdr.channel);
168}
#define out_uint32_be(s, v)
Definition: parse.h:78

Referenced by rdpdr_process().

◆ rdpdr_send_name()

static void rdpdr_send_name ( RDPCLIENT This)
static

Definition at line 172 of file rdpdr.c.

173{
174 uint8 magic[4] = "rDNC";
175 STREAM s;
176 uint32 hostlen;
177
178 if (NULL == This->rdpdr_clientname)
179 {
180 This->rdpdr_clientname = This->hostname;
181 }
182 hostlen = (strlen(This->rdpdr_clientname) + 1) * 2;
183
184 s = channel_init(This, This->rdpdr.channel, 16 + hostlen);
185 out_uint8a(s, magic, 4);
186 out_uint16_le(s, 0x63); /* unknown */
187 out_uint16_le(s, 0x72);
188 out_uint32(s, 0);
189 out_uint32_le(s, hostlen);
190 rdp_out_unistr(This, s, This->rdpdr_clientname, hostlen - 2);
191 s_mark_end(s);
192 channel_send(This, s, This->rdpdr.channel);
193}

Referenced by rdpdr_process().

Variable Documentation

◆ disk_fns

DEVICE_FNS disk_fns
extern

Definition at line 1240 of file disk.c.

Referenced by rdpdr_process_irp().

◆ parallel_fns

DEVICE_FNS parallel_fns
extern

Definition at line 181 of file parallel.c.

Referenced by rdpdr_process_irp().

◆ printer_fns

DEVICE_FNS printer_fns
extern

Definition at line 156 of file printer.c.

Referenced by rdpdr_process_irp().

◆ serial_fns

DEVICE_FNS serial_fns
extern

Definition at line 1068 of file serial.c.

Referenced by rdpdr_process_irp().