aboutsummaryrefslogtreecommitdiff
path: root/vboxshfl.h
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2022-04-11 04:36:49 +0200
committerJavier <dev.git@javispedro.com>2022-04-11 04:36:49 +0200
commit19231982b2f374aed286f4697aebd3fb9fda05d8 (patch)
tree1922eaf34af3d904ce0f75c0e812e8da8e0d38d4 /vboxshfl.h
parent970f90228a6978712c28529437721caffec76202 (diff)
downloadvbados-19231982b2f374aed286f4697aebd3fb9fda05d8.tar.gz
vbados-19231982b2f374aed286f4697aebd3fb9fda05d8.zip
add new virtualbox shared folders client
Diffstat (limited to 'vboxshfl.h')
-rw-r--r--vboxshfl.h423
1 files changed, 423 insertions, 0 deletions
diff --git a/vboxshfl.h b/vboxshfl.h
new file mode 100644
index 0000000..292b8a3
--- /dev/null
+++ b/vboxshfl.h
@@ -0,0 +1,423 @@
+/*
+ * VBMouse - VirtualBox Shared Folders service client functions
+ * Copyright (C) 2022 Javier S. Pedro
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef VBOXSHFL_H
+#define VBOXSHFL_H
+
+#include "vboxhgcm.h"
+
+#define SHFLSTRING_WITH_BUF(name, size) \
+ struct { \
+ SHFLSTRING shflstr; \
+ char buf[size]; \
+ } name = { {size, 0} }
+
+#define SHFLDIRINFO_WITH_BUF(name, size) \
+ struct { \
+ SHFLDIRINFO dirinfo; \
+ char buf[size]; \
+ } name
+
+static inline unsigned shflstring_size_with_buf(const SHFLSTRING *str)
+{
+ return sizeof(SHFLSTRING) + str->u16Size;
+}
+
+static inline unsigned shflstring_size_optional_in(const SHFLSTRING *str)
+{
+ if (str->u16Length > 0) {
+ return sizeof(SHFLSTRING) + str->u16Size;
+ } else {
+ return 0;
+ }
+}
+
+static inline void shflstring_clear(SHFLSTRING *str)
+{
+ str->u16Length = 0;
+}
+
+static void shflstring_strcpy(SHFLSTRING *str, const char __far *src)
+{
+ str->u16Length = MIN(_fstrlen(src), str->u16Size - 1);
+ _fmemcpy(str->ach, src, str->u16Length);
+ str->ach[str->u16Length] = '\0';
+}
+
+static void shflstring_strncpy(SHFLSTRING *str, const char __far *src, unsigned len)
+{
+ str->u16Length = MIN(len, str->u16Size - 1);
+ _fmemcpy(str->ach, src, str->u16Length);
+ str->ach[str->u16Length] = '\0';
+}
+
+static int32_t vbox_shfl_query_mappings(LPVBOXCOMM vb, hgcm_client_id_t client_id, uint32_t flags, unsigned __far *num_maps, SHFLMAPPING __far *maps)
+{
+ VMMDevHGCMCall __far *req = (void __far *) vb->buf;
+ vbox_hgcm_init_call(req, client_id, SHFL_FN_QUERY_MAPPINGS, 3);
+
+ req->aParms[0].type = VMMDevHGCMParmType_32bit;
+ req->aParms[0].u.value32 = flags;
+
+ req->aParms[1].type = VMMDevHGCMParmType_32bit;
+ req->aParms[1].u.value32 = *num_maps;
+
+ req->aParms[2].type = VMMDevHGCMParmType_LinAddr;
+ req->aParms[2].u.Pointer.size = sizeof(SHFLMAPPING) * *num_maps;
+ req->aParms[2].u.Pointer.u.linearAddr = linear_addr(maps);
+
+ vbox_send_request(vb->iobase, vb->dds.physicalAddress);
+
+ if (req->header.header.rc < 0) {
+ return req->header.header.rc;
+ } else if (req->header.header.rc == VINF_HGCM_ASYNC_EXECUTE) {
+ vbox_hgcm_wait(&req->header);
+ }
+
+ *num_maps = req->aParms[1].u.value32;
+
+ return req->header.result;
+}
+
+static int32_t vbox_shfl_query_map_name(LPVBOXCOMM vb, hgcm_client_id_t client_id, SHFLROOT root, SHFLSTRING *name)
+{
+ VMMDevHGCMCall __far *req = (void __far *) vb->buf;
+ vbox_hgcm_init_call(req, client_id, SHFL_FN_QUERY_MAP_NAME, 2);
+
+ req->aParms[0].type = VMMDevHGCMParmType_32bit;
+ req->aParms[0].u.value32 = root;
+
+ req->aParms[1].type = VMMDevHGCMParmType_LinAddr;
+ req->aParms[1].u.Pointer.size = shflstring_size_with_buf(name);
+ req->aParms[1].u.Pointer.u.linearAddr = linear_addr(name);
+
+ vbox_send_request(vb->iobase, vb->dds.physicalAddress);
+
+ if (req->header.header.rc < 0) {
+ return req->header.header.rc;
+ } else if (req->header.header.rc == VINF_HGCM_ASYNC_EXECUTE) {
+ vbox_hgcm_wait(&req->header);
+ }
+
+ return req->header.result;
+}
+
+static int32_t vbox_shfl_map_folder(LPVBOXCOMM vb, hgcm_client_id_t client_id, const SHFLSTRING *name, SHFLROOT *root)
+{
+ VMMDevHGCMCall __far *req = (void __far *) vb->buf;
+ vbox_hgcm_init_call(req, client_id, SHFL_FN_MAP_FOLDER, 4);
+
+ // arg 0 in shflstring "name"
+ req->aParms[0].type = VMMDevHGCMParmType_LinAddr;
+ req->aParms[0].u.Pointer.size = shflstring_size_with_buf(name);
+ req->aParms[0].u.Pointer.u.linearAddr = linear_addr(name);
+
+ // arg 1 out uint32 "root"
+ req->aParms[1].type = VMMDevHGCMParmType_32bit;
+ req->aParms[1].u.value32 = *root;
+
+ // arg 2 in uint32 "delimiter"
+ req->aParms[2].type = VMMDevHGCMParmType_32bit;
+ req->aParms[2].u.value32 = '\\';
+
+ // arg 3 in uint32 "caseSensitive"
+ req->aParms[3].type = VMMDevHGCMParmType_32bit;
+ req->aParms[3].u.value32 = 0;
+
+ vbox_send_request(vb->iobase, vb->dds.physicalAddress);
+
+ if (req->header.header.rc < 0) {
+ return req->header.header.rc;
+ } else if (req->header.header.rc == VINF_HGCM_ASYNC_EXECUTE) {
+ vbox_hgcm_wait(&req->header);
+ }
+
+ *root = req->aParms[1].u.value32;
+
+ return req->header.result;
+}
+
+static int32_t vbox_shfl_unmap_folder(LPVBOXCOMM vb, hgcm_client_id_t client_id, SHFLROOT root)
+{
+ VMMDevHGCMCall __far *req = (void __far *) vb->buf;
+ vbox_hgcm_init_call(req, client_id, SHFL_FN_UNMAP_FOLDER, 1);
+
+ // arg 0 in uint32 "root"
+ req->aParms[0].type = VMMDevHGCMParmType_32bit;
+ req->aParms[0].u.value32 = root;
+
+ vbox_send_request(vb->iobase, vb->dds.physicalAddress);
+
+ if (req->header.header.rc < 0) {
+ return req->header.header.rc;
+ } else if (req->header.header.rc == VINF_HGCM_ASYNC_EXECUTE) {
+ vbox_hgcm_wait(&req->header);
+ }
+
+ return req->header.result;
+}
+
+static int32_t vbox_shfl_open(LPVBOXCOMM vb, hgcm_client_id_t client_id, SHFLROOT root, const SHFLSTRING *name, SHFLCREATEPARMS *parms)
+{
+ VMMDevHGCMCall __far *req = (void __far *) vb->buf;
+ vbox_hgcm_init_call(req, client_id, SHFL_FN_CREATE, 3);
+
+ // arg 0 in uint32 "root"
+ req->aParms[0].type = VMMDevHGCMParmType_32bit;
+ req->aParms[0].u.value32 = root;
+
+ // arg 1 in shflstring "name"
+ req->aParms[1].type = VMMDevHGCMParmType_LinAddr;
+ req->aParms[1].u.Pointer.size = shflstring_size_with_buf(name);
+ req->aParms[1].u.Pointer.u.linearAddr = linear_addr(name);
+
+ // arg 2 in shflcreateparms "parms"
+ req->aParms[2].type = VMMDevHGCMParmType_LinAddr;
+ req->aParms[2].u.Pointer.size = sizeof(SHFLCREATEPARMS);
+ req->aParms[2].u.Pointer.u.linearAddr = linear_addr(parms);
+
+ vbox_send_request(vb->iobase, vb->dds.physicalAddress);
+
+ if (req->header.header.rc < 0) {
+ return req->header.header.rc;
+ } else if (req->header.header.rc == VINF_HGCM_ASYNC_EXECUTE) {
+ vbox_hgcm_wait(&req->header);
+ }
+
+ return req->header.result;
+}
+
+static int32_t vbox_shfl_close(LPVBOXCOMM vb, hgcm_client_id_t client_id, SHFLROOT root, SHFLHANDLE handle)
+{
+ VMMDevHGCMCall __far *req = (void __far *) vb->buf;
+ vbox_hgcm_init_call(req, client_id, SHFL_FN_CLOSE, 2);
+
+ // arg 0 in uint32 "root"
+ req->aParms[0].type = VMMDevHGCMParmType_32bit;
+ req->aParms[0].u.value32 = root;
+
+ // arg 1 in uint64 "handle"
+ req->aParms[1].type = VMMDevHGCMParmType_64bit;
+ req->aParms[1].u.value64 = handle;
+
+ vbox_send_request(vb->iobase, vb->dds.physicalAddress);
+
+ if (req->header.header.rc < 0) {
+ return req->header.header.rc;
+ } else if (req->header.header.rc == VINF_HGCM_ASYNC_EXECUTE) {
+ vbox_hgcm_wait(&req->header);
+ }
+
+ return req->header.result;
+}
+
+static int32_t vbox_shfl_read(LPVBOXCOMM vb, hgcm_client_id_t client_id, SHFLROOT root, SHFLHANDLE handle,
+ unsigned long offset, unsigned __far *size, void __far *buffer)
+{
+ VMMDevHGCMCall __far *req = (void __far *) vb->buf;
+ vbox_hgcm_init_call(req, client_id, SHFL_FN_READ, 5);
+
+ // arg 0 in uint32 "root"
+ req->aParms[0].type = VMMDevHGCMParmType_32bit;
+ req->aParms[0].u.value32 = root;
+
+ // arg 1 in uint64 "handle"
+ req->aParms[1].type = VMMDevHGCMParmType_64bit;
+ req->aParms[1].u.value64 = handle;
+
+ // arg 2 in uint64 "offset"
+ req->aParms[2].type = VMMDevHGCMParmType_64bit;
+ req->aParms[2].u.value64 = offset;
+
+ // arg 3 inout uint32 "size"
+ req->aParms[3].type = VMMDevHGCMParmType_32bit;
+ req->aParms[3].u.value32 = *size;
+
+ // arg 4 out void "buffer"
+ req->aParms[4].type = VMMDevHGCMParmType_LinAddr;
+ req->aParms[4].u.Pointer.size = *size;
+ req->aParms[4].u.Pointer.u.linearAddr = linear_addr(buffer);
+
+ vbox_send_request(vb->iobase, vb->dds.physicalAddress);
+
+ if (req->header.header.rc < 0) {
+ return req->header.header.rc;
+ } else if (req->header.header.rc == VINF_HGCM_ASYNC_EXECUTE) {
+ vbox_hgcm_wait(&req->header);
+ }
+
+ *size = req->aParms[3].u.value32;
+
+ return req->header.result;
+}
+
+static int32_t vbox_shfl_write(LPVBOXCOMM vb, hgcm_client_id_t client_id, SHFLROOT root, SHFLHANDLE handle,
+ unsigned long offset, unsigned __far *size, void __far *buffer)
+{
+ VMMDevHGCMCall __far *req = (void __far *) vb->buf;
+ vbox_hgcm_init_call(req, client_id, SHFL_FN_WRITE, 5);
+
+ // arg 0 in uint32 "root"
+ req->aParms[0].type = VMMDevHGCMParmType_32bit;
+ req->aParms[0].u.value32 = root;
+
+ // arg 1 in uint64 "handle"
+ req->aParms[1].type = VMMDevHGCMParmType_64bit;
+ req->aParms[1].u.value64 = handle;
+
+ // arg 2 in uint64 "offset"
+ req->aParms[2].type = VMMDevHGCMParmType_64bit;
+ req->aParms[2].u.value64 = offset;
+
+ // arg 3 inout uint32 "size"
+ req->aParms[3].type = VMMDevHGCMParmType_32bit;
+ req->aParms[3].u.value32 = *size;
+
+ // arg 4 in void "buffer"
+ req->aParms[4].type = VMMDevHGCMParmType_LinAddr;
+ req->aParms[4].u.Pointer.size = *size;
+ req->aParms[4].u.Pointer.u.linearAddr = linear_addr(buffer);
+
+ vbox_send_request(vb->iobase, vb->dds.physicalAddress);
+
+ if (req->header.header.rc < 0) {
+ return req->header.header.rc;
+ } else if (req->header.header.rc == VINF_HGCM_ASYNC_EXECUTE) {
+ vbox_hgcm_wait(&req->header);
+ }
+
+ *size = req->aParms[3].u.value32;
+
+ return req->header.result;
+}
+
+static int32_t vbox_shfl_list(LPVBOXCOMM vb, hgcm_client_id_t client_id, SHFLROOT root, SHFLHANDLE handle,
+ unsigned flags, unsigned __far *size, const SHFLSTRING *path, SHFLDIRINFO *dirinfo, unsigned __far *resume, unsigned __far *count)
+{
+ VMMDevHGCMCall __far *req = (void __far *) vb->buf;
+ vbox_hgcm_init_call(req, client_id, SHFL_FN_LIST, 8);
+
+ // arg 0 in uint32 "root"
+ req->aParms[0].type = VMMDevHGCMParmType_32bit;
+ req->aParms[0].u.value32 = root;
+
+ // arg 1 in uint64 "handle"
+ req->aParms[1].type = VMMDevHGCMParmType_64bit;
+ req->aParms[1].u.value64 = handle;
+
+ // arg 2 in uint32 "flags"
+ req->aParms[2].type = VMMDevHGCMParmType_32bit;
+ req->aParms[2].u.value32 = flags;
+
+ // arg 3 inout uint32 "size"
+ req->aParms[3].type = VMMDevHGCMParmType_32bit;
+ req->aParms[3].u.value32 = *size;
+
+ // arg 4 in shflstring "path"
+ req->aParms[4].type = VMMDevHGCMParmType_LinAddr;
+ req->aParms[4].u.Pointer.size = shflstring_size_optional_in(path);
+ req->aParms[4].u.Pointer.u.linearAddr = linear_addr(path);
+
+ // arg 5 out void "dirinfo"
+ req->aParms[5].type = VMMDevHGCMParmType_LinAddr;
+ req->aParms[5].u.Pointer.size = *size;
+ req->aParms[5].u.Pointer.u.linearAddr = linear_addr(dirinfo);
+
+ // arg 6 inout uint32 "resume_point"
+ req->aParms[6].type = VMMDevHGCMParmType_32bit;
+ req->aParms[6].u.value32 = *resume;
+
+ // arg 7 out uint32 "count"
+ req->aParms[7].type = VMMDevHGCMParmType_32bit;
+ req->aParms[7].u.value32 = 0;
+
+ vbox_send_request(vb->iobase, vb->dds.physicalAddress);
+
+ if (req->header.header.rc < 0) {
+ return req->header.header.rc;
+ } else if (req->header.header.rc == VINF_HGCM_ASYNC_EXECUTE) {
+ vbox_hgcm_wait(&req->header);
+ }
+
+ *size = req->aParms[3].u.value32;
+ *resume = req->aParms[6].u.value32;
+ *count = req->aParms[7].u.value32;
+
+ return req->header.result;
+}
+
+static int32_t vbox_shfl_set_utf8(LPVBOXCOMM vb, hgcm_client_id_t client_id)
+{
+ VMMDevHGCMCall __far *req = (void __far *) vb->buf;
+ vbox_hgcm_init_call(req, client_id, SHFL_FN_SET_UTF8, 0);
+
+ vbox_send_request(vb->iobase, vb->dds.physicalAddress);
+
+ if (req->header.header.rc < 0) {
+ return req->header.header.rc;
+ } else if (req->header.header.rc == VINF_HGCM_ASYNC_EXECUTE) {
+ vbox_hgcm_wait(&req->header);
+ }
+
+ return req->header.result;
+}
+
+static int32_t vbox_shfl_query_map_info(LPVBOXCOMM vb, hgcm_client_id_t client_id, SHFLROOT root,
+ SHFLSTRING *name, SHFLSTRING *mountPoint, unsigned *flags, unsigned *version)
+{
+ VMMDevHGCMCall __far *req = (void __far *) vb->buf;
+ vbox_hgcm_init_call(req, client_id, SHFL_FN_QUERY_MAP_INFO, 5);
+
+ // arg 0 in uint32 "root"
+ req->aParms[0].type = VMMDevHGCMParmType_32bit;
+ req->aParms[0].u.value32 = root;
+
+ // arg 1 inout shflstring "name"
+ req->aParms[1].type = VMMDevHGCMParmType_LinAddr;
+ req->aParms[1].u.Pointer.size = shflstring_size_with_buf(name);
+ req->aParms[1].u.Pointer.u.linearAddr = linear_addr(name);
+
+ // arg 2 inout shflstring "mountPoint"
+ req->aParms[2].type = VMMDevHGCMParmType_LinAddr;
+ req->aParms[2].u.Pointer.size = shflstring_size_with_buf(mountPoint);
+ req->aParms[2].u.Pointer.u.linearAddr = linear_addr(mountPoint);
+
+ // arg 3 inout uint64 "flags"
+ req->aParms[3].type = VMMDevHGCMParmType_64bit;
+ req->aParms[3].u.value64 = *flags;
+
+ // arg 4 out uint32 "version"
+ req->aParms[4].type = VMMDevHGCMParmType_32bit;
+ req->aParms[4].u.value32 = *version;
+
+ vbox_send_request(vb->iobase, vb->dds.physicalAddress);
+
+ if (req->header.header.rc < 0) {
+ return req->header.header.rc;
+ } else if (req->header.header.rc == VINF_HGCM_ASYNC_EXECUTE) {
+ vbox_hgcm_wait(&req->header);
+ }
+
+ *flags = req->aParms[3].u.value64;
+ *version = req->aParms[4].u.value32;
+
+ return req->header.result;
+}
+
+#endif // VBOXSHFL_H