18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: MIT 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Wrapper functions for the shfl host calls. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2006-2018 Oracle Corporation 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/mm.h> 98c2ecf20Sopenharmony_ci#include <linux/slab.h> 108c2ecf20Sopenharmony_ci#include <linux/vbox_err.h> 118c2ecf20Sopenharmony_ci#include <linux/vbox_utils.h> 128c2ecf20Sopenharmony_ci#include "vfsmod.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define SHFL_REQUEST \ 158c2ecf20Sopenharmony_ci (VMMDEV_REQUESTOR_KERNEL | VMMDEV_REQUESTOR_USR_DRV_OTHER | \ 168c2ecf20Sopenharmony_ci VMMDEV_REQUESTOR_CON_DONT_KNOW | VMMDEV_REQUESTOR_TRUST_NOT_GIVEN) 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_cistatic u32 vboxsf_client_id; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ciint vboxsf_connect(void) 218c2ecf20Sopenharmony_ci{ 228c2ecf20Sopenharmony_ci struct vbg_dev *gdev; 238c2ecf20Sopenharmony_ci struct vmmdev_hgcm_service_location loc; 248c2ecf20Sopenharmony_ci int err, vbox_status; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci loc.type = VMMDEV_HGCM_LOC_LOCALHOST_EXISTING; 278c2ecf20Sopenharmony_ci strcpy(loc.u.localhost.service_name, "VBoxSharedFolders"); 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci gdev = vbg_get_gdev(); 308c2ecf20Sopenharmony_ci if (IS_ERR(gdev)) 318c2ecf20Sopenharmony_ci return -ENODEV; /* No guest-device */ 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci err = vbg_hgcm_connect(gdev, SHFL_REQUEST, &loc, 348c2ecf20Sopenharmony_ci &vboxsf_client_id, &vbox_status); 358c2ecf20Sopenharmony_ci vbg_put_gdev(gdev); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci return err ? err : vbg_status_code_to_errno(vbox_status); 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_civoid vboxsf_disconnect(void) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci struct vbg_dev *gdev; 438c2ecf20Sopenharmony_ci int vbox_status; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci gdev = vbg_get_gdev(); 468c2ecf20Sopenharmony_ci if (IS_ERR(gdev)) 478c2ecf20Sopenharmony_ci return; /* guest-device is gone, already disconnected */ 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci vbg_hgcm_disconnect(gdev, SHFL_REQUEST, vboxsf_client_id, &vbox_status); 508c2ecf20Sopenharmony_ci vbg_put_gdev(gdev); 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistatic int vboxsf_call(u32 function, void *parms, u32 parm_count, int *status) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci struct vbg_dev *gdev; 568c2ecf20Sopenharmony_ci int err, vbox_status; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci gdev = vbg_get_gdev(); 598c2ecf20Sopenharmony_ci if (IS_ERR(gdev)) 608c2ecf20Sopenharmony_ci return -ESHUTDOWN; /* guest-dev removed underneath us */ 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci err = vbg_hgcm_call(gdev, SHFL_REQUEST, vboxsf_client_id, function, 638c2ecf20Sopenharmony_ci U32_MAX, parms, parm_count, &vbox_status); 648c2ecf20Sopenharmony_ci vbg_put_gdev(gdev); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci if (err < 0) 678c2ecf20Sopenharmony_ci return err; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci if (status) 708c2ecf20Sopenharmony_ci *status = vbox_status; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci return vbg_status_code_to_errno(vbox_status); 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ciint vboxsf_map_folder(struct shfl_string *folder_name, u32 *root) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci struct shfl_map_folder parms; 788c2ecf20Sopenharmony_ci int err, status; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL; 818c2ecf20Sopenharmony_ci parms.path.u.pointer.size = shfl_string_buf_size(folder_name); 828c2ecf20Sopenharmony_ci parms.path.u.pointer.u.linear_addr = (uintptr_t)folder_name; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 858c2ecf20Sopenharmony_ci parms.root.u.value32 = 0; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci parms.delimiter.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 888c2ecf20Sopenharmony_ci parms.delimiter.u.value32 = '/'; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci parms.case_sensitive.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 918c2ecf20Sopenharmony_ci parms.case_sensitive.u.value32 = 1; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci err = vboxsf_call(SHFL_FN_MAP_FOLDER, &parms, SHFL_CPARMS_MAP_FOLDER, 948c2ecf20Sopenharmony_ci &status); 958c2ecf20Sopenharmony_ci if (err == -ENOSYS && status == VERR_NOT_IMPLEMENTED) 968c2ecf20Sopenharmony_ci vbg_err("%s: Error host is too old\n", __func__); 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci *root = parms.root.u.value32; 998c2ecf20Sopenharmony_ci return err; 1008c2ecf20Sopenharmony_ci} 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ciint vboxsf_unmap_folder(u32 root) 1038c2ecf20Sopenharmony_ci{ 1048c2ecf20Sopenharmony_ci struct shfl_unmap_folder parms; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 1078c2ecf20Sopenharmony_ci parms.root.u.value32 = root; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci return vboxsf_call(SHFL_FN_UNMAP_FOLDER, &parms, 1108c2ecf20Sopenharmony_ci SHFL_CPARMS_UNMAP_FOLDER, NULL); 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci/** 1148c2ecf20Sopenharmony_ci * vboxsf_create - Create a new file or folder 1158c2ecf20Sopenharmony_ci * @root: Root of the shared folder in which to create the file 1168c2ecf20Sopenharmony_ci * @parsed_path: The path of the file or folder relative to the shared folder 1178c2ecf20Sopenharmony_ci * @param: create_parms Parameters for file/folder creation. 1188c2ecf20Sopenharmony_ci * 1198c2ecf20Sopenharmony_ci * Create a new file or folder or open an existing one in a shared folder. 1208c2ecf20Sopenharmony_ci * Note this function always returns 0 / success unless an exceptional condition 1218c2ecf20Sopenharmony_ci * occurs - out of memory, invalid arguments, etc. If the file or folder could 1228c2ecf20Sopenharmony_ci * not be opened or created, create_parms->handle will be set to 1238c2ecf20Sopenharmony_ci * SHFL_HANDLE_NIL on return. In this case the value in create_parms->result 1248c2ecf20Sopenharmony_ci * provides information as to why (e.g. SHFL_FILE_EXISTS), create_parms->result 1258c2ecf20Sopenharmony_ci * is also set on success as additional information. 1268c2ecf20Sopenharmony_ci * 1278c2ecf20Sopenharmony_ci * Returns: 1288c2ecf20Sopenharmony_ci * 0 or negative errno value. 1298c2ecf20Sopenharmony_ci */ 1308c2ecf20Sopenharmony_ciint vboxsf_create(u32 root, struct shfl_string *parsed_path, 1318c2ecf20Sopenharmony_ci struct shfl_createparms *create_parms) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci struct shfl_create parms; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 1368c2ecf20Sopenharmony_ci parms.root.u.value32 = root; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL; 1398c2ecf20Sopenharmony_ci parms.path.u.pointer.size = shfl_string_buf_size(parsed_path); 1408c2ecf20Sopenharmony_ci parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci parms.parms.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL; 1438c2ecf20Sopenharmony_ci parms.parms.u.pointer.size = sizeof(struct shfl_createparms); 1448c2ecf20Sopenharmony_ci parms.parms.u.pointer.u.linear_addr = (uintptr_t)create_parms; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci return vboxsf_call(SHFL_FN_CREATE, &parms, SHFL_CPARMS_CREATE, NULL); 1478c2ecf20Sopenharmony_ci} 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ciint vboxsf_close(u32 root, u64 handle) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci struct shfl_close parms; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 1548c2ecf20Sopenharmony_ci parms.root.u.value32 = root; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT; 1578c2ecf20Sopenharmony_ci parms.handle.u.value64 = handle; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci return vboxsf_call(SHFL_FN_CLOSE, &parms, SHFL_CPARMS_CLOSE, NULL); 1608c2ecf20Sopenharmony_ci} 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ciint vboxsf_remove(u32 root, struct shfl_string *parsed_path, u32 flags) 1638c2ecf20Sopenharmony_ci{ 1648c2ecf20Sopenharmony_ci struct shfl_remove parms; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 1678c2ecf20Sopenharmony_ci parms.root.u.value32 = root; 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN; 1708c2ecf20Sopenharmony_ci parms.path.u.pointer.size = shfl_string_buf_size(parsed_path); 1718c2ecf20Sopenharmony_ci parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 1748c2ecf20Sopenharmony_ci parms.flags.u.value32 = flags; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci return vboxsf_call(SHFL_FN_REMOVE, &parms, SHFL_CPARMS_REMOVE, NULL); 1778c2ecf20Sopenharmony_ci} 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ciint vboxsf_rename(u32 root, struct shfl_string *src_path, 1808c2ecf20Sopenharmony_ci struct shfl_string *dest_path, u32 flags) 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci struct shfl_rename parms; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 1858c2ecf20Sopenharmony_ci parms.root.u.value32 = root; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci parms.src.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN; 1888c2ecf20Sopenharmony_ci parms.src.u.pointer.size = shfl_string_buf_size(src_path); 1898c2ecf20Sopenharmony_ci parms.src.u.pointer.u.linear_addr = (uintptr_t)src_path; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci parms.dest.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN; 1928c2ecf20Sopenharmony_ci parms.dest.u.pointer.size = shfl_string_buf_size(dest_path); 1938c2ecf20Sopenharmony_ci parms.dest.u.pointer.u.linear_addr = (uintptr_t)dest_path; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 1968c2ecf20Sopenharmony_ci parms.flags.u.value32 = flags; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci return vboxsf_call(SHFL_FN_RENAME, &parms, SHFL_CPARMS_RENAME, NULL); 1998c2ecf20Sopenharmony_ci} 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ciint vboxsf_read(u32 root, u64 handle, u64 offset, u32 *buf_len, u8 *buf) 2028c2ecf20Sopenharmony_ci{ 2038c2ecf20Sopenharmony_ci struct shfl_read parms; 2048c2ecf20Sopenharmony_ci int err; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 2078c2ecf20Sopenharmony_ci parms.root.u.value32 = root; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT; 2108c2ecf20Sopenharmony_ci parms.handle.u.value64 = handle; 2118c2ecf20Sopenharmony_ci parms.offset.type = VMMDEV_HGCM_PARM_TYPE_64BIT; 2128c2ecf20Sopenharmony_ci parms.offset.u.value64 = offset; 2138c2ecf20Sopenharmony_ci parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 2148c2ecf20Sopenharmony_ci parms.cb.u.value32 = *buf_len; 2158c2ecf20Sopenharmony_ci parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT; 2168c2ecf20Sopenharmony_ci parms.buffer.u.pointer.size = *buf_len; 2178c2ecf20Sopenharmony_ci parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci err = vboxsf_call(SHFL_FN_READ, &parms, SHFL_CPARMS_READ, NULL); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci *buf_len = parms.cb.u.value32; 2228c2ecf20Sopenharmony_ci return err; 2238c2ecf20Sopenharmony_ci} 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ciint vboxsf_write(u32 root, u64 handle, u64 offset, u32 *buf_len, u8 *buf) 2268c2ecf20Sopenharmony_ci{ 2278c2ecf20Sopenharmony_ci struct shfl_write parms; 2288c2ecf20Sopenharmony_ci int err; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 2318c2ecf20Sopenharmony_ci parms.root.u.value32 = root; 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT; 2348c2ecf20Sopenharmony_ci parms.handle.u.value64 = handle; 2358c2ecf20Sopenharmony_ci parms.offset.type = VMMDEV_HGCM_PARM_TYPE_64BIT; 2368c2ecf20Sopenharmony_ci parms.offset.u.value64 = offset; 2378c2ecf20Sopenharmony_ci parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 2388c2ecf20Sopenharmony_ci parms.cb.u.value32 = *buf_len; 2398c2ecf20Sopenharmony_ci parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN; 2408c2ecf20Sopenharmony_ci parms.buffer.u.pointer.size = *buf_len; 2418c2ecf20Sopenharmony_ci parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci err = vboxsf_call(SHFL_FN_WRITE, &parms, SHFL_CPARMS_WRITE, NULL); 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci *buf_len = parms.cb.u.value32; 2468c2ecf20Sopenharmony_ci return err; 2478c2ecf20Sopenharmony_ci} 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci/* Returns 0 on success, 1 on end-of-dir, negative errno otherwise */ 2508c2ecf20Sopenharmony_ciint vboxsf_dirinfo(u32 root, u64 handle, 2518c2ecf20Sopenharmony_ci struct shfl_string *parsed_path, u32 flags, u32 index, 2528c2ecf20Sopenharmony_ci u32 *buf_len, struct shfl_dirinfo *buf, u32 *file_count) 2538c2ecf20Sopenharmony_ci{ 2548c2ecf20Sopenharmony_ci struct shfl_list parms; 2558c2ecf20Sopenharmony_ci int err, status; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 2588c2ecf20Sopenharmony_ci parms.root.u.value32 = root; 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT; 2618c2ecf20Sopenharmony_ci parms.handle.u.value64 = handle; 2628c2ecf20Sopenharmony_ci parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 2638c2ecf20Sopenharmony_ci parms.flags.u.value32 = flags; 2648c2ecf20Sopenharmony_ci parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 2658c2ecf20Sopenharmony_ci parms.cb.u.value32 = *buf_len; 2668c2ecf20Sopenharmony_ci if (parsed_path) { 2678c2ecf20Sopenharmony_ci parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN; 2688c2ecf20Sopenharmony_ci parms.path.u.pointer.size = shfl_string_buf_size(parsed_path); 2698c2ecf20Sopenharmony_ci parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path; 2708c2ecf20Sopenharmony_ci } else { 2718c2ecf20Sopenharmony_ci parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_IN; 2728c2ecf20Sopenharmony_ci parms.path.u.pointer.size = 0; 2738c2ecf20Sopenharmony_ci parms.path.u.pointer.u.linear_addr = 0; 2748c2ecf20Sopenharmony_ci } 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT; 2778c2ecf20Sopenharmony_ci parms.buffer.u.pointer.size = *buf_len; 2788c2ecf20Sopenharmony_ci parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci parms.resume_point.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 2818c2ecf20Sopenharmony_ci parms.resume_point.u.value32 = index; 2828c2ecf20Sopenharmony_ci parms.file_count.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 2838c2ecf20Sopenharmony_ci parms.file_count.u.value32 = 0; /* out parameter only */ 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci err = vboxsf_call(SHFL_FN_LIST, &parms, SHFL_CPARMS_LIST, &status); 2868c2ecf20Sopenharmony_ci if (err == -ENODATA && status == VERR_NO_MORE_FILES) 2878c2ecf20Sopenharmony_ci err = 1; 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci *buf_len = parms.cb.u.value32; 2908c2ecf20Sopenharmony_ci *file_count = parms.file_count.u.value32; 2918c2ecf20Sopenharmony_ci return err; 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ciint vboxsf_fsinfo(u32 root, u64 handle, u32 flags, 2958c2ecf20Sopenharmony_ci u32 *buf_len, void *buf) 2968c2ecf20Sopenharmony_ci{ 2978c2ecf20Sopenharmony_ci struct shfl_information parms; 2988c2ecf20Sopenharmony_ci int err; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 3018c2ecf20Sopenharmony_ci parms.root.u.value32 = root; 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT; 3048c2ecf20Sopenharmony_ci parms.handle.u.value64 = handle; 3058c2ecf20Sopenharmony_ci parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 3068c2ecf20Sopenharmony_ci parms.flags.u.value32 = flags; 3078c2ecf20Sopenharmony_ci parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 3088c2ecf20Sopenharmony_ci parms.cb.u.value32 = *buf_len; 3098c2ecf20Sopenharmony_ci parms.info.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL; 3108c2ecf20Sopenharmony_ci parms.info.u.pointer.size = *buf_len; 3118c2ecf20Sopenharmony_ci parms.info.u.pointer.u.linear_addr = (uintptr_t)buf; 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci err = vboxsf_call(SHFL_FN_INFORMATION, &parms, SHFL_CPARMS_INFORMATION, 3148c2ecf20Sopenharmony_ci NULL); 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci *buf_len = parms.cb.u.value32; 3178c2ecf20Sopenharmony_ci return err; 3188c2ecf20Sopenharmony_ci} 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ciint vboxsf_readlink(u32 root, struct shfl_string *parsed_path, 3218c2ecf20Sopenharmony_ci u32 buf_len, u8 *buf) 3228c2ecf20Sopenharmony_ci{ 3238c2ecf20Sopenharmony_ci struct shfl_readLink parms; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 3268c2ecf20Sopenharmony_ci parms.root.u.value32 = root; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN; 3298c2ecf20Sopenharmony_ci parms.path.u.pointer.size = shfl_string_buf_size(parsed_path); 3308c2ecf20Sopenharmony_ci parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path; 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT; 3338c2ecf20Sopenharmony_ci parms.buffer.u.pointer.size = buf_len; 3348c2ecf20Sopenharmony_ci parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci return vboxsf_call(SHFL_FN_READLINK, &parms, SHFL_CPARMS_READLINK, 3378c2ecf20Sopenharmony_ci NULL); 3388c2ecf20Sopenharmony_ci} 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ciint vboxsf_symlink(u32 root, struct shfl_string *new_path, 3418c2ecf20Sopenharmony_ci struct shfl_string *old_path, struct shfl_fsobjinfo *buf) 3428c2ecf20Sopenharmony_ci{ 3438c2ecf20Sopenharmony_ci struct shfl_symlink parms; 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT; 3468c2ecf20Sopenharmony_ci parms.root.u.value32 = root; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci parms.new_path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN; 3498c2ecf20Sopenharmony_ci parms.new_path.u.pointer.size = shfl_string_buf_size(new_path); 3508c2ecf20Sopenharmony_ci parms.new_path.u.pointer.u.linear_addr = (uintptr_t)new_path; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci parms.old_path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN; 3538c2ecf20Sopenharmony_ci parms.old_path.u.pointer.size = shfl_string_buf_size(old_path); 3548c2ecf20Sopenharmony_ci parms.old_path.u.pointer.u.linear_addr = (uintptr_t)old_path; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci parms.info.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT; 3578c2ecf20Sopenharmony_ci parms.info.u.pointer.size = sizeof(struct shfl_fsobjinfo); 3588c2ecf20Sopenharmony_ci parms.info.u.pointer.u.linear_addr = (uintptr_t)buf; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci return vboxsf_call(SHFL_FN_SYMLINK, &parms, SHFL_CPARMS_SYMLINK, NULL); 3618c2ecf20Sopenharmony_ci} 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_ciint vboxsf_set_utf8(void) 3648c2ecf20Sopenharmony_ci{ 3658c2ecf20Sopenharmony_ci return vboxsf_call(SHFL_FN_SET_UTF8, NULL, 0, NULL); 3668c2ecf20Sopenharmony_ci} 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ciint vboxsf_set_symlinks(void) 3698c2ecf20Sopenharmony_ci{ 3708c2ecf20Sopenharmony_ci return vboxsf_call(SHFL_FN_SET_SYMLINKS, NULL, 0, NULL); 3718c2ecf20Sopenharmony_ci} 372