aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--int21dos.h10
-rw-r--r--mousetsr.h7
-rw-r--r--mousmain.c2
-rw-r--r--sfmain.c2
-rw-r--r--sftsr.c109
-rw-r--r--sftsr.h7
-rw-r--r--vbox.c28
-rw-r--r--vbox.h15
-rw-r--r--vboxdev.h51
9 files changed, 161 insertions, 70 deletions
diff --git a/int21dos.h b/int21dos.h
index a76c2c5..329ef8b 100644
--- a/int21dos.h
+++ b/int21dos.h
@@ -354,11 +354,11 @@ enum DOS_REDIR_SUBFUNCTION {
};
enum OPENEX_ACTIONS {
- OPENEX_FAIL_IF_EXISTS = 0x0000,
- OPENEX_OPEN_IF_EXISTS = 0x0001,
- OPENEX_REPLACE_IF_EXISTS = 0x0002,
- OPENEX_FAIL_IF_NEW = 0x0000,
- OPENEX_CREATE_IF_NEW = 0x0100,
+ OPENEX_FAIL_IF_EXISTS = 0x00,
+ OPENEX_OPEN_IF_EXISTS = 0x01,
+ OPENEX_REPLACE_IF_EXISTS = 0x02,
+ OPENEX_FAIL_IF_NEW = 0x00,
+ OPENEX_CREATE_IF_NEW = 0x10,
};
enum OPENEX_MODE {
diff --git a/mousetsr.h b/mousetsr.h
index 5958505..f3f6785 100644
--- a/mousetsr.h
+++ b/mousetsr.h
@@ -58,6 +58,10 @@
#if USE_VIRTUALBOX
#include "vbox.h"
+
+/** Size of the VBox buffer. The maximum message length that may be sent.
+ * Enough to fit a set_pointer_shape message with a 16x16 cursor. */
+#define VBOX_BUFFER_SIZE (1024 + 32 + 24 + 20)
#endif
struct point {
@@ -188,11 +192,12 @@ typedef struct tsrdata {
/** Have VirtualBox absolute coordinates. */
bool vbhaveabs : 1;
struct vboxcomm vb;
+ char vbbuf[VBOX_BUFFER_SIZE];
#endif
#if USE_VMWARE
/** VMware is available. */
- bool vmwavail : 1;
+ bool vmwavail;
#endif
} TSRDATA;
diff --git a/mousmain.c b/mousmain.c
index e86a192..80a62fd 100644
--- a/mousmain.c
+++ b/mousmain.c
@@ -98,7 +98,7 @@ static int set_virtualbox_integration(LPTSRDATA data, bool enable)
return err;
}
- err = vbox_init_buffer(&data->vb);
+ err = vbox_init_buffer(&data->vb, VBOX_BUFFER_SIZE);
if (err) {
fprintf(stderr, "Cannot lock buffer used for VirtualBox communication, err=%d\n", err);
return err;
diff --git a/sfmain.c b/sfmain.c
index d49f823..eadb7ae 100644
--- a/sfmain.c
+++ b/sfmain.c
@@ -353,7 +353,7 @@ static int configure_driver(LPTSRDATA data)
return -1;
}
- err = vbox_init_buffer(&data->vb);
+ err = vbox_init_buffer(&data->vb, VBOX_BUFFER_SIZE);
if (err) {
fprintf(stderr, "Cannot lock buffer used for VirtualBox communication, err=%ld\n", err);
return -1;
diff --git a/sftsr.c b/sftsr.c
index 0e86930..37be41a 100644
--- a/sftsr.c
+++ b/sftsr.c
@@ -33,7 +33,10 @@ static SHFLSTRING_WITH_BUF(shflstr, SHFL_MAX_LEN);
static SHFLDIRINFO_WITH_NAME_BUF(shfldirinfo, SHFL_MAX_LEN);
-static SHFLCREATEPARMS createparms;
+static union {
+ SHFLVOLINFO volinfo;
+ SHFLCREATEPARMS create;
+} parms;
static uint8_t map_shfl_attr_to_dosattr(const SHFLFSOBJATTR *a)
{
@@ -366,50 +369,50 @@ static void handle_create_open_ex(union INTPACK __far *r)
copy_drive_relative_filename(&shflstr.shflstr, path);
translate_filename_to_host(&shflstr.shflstr);
- memset(&createparms, 0, sizeof(SHFLCREATEPARMS));
+ memset(&parms.create, 0, sizeof(SHFLCREATEPARMS));
if (action & OPENEX_REPLACE_IF_EXISTS) {
- createparms.CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS;
+ parms.create.CreateFlags |= SHFL_CF_ACT_REPLACE_IF_EXISTS;
} else if (action & OPENEX_OPEN_IF_EXISTS) {
- createparms.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
+ parms.create.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
} else {
- createparms.CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS;
+ parms.create.CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS;
}
if (action & OPENEX_CREATE_IF_NEW) {
- createparms.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW;
+ parms.create.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW;
} else {
- createparms.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
+ parms.create.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
}
if ((mode & OPENEX_MODE_RDWR) == OPENEX_MODE_RDWR) {
- createparms.CreateFlags |= SHFL_CF_ACCESS_READWRITE;
+ parms.create.CreateFlags |= SHFL_CF_ACCESS_READWRITE;
} else if (mode & OPENEX_MODE_WRITE) {
- createparms.CreateFlags |= SHFL_CF_ACCESS_WRITE;
+ parms.create.CreateFlags |= SHFL_CF_ACCESS_WRITE;
} else {
- createparms.CreateFlags |= SHFL_CF_ACCESS_READ;
+ parms.create.CreateFlags |= SHFL_CF_ACCESS_READ;
}
- if (!(createparms.CreateFlags & SHFL_CF_ACCESS_WRITE)) {
+ if (!(parms.create.CreateFlags & SHFL_CF_ACCESS_WRITE)) {
// Do we really want to create new files without opening them for writing?
- createparms.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
+ parms.create.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
}
- dlog_print("vbox createparms flags=");
- dlog_printx(createparms.CreateFlags);
+ dlog_print("vbox create flags=");
+ dlog_printx(parms.create.CreateFlags);
dlog_endline();
- err = vbox_shfl_open(&data.vb, data.hgcm_client_id, root, &shflstr.shflstr, &createparms);
+ err = vbox_shfl_open(&data.vb, data.hgcm_client_id, root, &shflstr.shflstr, &parms.create);
if (err) {
set_vbox_err(r, err);
return;
}
dlog_print("vbox success result=");
- dlog_printd(createparms.Result);
+ dlog_printd(parms.create.Result);
dlog_print(" openfile=");
dlog_printu(openfile);
dlog_endline();
- switch (createparms.Result) {
+ switch (parms.create.Result) {
case SHFL_PATH_NOT_FOUND:
set_dos_err(r, DOS_ERROR_PATH_NOT_FOUND);
return;
@@ -427,16 +430,16 @@ static void handle_create_open_ex(union INTPACK __far *r)
break;
}
- if (createparms.Handle == SHFL_HANDLE_NIL) {
+ if (parms.create.Handle == SHFL_HANDLE_NIL) {
set_dos_err(r, DOS_ERROR_GEN_FAILURE);
return;
}
data.files[openfile].root = root;
- data.files[openfile].handle = createparms.Handle;
+ data.files[openfile].handle = parms.create.Handle;
// Fill in the SFT
- map_shfl_info_to_dossft(sft, &createparms.Info);
+ map_shfl_info_to_dossft(sft, &parms.create.Info);
sft->open_mode = mode;
sft->dev_info = 0x8040 | drive; // "Network drive, unwritten to"
sft->f_pos = 0;
@@ -687,16 +690,16 @@ static void handle_getattr(union INTPACK __far *r)
copy_drive_relative_filename(&shflstr.shflstr, path);
translate_filename_to_host(&shflstr.shflstr);
- memset(&createparms, 0, sizeof(SHFLCREATEPARMS));
- createparms.CreateFlags = SHFL_CF_LOOKUP;
+ memset(&parms.create, 0, sizeof(SHFLCREATEPARMS));
+ parms.create.CreateFlags = SHFL_CF_LOOKUP;
err = vbox_shfl_open(&data.vb, data.hgcm_client_id, root,
- &shflstr.shflstr, &createparms);
+ &shflstr.shflstr, &parms.create);
if (err) {
set_vbox_err(r, err);
return;
}
- switch (createparms.Result) {
+ switch (parms.create.Result) {
case SHFL_PATH_NOT_FOUND:
set_dos_err(r, DOS_ERROR_PATH_NOT_FOUND);
return;
@@ -707,7 +710,7 @@ static void handle_getattr(union INTPACK __far *r)
break;
}
- map_shfl_info_to_getattr(r, &createparms.Info);
+ map_shfl_info_to_getattr(r, &parms.create.Info);
clear_dos_err(r);
}
@@ -721,19 +724,19 @@ static vboxerr open_search_dir(SHFLROOT root, const char __far *path)
copy_drive_relative_dirname(&shflstr.shflstr, path);
translate_filename_to_host(&shflstr.shflstr);
- memset(&createparms, 0, sizeof(SHFLCREATEPARMS));
- createparms.CreateFlags = SHFL_CF_DIRECTORY
+ memset(&parms.create, 0, sizeof(SHFLCREATEPARMS));
+ parms.create.CreateFlags = SHFL_CF_DIRECTORY
| SHFL_CF_ACT_OPEN_IF_EXISTS | SHFL_CF_ACT_FAIL_IF_NEW
| SHFL_CF_ACCESS_READ;
err = vbox_shfl_open(&data.vb, data.hgcm_client_id, root,
- &shflstr.shflstr, &createparms);
+ &shflstr.shflstr, &parms.create);
if (err) {
dlog_puts("open search dir failed");
return err;
}
- switch (createparms.Result) {
+ switch (parms.create.Result) {
case SHFL_PATH_NOT_FOUND:
return VERR_PATH_NOT_FOUND;
case SHFL_FILE_NOT_FOUND:
@@ -742,13 +745,13 @@ static vboxerr open_search_dir(SHFLROOT root, const char __far *path)
break;
}
- if (createparms.Handle == SHFL_HANDLE_NIL) {
+ if (parms.create.Handle == SHFL_HANDLE_NIL) {
dlog_puts("open search dir returned no handle...");
return VERR_INVALID_HANDLE;
}
data.files[SEARCH_DIR_FILE].root = root;
- data.files[SEARCH_DIR_FILE].handle = createparms.Handle;
+ data.files[SEARCH_DIR_FILE].handle = parms.create.Handle;
return 0;
}
@@ -965,17 +968,17 @@ static void handle_chdir(union INTPACK __far *r)
copy_drive_relative_filename(&shflstr.shflstr, path);
translate_filename_to_host(&shflstr.shflstr);
- memset(&createparms, 0, sizeof(SHFLCREATEPARMS));
- createparms.CreateFlags = SHFL_CF_LOOKUP;
+ memset(&parms.create, 0, sizeof(SHFLCREATEPARMS));
+ parms.create.CreateFlags = SHFL_CF_LOOKUP;
err = vbox_shfl_open(&data.vb, data.hgcm_client_id, root,
- &shflstr.shflstr, &createparms);
+ &shflstr.shflstr, &parms.create);
if (err) {
set_vbox_err(r, err);
return;
}
- switch (createparms.Result) {
+ switch (parms.create.Result) {
case SHFL_PATH_NOT_FOUND:
case SHFL_FILE_NOT_FOUND:
set_dos_err(r, DOS_ERROR_PATH_NOT_FOUND);
@@ -985,7 +988,7 @@ static void handle_chdir(union INTPACK __far *r)
}
// Also check whether it is really a directory
- if (!(map_shfl_attr_to_dosattr(&createparms.Info.Attr) & _A_SUBDIR)) {
+ if (!(map_shfl_attr_to_dosattr(&parms.create.Info.Attr) & _A_SUBDIR)) {
set_dos_err(r, DOS_ERROR_PATH_NOT_FOUND);
return;
}
@@ -1007,18 +1010,18 @@ static void handle_mkdir(union INTPACK __far *r)
copy_drive_relative_filename(&shflstr.shflstr, path);
translate_filename_to_host(&shflstr.shflstr);
- memset(&createparms, 0, sizeof(SHFLCREATEPARMS));
- createparms.CreateFlags = SHFL_CF_DIRECTORY
+ memset(&parms.create, 0, sizeof(SHFLCREATEPARMS));
+ parms.create.CreateFlags = SHFL_CF_DIRECTORY
| SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACT_CREATE_IF_NEW;
err = vbox_shfl_open(&data.vb, data.hgcm_client_id, root,
- &shflstr.shflstr, &createparms);
+ &shflstr.shflstr, &parms.create);
if (err) {
set_vbox_err(r, err);
return;
}
- switch (createparms.Result) {
+ switch (parms.create.Result) {
case SHFL_PATH_NOT_FOUND:
case SHFL_FILE_NOT_FOUND:
set_dos_err(r, DOS_ERROR_PATH_NOT_FOUND);
@@ -1057,6 +1060,27 @@ static void handle_rmdir(union INTPACK __far *r)
clear_dos_err(r);
}
+static void handle_get_disk_free(union INTPACK __far *r)
+{
+ const unsigned long total_space = 10 * 1024 * 1024UL;
+ const unsigned long free_space = 4 * 1024 * 1024UL;
+ const unsigned cluster_bytes = 4 * 4096UL;
+
+ // TODO SHFLVOLINFO
+
+ r->h.ah = 0; // media ID byte
+ r->h.al = 4; /* Sectors per cluster */
+ r->x.cx = 4096; /* Bytes per sector */
+ r->x.bx = total_space / cluster_bytes; /* Total clusters */
+ r->x.dx = free_space / cluster_bytes; /* Number of available clusters */
+
+ dlog_print("disk free");
+ dlog_printd(r->x.dx);
+ dlog_endline();
+
+ clear_dos_err(r);
+}
+
static bool int2f_11_handler(union INTPACK r)
#pragma aux int2f_11_handler "*" parm caller [] value [al] modify [ax bx cx dx si di es gs fs]
{
@@ -1128,7 +1152,10 @@ static bool int2f_11_handler(union INTPACK r)
handle_rmdir(&r);
return true;
case DOS_FN_GET_DISK_FREE:
- // We don't support this
+ handle_get_disk_free(&r);
+ return true;
+ case DOS_FN_SEEK_END:
+ // I have no testcase for this function, so unsupported
set_dos_err(&r, DOS_ERROR_INVALID_FUNCTION);
return true;
}
diff --git a/sftsr.h b/sftsr.h
index 0e5530c..48ffa4f 100644
--- a/sftsr.h
+++ b/sftsr.h
@@ -33,9 +33,13 @@
/** Maximum number of open files */
#define NUM_FILES 40
-/** Directory enumeration needs an open file, this is its index. */
+/** Directory enumeration needs an open file, this is its index in the "openfile" table. */
#define SEARCH_DIR_FILE 0
+/** Size of the VBox buffer. The maximum message length that may be sent.
+ * Enough to fit an HGCM connect call, which is actually larger than most other calls we use ( <= 7 args ). */
+#define VBOX_BUFFER_SIZE (200)
+
typedef struct {
uint32_t root;
uint64_t handle;
@@ -65,6 +69,7 @@ typedef struct {
// VirtualBox communication
struct vboxcomm vb;
+ char vbbuf[VBOX_BUFFER_SIZE];
uint32_t hgcm_client_id;
} TSRDATA;
diff --git a/vbox.c b/vbox.c
index eb05f1b..8c6d28a 100644
--- a/vbox.c
+++ b/vbox.c
@@ -77,18 +77,19 @@ int vbox_init_device(LPVBOXCOMM vb)
return 0;
}
-int vbox_init_buffer(LPVBOXCOMM vb)
+int vbox_init_buffer(LPVBOXCOMM vb, unsigned size)
{
+ vb->dds.regionSize = size;
+ vb->dds.segOrSelector = FP_SEG(&vb->buf);
+ vb->dds.offset = FP_OFF(&vb->buf);
+ vb->dds.bufferId = 0;
+ vb->dds.physicalAddress = 0;
+ vb->vds = false;
+
if (vds_available()) {
// Use the Virtual DMA Service to get the physical address of this buffer
int err;
- vb->dds.regionSize = sizeof(vb->buf);
- vb->dds.segOrSelector = FP_SEG(&vb->buf);
- vb->dds.offset = FP_OFF(&vb->buf);
- vb->dds.bufferId = 0;
- vb->dds.physicalAddress = 0;
-
err = vds_lock_dma_buffer_region(&vb->dds, VDS_NO_AUTO_ALLOC);
if (err) {
// As far as I have seen, most VDS providers always keep low memory contiguous,
@@ -98,12 +99,11 @@ int vbox_init_buffer(LPVBOXCOMM vb)
dlog_endline();
return err;
}
- } else {
- vb->dds.regionSize = 0; // So that we don't try to unlock it later
- vb->dds.segOrSelector = FP_SEG(&vb->buf);
- vb->dds.offset = FP_OFF(&vb->buf);
- vb->dds.bufferId = 0;
+ vb->vds = true;
+ } else {
+ // If VDS is not available,
+ // we assume a 1:1 mapping between linear and physical addresses
vb->dds.physicalAddress = linear_addr(&vb->buf);
}
@@ -112,8 +112,7 @@ int vbox_init_buffer(LPVBOXCOMM vb)
int vbox_release_buffer(LPVBOXCOMM vb)
{
- if (vds_available() && vb->dds.regionSize) {
-
+ if (vb->vds && vds_available()) {
int err = vds_unlock_dma_buffer_region(&vb->dds, 0);
if (err) {
dlog_print("Error while VDS unlocking, err=");
@@ -122,6 +121,7 @@ int vbox_release_buffer(LPVBOXCOMM vb)
// Ignore the error, it's not like we can do anything
}
}
+ vb->vds = false;
vb->dds.regionSize = 0;
vb->dds.segOrSelector = 0;
vb->dds.offset = 0;
diff --git a/vbox.h b/vbox.h
index 6a1e66c..8bbfed9 100644
--- a/vbox.h
+++ b/vbox.h
@@ -31,14 +31,17 @@
#include "utils.h"
#include "vboxdev.h"
-/** Size of the VBox buffer. The maximum message length that may be sent. */
-// Enough to fit a set_pointer_shape message with a 16x16 cursor
-#define VBOX_BUFFER_SIZE (1024 + 32 + 24 + 20)
-
+/** Struct containing all the information required to send a VirtualBox message. */
typedef struct vboxcomm {
+ /** The IO port of the VirtualBox pci device, found by vbox_init_device(). */
uint16_t iobase;
- char buf[VBOX_BUFFER_SIZE];
+ /** Whether we are using VDS or not. */
+ bool vds;
+ /** The VDS (Virtual DMA service) descriptor corresponding to the buffer that we will use.
+ * Initialized by vbox_init_buffer(), even if we don't use VDS. */
VDSDDS dds;
+ /** We assume the actual buffer comes in memory after this struct. */
+ char buf[];
} vboxcomm_t;
typedef vboxcomm_t * PVBOXCOMM;
typedef vboxcomm_t __far * LPVBOXCOMM;
@@ -65,7 +68,7 @@ extern int vbox_init_device(LPVBOXCOMM vb);
/** Prepares the buffer used for communicating with VBox and
* computes its physical address (using VDS if necessary). */
-extern int vbox_init_buffer(LPVBOXCOMM vb);
+extern int vbox_init_buffer(LPVBOXCOMM vb, unsigned size);
/** Releases/unlocks buffer, no further use possible. */
extern int vbox_release_buffer(LPVBOXCOMM vb);
diff --git a/vboxdev.h b/vboxdev.h
index c2bf5a3..2b509d6 100644
--- a/vboxdev.h
+++ b/vboxdev.h
@@ -1408,6 +1408,57 @@ typedef struct _SHFLDIRINFO
SHFLSTRING name;
} SHFLDIRINFO, *PSHFLDIRINFO;
+/**
+ * Shared folder filesystem properties.
+ */
+typedef struct SHFLFSPROPERTIES
+{
+ /** The maximum size of a filesystem object name.
+ * This does not include the '\\0'. */
+ uint32_t cbMaxComponent;
+
+ /** True if the filesystem is remote.
+ * False if the filesystem is local. */
+ bool fRemote;
+
+ /** True if the filesystem is case sensitive.
+ * False if the filesystem is case insensitive. */
+ bool fCaseSensitive;
+
+ /** True if the filesystem is mounted read only.
+ * False if the filesystem is mounted read write. */
+ bool fReadOnly;
+
+ /** True if the filesystem can encode unicode object names.
+ * False if it can't. */
+ bool fSupportsUnicode;
+
+ /** True if the filesystem is compresses.
+ * False if it isn't or we don't know. */
+ bool fCompressed;
+
+ /** True if the filesystem compresses of individual files.
+ * False if it doesn't or we don't know. */
+ bool fFileCompression;
+
+ /** @todo more? */
+} SHFLFSPROPERTIES;
+AssertCompileSize(SHFLFSPROPERTIES, 12);
+/** Pointer to a shared folder filesystem properties structure. */
+typedef SHFLFSPROPERTIES *PSHFLFSPROPERTIES;
+/** Pointer to a const shared folder filesystem properties structure. */
+typedef SHFLFSPROPERTIES const *PCSHFLFSPROPERTIES;
+
+typedef struct _SHFLVOLINFO
+{
+ uint64_t ullTotalAllocationBytes;
+ uint64_t ullAvailableAllocationBytes;
+ uint32_t ulBytesPerAllocationUnit;
+ uint32_t ulBytesPerSector;
+ uint32_t ulSerial;
+ SHFLFSPROPERTIES fsProperties;
+} SHFLVOLINFO, *PSHFLVOLINFO;
+
#define SHFL_LIST_NONE 0
#define SHFL_LIST_RETURN_ONE 1
#define SHFL_LIST_RESTART 2