/[rdesktop]/sourceforge.net/trunk/rdesktop/rdpdr.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/rdesktop/rdpdr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 432 - (show annotations)
Tue Jul 1 09:31:25 2003 UTC (20 years, 11 months ago) by matthewc
File MIME type: text/plain
File size: 5711 byte(s)
Commit of work in progress on channels (so that other people can hack on
RDPSND), in particular:
* channel layer takes care of virtual channel header
* split X dependent parts out of CLIPRDR, simplified IPC implementation
* initial RDPDR implementation

1 #include "rdesktop.h"
2
3 #define IRP_MJ_CREATE 0x00
4 #define IRP_MJ_CLOSE 0x02
5 #define IRP_MJ_READ 0x03
6 #define IRP_MJ_WRITE 0x04
7 #define IRP_MJ_DEVICE_CONTROL 0x0e
8
9 extern char hostname[16];
10 extern DEVICE_FNS serial_fns;
11 extern DEVICE_FNS printer_fns;
12
13 static VCHANNEL *rdpdr_channel;
14
15 void
16 rdpdr_send_connect(void)
17 {
18 uint8 magic[4] = "rDCC";
19 STREAM s;
20
21 s = channel_init(rdpdr_channel, 12);
22 out_uint8a(s, magic, 4);
23 out_uint16_le(s, 1); /* unknown */
24 out_uint16_le(s, 5);
25 out_uint32_be(s, 0x815ed39d); /* IP address (use 127.0.0.1) 0x815ed39d */
26 s_mark_end(s);
27 channel_send(s, rdpdr_channel);
28 }
29
30 void
31 rdpdr_send_name(void)
32 {
33 uint8 magic[4] = "rDNC";
34 uint32 hostlen = (strlen(hostname)+1)*2;
35 STREAM s;
36
37 s = channel_init(rdpdr_channel, 16+hostlen);
38 out_uint8a(s, magic, 4);
39 out_uint16_le(s, 0x63); /* unknown */
40 out_uint16_le(s, 0x72);
41 out_uint32(s, 0);
42 out_uint32_le(s, hostlen);
43 rdp_out_unistr(s, hostname, hostlen-2);
44 s_mark_end(s);
45 channel_send(s, rdpdr_channel);
46 }
47
48 void
49 rdpdr_send_available(void)
50 {
51 uint8 magic[4] = "rDAD";
52 char *driver = "Digital turbo PrintServer 20"; /* Fairly generic PostScript driver */
53 char *printer = "PostScript";
54 uint32 driverlen = (strlen(driver)+1)*2;
55 uint32 printerlen = (strlen(printer)+1)*2;
56 STREAM s;
57
58 s = channel_init(rdpdr_channel, 8+20);
59 out_uint8a(s, magic, 4);
60 out_uint32_le(s, 1); /* Number of devices */
61
62 #if 1
63 out_uint32_le(s, 0x1); /* Device type 0x1 - serial */
64 out_uint32_le(s, 0); /* Handle */
65 out_uint8p(s, "COM2", 4);
66 out_uint8s(s, 4); /* Pad to 8 */
67 out_uint32(s, 0);
68 #endif
69 #if 0
70 out_uint32_le(s, 0x2); /* Device type 0x2 - parallel */
71 out_uint32_le(s, 0);
72 out_uint8p(s, "LPT2", 4);
73 out_uint8s(s, 4);
74 out_uint32(s, 0);
75 #endif
76 #if 1
77 out_uint32_le(s, 0x4); /* Device type 0x4 - printer */
78 out_uint32_le(s, 1);
79 out_uint8p(s, "PRN1", 4);
80 out_uint8s(s, 4);
81 out_uint32_le(s, 24+driverlen+printerlen); /* length of extra info */
82 out_uint32_le(s, 2); /* unknown */
83 out_uint8s(s, 8); /* unknown */
84 out_uint32_le(s, driverlen); /* length of driver name */
85 out_uint32_le(s, printerlen); /* length of printer name */
86 out_uint32(s, 0); /* unknown */
87 rdp_out_unistr(s, driver, driverlen-2);
88 rdp_out_unistr(s, printer, printerlen-2);
89 #endif
90 #if 0
91 out_uint32_le(s, 0x8); /* Device type 0x8 - disk */
92 out_uint32_le(s, 0);
93 out_uint8p(s, "Z:", 2);
94 out_uint8s(s, 6);
95 out_uint32(s, 0);
96 #endif
97 #if 0
98 out_uint32_le(s, 0x20); /* Device type 0x20 - smart card */
99 out_uint32_le(s, 0);
100 out_uint8p(s, "SCARD", 5);
101 out_uint8s(s, 3);
102 out_uint32(s, 0);
103 #endif
104
105 s_mark_end(s);
106 channel_send(s, rdpdr_channel);
107 }
108
109 void
110 rdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, uint8 *buffer, uint32 length)
111 {
112 uint8 magic[4] = "rDCI";
113 STREAM s;
114
115 s = channel_init(rdpdr_channel, 20 + length);
116 out_uint8a(s, magic, 4);
117 out_uint32_le(s, device);
118 out_uint32_le(s, id);
119 out_uint32_le(s, status);
120 out_uint32_le(s, result);
121 out_uint8p(s, buffer, length);
122 s_mark_end(s);
123 hexdump(s->channel_hdr+8, s->end-s->channel_hdr-8);
124 channel_send(s, rdpdr_channel);
125 }
126
127 static void
128 rdpdr_process_irp(STREAM s)
129 {
130 uint32 device, file, id, major, minor;
131 NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
132 uint32 result = 0, length, request, bytes_in, bytes_out;
133 uint8 buffer[256];
134 uint32 buffer_len = 1;
135 struct stream out;
136 DEVICE_FNS *fns;
137
138 in_uint32_le(s, device);
139 in_uint32_le(s, file);
140 in_uint32_le(s, id);
141 in_uint32_le(s, major);
142 in_uint32_le(s, minor);
143
144 memset(buffer, 0, sizeof(buffer));
145
146 /* FIXME: this should probably be a more dynamic mapping */
147 switch (device)
148 {
149 case 0:
150 fns = &serial_fns;
151 case 1:
152 fns = &printer_fns;
153 default:
154 error("IRP for bad device %ld\n", device);
155 return;
156 }
157
158 switch (major)
159 {
160 case IRP_MJ_CREATE:
161 if (fns->create)
162 status = fns->create(&result);
163 break;
164
165 case IRP_MJ_CLOSE:
166 if (fns->close)
167 status = fns->close(file);
168 break;
169
170 case IRP_MJ_READ:
171 if (fns->read)
172 {
173 if (length > sizeof(buffer))
174 length = sizeof(buffer);
175 status = fns->read(file, buffer, length, &result);
176 buffer_len = result;
177 }
178 break;
179
180 case IRP_MJ_WRITE:
181 if (fns->write)
182 status = fns->write(file, s->p, length, &result);
183 break;
184
185 case IRP_MJ_DEVICE_CONTROL:
186 if (fns->device_control)
187 {
188 in_uint32_le(s, bytes_out);
189 in_uint32_le(s, bytes_in);
190 in_uint32_le(s, request);
191 in_uint8s(s, 0x14);
192 out.data = out.p = buffer;
193 out.size = sizeof(buffer);
194 status = fns->device_control(file, request, s, &out);
195 result = buffer_len = out.p - out.data;
196 }
197 break;
198
199 default:
200 unimpl("IRP major=0x%x minor=0x%x\n", major, minor);
201 break;
202 }
203
204 rdpdr_send_completion(device, id, status, result, buffer, buffer_len);
205 }
206
207 static void
208 rdpdr_process(STREAM s)
209 {
210 uint32 handle;
211 char *magic;
212
213 printf("rdpdr_process\n");
214 hexdump(s->p, s->end-s->p);
215 in_uint8p(s, magic, 4);
216
217 if ((magic[0] == 'r') && (magic[1] == 'D'))
218 {
219 if ((magic[2] == 'R') && (magic[3] == 'I'))
220 {
221 rdpdr_process_irp(s);
222 return;
223 }
224 if ((magic[2] == 'n') && (magic[3] == 'I'))
225 {
226 rdpdr_send_connect();
227 rdpdr_send_name();
228 rdpdr_send_available();
229 return;
230 }
231 else if ((magic[2] == 'C') && (magic[3] == 'C'))
232 {
233 /* connect from server */
234 return;
235 }
236 else if ((magic[2] == 'r') && (magic[3] == 'd'))
237 {
238 /* connect to a specific resource */
239 in_uint32(s, handle);
240 printf("Server connected to resource %d\n", handle);
241 return;
242 }
243 }
244 unimpl("RDPDR packet type %c%c%c%c\n", magic[0], magic[1], magic[2], magic[3]);
245 }
246
247 BOOL
248 rdpdr_init(void)
249 {
250 rdpdr_channel = channel_register("rdpdr", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_COMPRESS_RDP, rdpdr_process);
251 return (rdpdr_channel != NULL);
252 }

  ViewVC Help
Powered by ViewVC 1.1.26