rdpdr-fs.c (5379B)
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20#include "channels/rdpdr/rdpdr-fs.h" 21#include "channels/rdpdr/rdpdr-fs-messages.h" 22#include "channels/rdpdr/rdpdr.h" 23#include "rdp.h" 24 25#include <freerdp/channels/rdpdr.h> 26#include <freerdp/settings.h> 27#include <guacamole/client.h> 28#include <guacamole/unicode.h> 29#include <winpr/stream.h> 30 31#include <stddef.h> 32 33void guac_rdpdr_device_fs_iorequest_handler(guac_rdp_common_svc* svc, 34 guac_rdpdr_device* device, guac_rdpdr_iorequest* iorequest, 35 wStream* input_stream) { 36 37 switch (iorequest->major_func) { 38 39 /* File open */ 40 case IRP_MJ_CREATE: 41 guac_rdpdr_fs_process_create(svc, device, iorequest, input_stream); 42 break; 43 44 /* File close */ 45 case IRP_MJ_CLOSE: 46 guac_rdpdr_fs_process_close(svc, device, iorequest, input_stream); 47 break; 48 49 /* File read */ 50 case IRP_MJ_READ: 51 guac_rdpdr_fs_process_read(svc, device, iorequest, input_stream); 52 break; 53 54 /* File write */ 55 case IRP_MJ_WRITE: 56 guac_rdpdr_fs_process_write(svc, device, iorequest, input_stream); 57 break; 58 59 /* Device control request (Windows FSCTL_ control codes) */ 60 case IRP_MJ_DEVICE_CONTROL: 61 guac_rdpdr_fs_process_device_control(svc, device, iorequest, input_stream); 62 break; 63 64 /* Query volume (drive) information */ 65 case IRP_MJ_QUERY_VOLUME_INFORMATION: 66 guac_rdpdr_fs_process_volume_info(svc, device, iorequest, input_stream); 67 break; 68 69 /* Set volume (drive) information */ 70 case IRP_MJ_SET_VOLUME_INFORMATION: 71 guac_rdpdr_fs_process_set_volume_info(svc, device, iorequest, input_stream); 72 break; 73 74 /* Query file information */ 75 case IRP_MJ_QUERY_INFORMATION: 76 guac_rdpdr_fs_process_file_info(svc, device, iorequest, input_stream); 77 break; 78 79 /* Set file information */ 80 case IRP_MJ_SET_INFORMATION: 81 guac_rdpdr_fs_process_set_file_info(svc, device, iorequest, input_stream); 82 break; 83 84 case IRP_MJ_DIRECTORY_CONTROL: 85 86 /* Enumerate directory contents */ 87 if (iorequest->minor_func == IRP_MN_QUERY_DIRECTORY) 88 guac_rdpdr_fs_process_query_directory(svc, device, iorequest, 89 input_stream); 90 91 /* Request notification of changes to directory */ 92 else if (iorequest->minor_func == IRP_MN_NOTIFY_CHANGE_DIRECTORY) 93 guac_rdpdr_fs_process_notify_change_directory(svc, device, 94 iorequest, input_stream); 95 96 break; 97 98 /* Lock/unlock portions of a file */ 99 case IRP_MJ_LOCK_CONTROL: 100 guac_rdpdr_fs_process_lock_control(svc, device, iorequest, input_stream); 101 break; 102 103 default: 104 guac_client_log(svc->client, GUAC_LOG_DEBUG, 105 "Unknown filesystem I/O request function: 0x%x/0x%x", 106 iorequest->major_func, iorequest->minor_func); 107 } 108 109} 110 111void guac_rdpdr_device_fs_free_handler(guac_rdp_common_svc* svc, 112 guac_rdpdr_device* device) { 113 114 Stream_Free(device->device_announce, 1); 115 116} 117 118void guac_rdpdr_register_fs(guac_rdp_common_svc* svc, char* drive_name) { 119 120 guac_client* client = svc->client; 121 guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; 122 123 guac_rdpdr* rdpdr = (guac_rdpdr*) svc->data; 124 int id = rdpdr->devices_registered++; 125 126 /* Get new device */ 127 guac_rdpdr_device* device = &(rdpdr->devices[id]); 128 129 /* Init device */ 130 device->device_id = id; 131 device->device_name = drive_name; 132 int device_name_len = guac_utf8_strlen(device->device_name); 133 device->device_type = RDPDR_DTYP_FILESYSTEM; 134 device->dos_name = "GUACFS\0\0"; 135 136 /* Set up the device announcement */ 137 device->device_announce_len = 20 + device_name_len; 138 device->device_announce = Stream_New(NULL, device->device_announce_len); 139 Stream_Write_UINT32(device->device_announce, device->device_type); 140 Stream_Write_UINT32(device->device_announce, device->device_id); 141 Stream_Write(device->device_announce, device->dos_name, 8); 142 Stream_Write_UINT32(device->device_announce, device_name_len); 143 Stream_Write(device->device_announce, device->device_name, device_name_len); 144 145 146 /* Set handlers */ 147 device->iorequest_handler = guac_rdpdr_device_fs_iorequest_handler; 148 device->free_handler = guac_rdpdr_device_fs_free_handler; 149 150 /* Init data */ 151 device->data = rdp_client->filesystem; 152 153} 154