/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 554 - (hide annotations)
Tue Dec 9 09:57:44 2003 UTC (20 years, 5 months ago) by stargo
File MIME type: text/plain
File size: 5762 byte(s)
Timezone patch by Mark Roach

1 matthewc 432 #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 astrand 435 out_uint16_le(s, 1); /* unknown */
24 matthewc 432 out_uint16_le(s, 5);
25 astrand 435 out_uint32_be(s, 0x815ed39d); /* IP address (use 127.0.0.1) 0x815ed39d */
26 matthewc 432 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 astrand 435 uint32 hostlen = (strlen(hostname) + 1) * 2;
35 matthewc 432 STREAM s;
36    
37 astrand 435 s = channel_init(rdpdr_channel, 16 + hostlen);
38 matthewc 432 out_uint8a(s, magic, 4);
39 astrand 435 out_uint16_le(s, 0x63); /* unknown */
40 matthewc 432 out_uint16_le(s, 0x72);
41     out_uint32(s, 0);
42     out_uint32_le(s, hostlen);
43 astrand 435 rdp_out_unistr(s, hostname, hostlen - 2);
44 matthewc 432 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 astrand 435 char *driver = "Digital turbo PrintServer 20"; /* Fairly generic PostScript driver */
53 matthewc 432 char *printer = "PostScript";
54 astrand 435 uint32 driverlen = (strlen(driver) + 1) * 2;
55     uint32 printerlen = (strlen(printer) + 1) * 2;
56 matthewc 432 STREAM s;
57    
58 astrand 435 s = channel_init(rdpdr_channel, 8 + 20);
59 matthewc 432 out_uint8a(s, magic, 4);
60 astrand 435 out_uint32_le(s, 1); /* Number of devices */
61 matthewc 432
62     #if 1
63     out_uint32_le(s, 0x1); /* Device type 0x1 - serial */
64     out_uint32_le(s, 0); /* Handle */
65 stargo 554 out_uint8p(s, "COM4", 4);
66 matthewc 432 out_uint8s(s, 4); /* Pad to 8 */
67     out_uint32(s, 0);
68     #endif
69     #if 0
70 astrand 435 out_uint32_le(s, 0x2); /* Device type 0x2 - parallel */
71 matthewc 432 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 astrand 435 out_uint32_le(s, 0x4); /* Device type 0x4 - printer */
78 matthewc 432 out_uint32_le(s, 1);
79     out_uint8p(s, "PRN1", 4);
80     out_uint8s(s, 4);
81 astrand 435 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 matthewc 432 #endif
90     #if 0
91 astrand 435 out_uint32_le(s, 0x8); /* Device type 0x8 - disk */
92 matthewc 432 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 astrand 435 out_uint32_le(s, 0x20); /* Device type 0x20 - smart card */
99 matthewc 432 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 astrand 435 rdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, uint8 * buffer,
111     uint32 length)
112 matthewc 432 {
113     uint8 magic[4] = "rDCI";
114     STREAM s;
115    
116     s = channel_init(rdpdr_channel, 20 + length);
117     out_uint8a(s, magic, 4);
118     out_uint32_le(s, device);
119     out_uint32_le(s, id);
120     out_uint32_le(s, status);
121     out_uint32_le(s, result);
122     out_uint8p(s, buffer, length);
123     s_mark_end(s);
124 astrand 435 hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
125 matthewc 432 channel_send(s, rdpdr_channel);
126     }
127    
128     static void
129     rdpdr_process_irp(STREAM s)
130     {
131     uint32 device, file, id, major, minor;
132     NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
133     uint32 result = 0, length, request, bytes_in, bytes_out;
134     uint8 buffer[256];
135     uint32 buffer_len = 1;
136     struct stream out;
137     DEVICE_FNS *fns;
138    
139     in_uint32_le(s, device);
140     in_uint32_le(s, file);
141     in_uint32_le(s, id);
142     in_uint32_le(s, major);
143     in_uint32_le(s, minor);
144    
145     memset(buffer, 0, sizeof(buffer));
146    
147     /* FIXME: this should probably be a more dynamic mapping */
148     switch (device)
149     {
150     case 0:
151     fns = &serial_fns;
152     case 1:
153     fns = &printer_fns;
154     default:
155     error("IRP for bad device %ld\n", device);
156     return;
157     }
158    
159     switch (major)
160     {
161     case IRP_MJ_CREATE:
162     if (fns->create)
163     status = fns->create(&result);
164     break;
165    
166     case IRP_MJ_CLOSE:
167     if (fns->close)
168     status = fns->close(file);
169     break;
170    
171     case IRP_MJ_READ:
172     if (fns->read)
173     {
174     if (length > sizeof(buffer))
175     length = sizeof(buffer);
176     status = fns->read(file, buffer, length, &result);
177     buffer_len = result;
178     }
179     break;
180    
181     case IRP_MJ_WRITE:
182     if (fns->write)
183     status = fns->write(file, s->p, length, &result);
184     break;
185    
186     case IRP_MJ_DEVICE_CONTROL:
187     if (fns->device_control)
188     {
189     in_uint32_le(s, bytes_out);
190     in_uint32_le(s, bytes_in);
191     in_uint32_le(s, request);
192     in_uint8s(s, 0x14);
193     out.data = out.p = buffer;
194     out.size = sizeof(buffer);
195     status = fns->device_control(file, request, s, &out);
196     result = buffer_len = out.p - out.data;
197     }
198     break;
199    
200     default:
201     unimpl("IRP major=0x%x minor=0x%x\n", major, minor);
202     break;
203     }
204    
205     rdpdr_send_completion(device, id, status, result, buffer, buffer_len);
206     }
207    
208     static void
209     rdpdr_process(STREAM s)
210     {
211     uint32 handle;
212 matthewc 536 uint8 *magic;
213 matthewc 432
214     printf("rdpdr_process\n");
215 astrand 435 hexdump(s->p, s->end - s->p);
216 matthewc 432 in_uint8p(s, magic, 4);
217    
218     if ((magic[0] == 'r') && (magic[1] == 'D'))
219     {
220     if ((magic[2] == 'R') && (magic[3] == 'I'))
221     {
222     rdpdr_process_irp(s);
223     return;
224     }
225     if ((magic[2] == 'n') && (magic[3] == 'I'))
226     {
227     rdpdr_send_connect();
228     rdpdr_send_name();
229     rdpdr_send_available();
230     return;
231     }
232     else if ((magic[2] == 'C') && (magic[3] == 'C'))
233     {
234     /* connect from server */
235     return;
236     }
237     else if ((magic[2] == 'r') && (magic[3] == 'd'))
238     {
239     /* connect to a specific resource */
240     in_uint32(s, handle);
241     printf("Server connected to resource %d\n", handle);
242     return;
243     }
244     }
245     unimpl("RDPDR packet type %c%c%c%c\n", magic[0], magic[1], magic[2], magic[3]);
246     }
247    
248     BOOL
249     rdpdr_init(void)
250     {
251 astrand 435 rdpdr_channel =
252     channel_register("rdpdr", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_COMPRESS_RDP,
253     rdpdr_process);
254 matthewc 432 return (rdpdr_channel != NULL);
255     }

  ViewVC Help
Powered by ViewVC 1.1.26