summaryrefslogtreecommitdiffstats
path: root/sesman/chansrv/devredir.h
blob: 231c2626ec9c22104ca20596f46f21e69058a965 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
/**
 * xrdp: A Remote Desktop Protocol server.
 *
 * xrdp device redirection - we mainly use it for drive redirection
 *
 * Copyright (C) Laxmikant Rashinkar 2013 LK.Rashinkar@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// LK_TODO dev_redir_xxx should become devredir_xxx

#if !defined(DEVREDIR_H)
#define DEVREDIR_H

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

#include "arch.h"
#include "parse.h"
#include "os_calls.h"
#include "log.h"
#include "chansrv_fuse.h"

typedef struct fuse_data FUSE_DATA;
struct fuse_data
{
    void      *data_ptr;
    FUSE_DATA *next;
};

/* An I/O Resource Packet to track dev_dir I/O calls */

typedef struct irp IRP;

struct irp
{
    tui32      completion_id;       /* unique number                     */
    char       completion_type;     /* describes I/O type                */
    tui32      FileId;              /* RDP client provided unique number */
    char       pathname[256];       /* absolute pathname                 */
    char       gen_buf[1024];       /* for general use                   */
    int        type;
    tui32      device_id;           /* identifies remote device          */
    FUSE_DATA *fd_head;             /* point to first FUSE opaque object */
    FUSE_DATA *fd_tail;             /* point to last FUSE opaque object  */
    IRP       *next;                /* point to next IRP                 */
    IRP       *prev;                /* point to previous IRP             */
};

void *dev_redir_fuse_data_peek(IRP *irp);
void *dev_redir_fuse_data_dequeue(IRP *irp);
int   dev_redir_fuse_data_enqueue(IRP *irp, void *vp);

IRP * dev_redir_irp_new();
IRP * dev_redir_irp_find(tui32 completion_id);
IRP * dev_redir_irp_find_by_fileid(tui32 FileId);
IRP * dev_redir_irp_get_last();
int   dev_redir_irp_delete(IRP *irp);
void  dev_redir_irp_dump();

int APP_CC dev_redir_init(void);
int APP_CC dev_redir_deinit(void);

int APP_CC dev_redir_data_in(struct stream* s, int chan_id, int chan_flags,
                             int length, int total_length);

int APP_CC dev_redir_get_wait_objs(tbus* objs, int* count, int* timeout);
int APP_CC dev_redir_check_wait_objs(void);

void dev_redir_send_server_core_cap_req();
void dev_redir_send_server_clientID_confirm();
void dev_redir_send_server_user_logged_on();
void dev_redir_send_server_device_announce_resp(tui32 device_id);

void dev_redir_send_drive_dir_request(IRP *irp, tui32 device_id,
                                      tui32 InitialQuery, char *Path);

int  dev_redir_send_drive_create_request(tui32 device_id, char *path,
                                         tui32 DesiredAccess,
                                         tui32 CreateOptions,
                                         tui32 CreateDisposition,
                                         tui32 completion_id);

int dev_redir_send_drive_close_request(tui16 Component, tui16 PacketId,
                                       tui32 DeviceId,
                                       tui32 FileId,
                                       tui32 CompletionId,
                                       tui32 MajorFunction,
                                       tui32 MinorFunc,
                                       int pad_len);

void dev_redir_proc_client_devlist_announce_req(struct stream *s);
void dev_redir_proc_client_core_cap_resp(struct stream *s);
void dev_redir_proc_device_iocompletion(struct stream *s);

void dev_redir_proc_query_dir_response(IRP *irp,
                                       struct stream *s,
                                       tui32 DeviceId,
                                       tui32 CompletionId,
                                       tui32 IoStatus);

/* misc stuff */
void dev_redir_insert_dev_io_req_header(struct stream *s,
                                        tui32 DeviceId,
                                        tui32 FileId,
                                        tui32 CompletionId,
                                        tui32 MajorFunction,
                                        tui32 MinorFunction);

void devredir_cvt_to_unicode(char *unicode, char *path);
void devredir_cvt_from_unicode_len(char *path, char *unicode, int len);
int  dev_redir_string_ends_with(char *string, char c);

void dev_redir_insert_rdpdr_header(struct stream *s, tui16 Component,
                                   tui16 PacketId);

void devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus);
void devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus);
void devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus);
void devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus);

/* called from FUSE module */
int dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path);

int dev_redir_file_open(void *fusep, tui32 device_id, char *path,
                        int mode, int type, char *gen_buf);

int devredir_file_close(void *fusep, tui32 device_id, tui32 file_id);

int dev_redir_file_read(void *fusep, tui32 device_id, tui32 FileId,
                        tui32 Length, tui64 Offset);

/* module based logging */
#define LOG_ERROR   0
#define LOG_INFO    1
#define LOG_DEBUG   2

#ifndef LOG_LEVEL
#define LOG_LEVEL   LOG_ERROR
#endif

#define log_error(_params...)                           \
{                                                       \
    g_write("[%10.10u]: DEV_REDIR  %s: %d : ERROR: ",   \
            g_time3(), __func__, __LINE__);             \
    g_writeln (_params);                                \
}

#define log_info(_params...)                            \
{                                                       \
    if (LOG_INFO <= LOG_LEVEL)                         \
    {                                                   \
        g_write("[%10.10u]: DEV_REDIR  %s: %d : ",      \
                g_time3(), __func__, __LINE__);         \
        g_writeln (_params);                            \
    }                                                   \
}

#define log_debug(_params...)                           \
{                                                       \
    if (LOG_DEBUG <= LOG_LEVEL)                        \
    {                                                   \
        g_write("[%10.10u]: DEV_REDIR  %s: %d : ",      \
                g_time3(), __func__, __LINE__);         \
        g_writeln (_params);                            \
    }                                                   \
}

int send_channel_data(int chan_id, char *data, int size);

/*
 * RDPDR_HEADER definitions
 */

/* device redirector core component; most of the packets in this protocol */
/* are sent under this component ID                                       */
#define RDPDR_CTYP_CORE                 0x4472

/* printing component. the packets that use this ID are typically about   */
/* printer cache management and identifying XPS printers                  */
#define RDPDR_CTYP_PRN                  0x5052

/* Server Announce Request, as specified in section 2.2.2.2               */
#define PAKID_CORE_SERVER_ANNOUNCE      0x496E

/* Client Announce Reply and Server Client ID Confirm, as specified in    */
/* sections 2.2.2.3 and 2.2.2.6.                                          */
#define PAKID_CORE_CLIENTID_CONFIRM     0x4343

/* Client Name Request, as specified in section 2.2.2.4                   */
#define PAKID_CORE_CLIENT_NAME          0x434E

/* Client Device List Announce Request, as specified in section 2.2.2.9   */
#define PAKID_CORE_DEVICELIST_ANNOUNCE  0x4441

/* Server Device Announce Response, as specified in section 2.2.2.1       */
#define PAKID_CORE_DEVICE_REPLY         0x6472

/* Device I/O Request, as specified in section 2.2.1.4                    */
#define PAKID_CORE_DEVICE_IOREQUEST     0x4952

/* Device I/O Response, as specified in section 2.2.1.5                   */
#define PAKID_CORE_DEVICE_IOCOMPLETION  0x4943

/* Server Core Capability Request, as specified in section 2.2.2.7        */
#define PAKID_CORE_SERVER_CAPABILITY    0x5350

/* Client Core Capability Response, as specified in section 2.2.2.8       */
#define PAKID_CORE_CLIENT_CAPABILITY    0x4350

/* Client Drive Device List Remove, as specified in section 2.2.3.2       */
#define PAKID_CORE_DEVICELIST_REMOVE    0x444D

/* Add Printer Cachedata, as specified in [MS-RDPEPC] section 2.2.2.3     */
#define PAKID_PRN_CACHE_DATA            0x5043

/* Server User Logged On, as specified in section 2.2.2.5                 */
#define PAKID_CORE_USER_LOGGEDON        0x554C

/* Server Printer Set XPS Mode, as specified in [MS-RDPEPC] section 2.2.2.2 */
#define PAKID_PRN_USING_XPS             0x5543

/*
 * Capability header definitions
 */

#define CAP_GENERAL_TYPE   0x0001 /* General cap set - GENERAL_CAPS_SET      */
#define CAP_PRINTER_TYPE   0x0002 /* Print cap set - PRINTER_CAPS_SET        */
#define CAP_PORT_TYPE      0x0003 /* Port cap set - PORT_CAPS_SET            */
#define CAP_DRIVE_TYPE     0x0004 /* Drive cap set - DRIVE_CAPS_SET          */
#define CAP_SMARTCARD_TYPE 0x0005 /* Smart card cap set - SMARTCARD_CAPS_SET */

/* client minor versions */
#define RDP_CLIENT_50                   0x0002
#define RDP_CLIENT_51                   0x0005
#define RDP_CLIENT_52                   0x000a
#define RDP_CLIENT_60_61                0x000c

/* used in device announce list */
#define RDPDR_DTYP_SERIAL               0x0001
#define RDPDR_DTYP_PARALLEL             0x0002
#define RDPDR_DTYP_PRINT                0x0004
#define RDPDR_DTYP_FILESYSTEM           0x0008
#define RDPDR_DTYP_SMARTCARD            0x0020

/*
 * DesiredAccess Mask [MS-SMB2] section 2.2.13.1.1
 */

#define DA_FILE_READ_DATA               0x00000001
#define DA_FILE_WRITE_DATA              0x00000002
#define DA_FILE_APPEND_DATA             0x00000004
#define DA_FILE_READ_EA                 0x00000008 /* rd extended attributes */
#define DA_FILE_WRITE_EA                0x00000010 /* wr extended attributes */
#define DA_FILE_EXECUTE                 0x00000020
#define DA_FILE_READ_ATTRIBUTES         0x00000080
#define DA_FILE_WRITE_ATTRIBUTES        0x00000100
#define DA_DELETE                       0x00010000
#define DA_READ_CONTROL                 0x00020000 /* rd security descriptor */
#define DA_WRITE_DAC                    0x00040000
#define DA_WRITE_OWNER                  0x00080000
#define DA_SYNCHRONIZE                  0x00100000
#define DA_ACCESS_SYSTEM_SECURITY       0x01000000
#define DA_MAXIMUM_ALLOWED              0x02000000
#define DA_GENERIC_ALL                  0x10000000
#define DA_GENERIC_EXECUTE              0x20000000
#define DA_GENERIC_WRITE                0x40000000
#define DA_GENERIC_READ                 0x80000000

/*
 * CreateOptions Mask [MS-SMB2] section 2.2.13 SMB2 CREATE Request
 */

enum CREATE_OPTIONS
{
    CO_FILE_DIRECTORY_FILE          = 0x00000001,
    CO_FILE_WRITE_THROUGH           = 0x00000002,
    CO_FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020,
    CO_FILE_DELETE_ON_CLOSE         = 0x00001000
};

/*
 * CreateDispositions Mask [MS-SMB2] section 2.2.13
 */

#define CD_FILE_SUPERSEDE               0x00000000
#define CD_FILE_OPEN                    0x00000001
#define CD_FILE_CREATE                  0x00000002
#define CD_FILE_OPEN_IF                 0x00000003
#define CD_FILE_OVERWRITE               0x00000004
#define CD_FILE_OVERWRITE_IF            0x00000005

/*
 * Device I/O Request MajorFunction definitions
 */

#define IRP_MJ_CREATE                   0x00000000
#define IRP_MJ_CLOSE                    0x00000002
#define IRP_MJ_READ                     0x00000003
#define IRP_MJ_WRITE                    0x00000004
#define IRP_MJ_DEVICE_CONTROL           0x0000000E
#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0000000A
#define IRP_MJ_SET_VOLUME_INFORMATION   0x0000000B
#define IRP_MJ_QUERY_INFORMATION        0x00000005
#define IRP_MJ_SET_INFORMATION          0x00000006
#define IRP_MJ_DIRECTORY_CONTROL        0x0000000C
#define IRP_MJ_LOCK_CONTROL             0x00000011

/*
 * Device I/O Request MinorFunction definitions
 *
 * Only valid when MajorFunction code = IRP_MJ_DIRECTORY_CONTROL
 */

#define IRP_MN_QUERY_DIRECTORY          0x00000001
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY  0x00000002

/*
 * NTSTATUS codes (used by IoStatus)
 */

#define NT_STATUS_SUCCESS               0x00000000
#define NT_STATUS_UNSUCCESSFUL          0xC0000001

/*
 * File system ioctl codes
 * MS-FSCC section 2.3 FSCTL Structures
 */
#define FSCTL_DELETE_OBJECT_ID          0x900a0


/*
 * CompletionID types, used in IRPs to indicate I/O operation
 */

enum COMPLETION_ID
{
    CID_CREATE_DIR_REQ = 1,
    CID_DIRECTORY_CONTROL,
    CID_CREATE_OPEN_REQ,
    CID_READ,
    CID_WRITE,
    CID_CLOSE,
    CID_FILE_CLOSE,
    CID_RMDIR_OR_FILE,
    CID_RMDIR_OR_FILE_RESP,
    CID_RENAME_FILE,
    CID_RENAME_FILE_RESP
};

enum FS_INFORMATION_CLASS
{
    FileBasicInformation       = 0x00000004, /* set atime, mtime, ctime etc */
    FileEndOfFileInformation   = 0x00000014, /* set EOF info                */
    FileDispositionInformation = 0x0000000D, /* mark a file for deletion    */
    FileRenameInformation      = 0x0000000A, /* rename a file               */
    FileAllocationInformation  = 0x00000013  /* set file allocation size    */
};

/*
 * constants for drive dir query
 */

/* Basic information about a file or directory. Basic information is       */
/* defined as the file's name, time stamp, and size, or its attributes     */
#define FileDirectoryInformation        0x00000001

/* Full information about a file or directory. Full information is defined */
/* as all the basic information, plus extended attribute size.             */
#define FileFullDirectoryInformation    0x00000002

/* Basic information plus extended attribute size and short name           */
/* about a file or directory.                                              */
#define FileBothDirectoryInformation    0x00000003

/* Detailed information on the names of files in a directory.              */
#define FileNamesInformation            0x0000000C

/*
 * NTSTATUS Codes of interest to us
 */

/* No more files were found which match the file specification             */
#define STATUS_NO_MORE_FILES            0x80000006

/* Windows file attributes */
#define W_FILE_ATTRIBUTE_DIRECTORY      0x00000010
#define W_FILE_ATTRIBUTE_READONLY       0x00000001

#define WINDOWS_TO_LINUX_FILE_PERM(_a) \
            (((_a) & W_FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR | 0100 : S_IFREG) |\
            (((_a) & W_FILE_ATTRIBUTE_READONLY)  ? 0444 : 0644)

/* winodws time starts on Jan 1, 1601 */
/* Linux   time starts on Jan 1, 1970 */
#define EPOCH_DIFF 11644473600LL
#define WINDOWS_TO_LINUX_TIME(_t) ((_t) / 10000000) - EPOCH_DIFF;

#define OP_RENAME_FILE                  0x01

#endif