From 255c22e6016a06bb7c80285fdb5a032c85e6e0bb Mon Sep 17 00:00:00 2001 From: Dale Whinham Date: Fri, 11 Dec 2020 12:37:57 +0000 Subject: [PATCH 1/6] minimig: Don't return failure if renaming to self Renaming a file or directory to its own name is legal under AmigaOS, so ensure that this case is a no-op and returns success. This fixes the error encountered when creating a new drawer under SHARE: and accepting the default name of "Unnamed1", for example. --- support/minimig/minimig_share.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/support/minimig/minimig_share.cpp b/support/minimig/minimig_share.cpp index 6c974aa..954ab77 100644 --- a/support/minimig/minimig_share.cpp +++ b/support/minimig/minimig_share.cpp @@ -694,6 +694,16 @@ static int process_request(void *reqres_buffer) ret = ERROR_OBJECT_NOT_FOUND; break; } + + strcpy(buf, getFullPath(buf)); + const char *fp2 = getFullPath(cp2); + + // Identical match; do nothing + if (!strcmp(buf, fp2)) + { + ret = 0; + break; + } if (FileExists(cp2, 0) || PathIsDir(cp2, 0)) { @@ -701,8 +711,7 @@ static int process_request(void *reqres_buffer) break; } - strcpy(buf, getFullPath(buf)); - if (rename(buf, getFullPath(cp2))) + if (rename(buf, fp2)) { ret = ERROR_OBJECT_NOT_FOUND; break; From c8a124385e9c48cbe753d8e3e8187bfe0dd2c5c2 Mon Sep 17 00:00:00 2001 From: Dale Whinham Date: Fri, 11 Dec 2020 19:15:30 +0000 Subject: [PATCH 2/6] minimig: Add ACTION_SAME_LOCK to shared filesystem Adapt upstream fix from a314. This fixes some odd behaviour in Workbench such as: - Icons that were "Left Out" would reappear in their parent windows when refreshed. - Deleted files would not disappear from the window unless it was refreshed. Original message from a314 commit: This call is used in at least 2.1 to terminate directory traversal when deleting a directory using Workbench. This sometimes caused unhandled exceptions in a314d and much worse unintended files being deleted! --- support/minimig/miminig_fs_messages.h | 20 ++++++++++++++++++++ support/minimig/minimig_share.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/support/minimig/miminig_fs_messages.h b/support/minimig/miminig_fs_messages.h index d65f906..bdc1af2 100644 --- a/support/minimig/miminig_fs_messages.h +++ b/support/minimig/miminig_fs_messages.h @@ -28,6 +28,7 @@ #define ACTION_DISK_TYPE 32 #define ACTION_DISK_CHANGE 33 #define ACTION_SET_DATE 34 +#define ACTION_SAME_LOCK 40 #define ACTION_SCREEN_MODE 994 #define ACTION_READ_RETURN 1001 #define ACTION_WRITE_RETURN 1002 @@ -74,6 +75,10 @@ #define SHARED_LOCK -2 #define EXCLUSIVE_LOCK -1 +#define LOCK_DIFFERENT -1 +#define LOCK_SAME 0 +#define LOCK_SAME_VOLUME 1 + #define MODE_OLDFILE 1005 #define MODE_NEWFILE 1006 #define MODE_READWRITE 1004 @@ -356,6 +361,21 @@ struct SetCommentResponse long error_code; }; +struct SameLockRequest +{ + long sz; + long type; + long key1; + long key2; +}; + +struct SameLockResponse +{ + long sz; + long success; + long error_code; +}; + struct DiskInfoRequest { long sz; diff --git a/support/minimig/minimig_share.cpp b/support/minimig/minimig_share.cpp index 954ab77..f065360 100644 --- a/support/minimig/minimig_share.cpp +++ b/support/minimig/minimig_share.cpp @@ -781,6 +781,30 @@ static int process_request(void *reqres_buffer) ret = 0; } break; + + case ACTION_SAME_LOCK: + { + dbg_print("> ACTION_SAME_LOCK\n"); + SameLockRequest *req = (SameLockRequest*)reqres_buffer; + + uint32_t key1 = SWAP_INT(req->key1); + uint32_t key2 = SWAP_INT(req->key2); + + if ((locks.find(key1) == locks.end()) || (locks.find(key2) == locks.end())) + { + ret = LOCK_DIFFERENT; + break; + } + + if (locks[key1].path == locks[key2].path) + { + ret = LOCK_SAME; + break; + } + + ret = LOCK_SAME_VOLUME; + } + break; } int success = ret ? 0 : 1; From 23a5258e376c82617b807369a5dea6bf897e6724 Mon Sep 17 00:00:00 2001 From: Dale Whinham Date: Fri, 11 Dec 2020 19:29:41 +0000 Subject: [PATCH 3/6] minimig: Fix ACTION_SEEK when offset is negative Some applications would fail to load some files due to negative seek offsets being corrupted by unsigned conversion. A simple test case is AmigaGuide: place an AmigaGuide document on the shared volume and attempt to open it. Before this patch, this would fail silently. --- support/minimig/minimig_share.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/support/minimig/minimig_share.cpp b/support/minimig/minimig_share.cpp index f065360..213e392 100644 --- a/support/minimig/minimig_share.cpp +++ b/support/minimig/minimig_share.cpp @@ -591,10 +591,10 @@ static int process_request(void *reqres_buffer) break; } - uint32_t old_pos = open_file_handles[key].offset; + int old_pos = open_file_handles[key].offset; - uint32_t new_pos = SWAP_INT(req->new_pos); - uint32_t mode = SWAP_INT(req->mode); + int new_pos = SWAP_INT(req->new_pos); + int mode = SWAP_INT(req->mode); int origin = SEEK_SET; if (mode == OFFSET_CURRENT) origin = SEEK_CUR; From 5431c99d6a844c252dc11984e62e8b2e243a9860 Mon Sep 17 00:00:00 2001 From: Dale Whinham Date: Sat, 12 Dec 2020 20:51:33 +0000 Subject: [PATCH 4/6] minimig: Add ACTION_EXAMINE_FH to shared filesystem Adapt upstream fix from a314. Original message: This action is performed when doing a drag-n-drop copy from the PiDisk to an other device in Workbench 3.1.4 --- support/minimig/miminig_fs_messages.h | 22 +++++++ support/minimig/minimig_share.cpp | 86 +++++++++++++++++++++++---- 2 files changed, 97 insertions(+), 11 deletions(-) diff --git a/support/minimig/miminig_fs_messages.h b/support/minimig/miminig_fs_messages.h index bdc1af2..fc73fcc 100644 --- a/support/minimig/miminig_fs_messages.h +++ b/support/minimig/miminig_fs_messages.h @@ -39,6 +39,7 @@ #define ACTION_SEEK 1008 #define ACTION_TRUNCATE 1022 #define ACTION_WRITE_PROTECT 1023 +#define ACTION_EXAMINE_FH 1034 #define ERROR_NO_FREE_STORE 103 #define ERROR_TASK_TABLE_FULL 105 @@ -376,6 +377,27 @@ struct SameLockResponse long error_code; }; +struct ExamineFhRequest +{ + long sz; + long type; + long arg1; +}; + +struct ExamineFhResponse +{ + long sz; + long success; + long error_code; + + long disk_key; + long entry_type; + int size; + int protection; + int date[3]; + char file_name[1]; +}; + struct DiskInfoRequest { long sz; diff --git a/support/minimig/minimig_share.cpp b/support/minimig/minimig_share.cpp index 213e392..fd5381d 100644 --- a/support/minimig/minimig_share.cpp +++ b/support/minimig/minimig_share.cpp @@ -218,6 +218,21 @@ static char* find_path(uint32_t key, const char *name) return str; } +static void fill_date(time_t time, int date[3]) +{ + time_t days = time / 86400; + time_t left = time - (days * 86400); + time_t mins = left / 60; + time_t secs = left - (mins * 60); + time_t ticks = secs * 50; + days -= 2922; // Days between 1970 - 01 - 01 and 1978 - 01 - 01 + if (days < 0) days = 0; + + date[0] = SWAP_INT(days); + date[1] = SWAP_INT(mins); + date[2] = SWAP_INT(ticks); +} + static int process_request(void *reqres_buffer) { static char buf[1024]; @@ -465,21 +480,11 @@ static int process_request(void *reqres_buffer) } } - time_t days = time / 86400; - time_t left = time - (days * 86400); - time_t mins = left / 60; - time_t secs = left - (mins * 60); - time_t ticks = secs * 50; - days -= 2922; // Days between 1970 - 01 - 01 and 1978 - 01 - 01 - if (days < 0) days = 0; - res->disk_key = SWAP_INT(disk_key); res->entry_type = SWAP_INT(type); res->size = SWAP_INT(size); res->protection = 0; - res->date[0] = SWAP_INT(days); - res->date[1] = SWAP_INT(mins); - res->date[2] = SWAP_INT(ticks); + fill_date(time, res->date); res->file_name[0] = strlen(fn); strcpy(res->file_name + 1, fn); @@ -489,6 +494,65 @@ static int process_request(void *reqres_buffer) } break; + case ACTION_EXAMINE_FH: + { + dbg_print("> ACTION_EXAMINE_FH\n"); + ExamineFhRequest *req = (ExamineFhRequest*)reqres_buffer; + ExamineFhResponse *res = (ExamineFhResponse*)reqres_buffer; + sz_res = sizeof(ExamineFhResponse); + + uint32_t key = SWAP_INT(req->arg1); + dbg_print(" key: %d\n", key); + + if (open_file_handles.find(key) == open_file_handles.end()) + { + ret = ERROR_OBJECT_NOT_FOUND; + break; + } + + const char *fn = open_file_handles[key].name; + int disk_key = 666; + int type = 0; + time_t time = 0; + uint32_t size = 0; + + struct stat64 st; + if (fstat64(fileno(open_file_handles[key].filp), &st) == 0) + { + time = st.st_mtime; + if (st.st_mode & S_IFDIR) type = ST_USERDIR; + else + { + type = ST_FILE; + if (st.st_size > UINT32_MAX) size = UINT32_MAX; + else size = (uint32_t)st.st_size; + } + } + else + { + dbg_print("Couldn't stat %s: %d\n", fn, errno); + ret = ERROR_OBJECT_NOT_FOUND; + break; + } + + dbg_print(" fn: %s\n", fn); + dbg_print(" size: %lld\n", open_file_handles[key].size); + dbg_print(" type: %d\n", type); + + res->disk_key = SWAP_INT(disk_key); + res->entry_type = SWAP_INT(type); + res->size = SWAP_INT(size); + res->protection = 0; + fill_date(time, res->date); + + res->file_name[0] = strlen(fn); + strcpy(res->file_name + 1, fn); + + sz_res = sizeof(ExamineFhResponse) + strlen(fn); + ret = 0; + } + break; + case ACTION_FINDINPUT: // MODE_OLDFILE case ACTION_FINDOUTPUT: // MODE_NEWFILE case ACTION_FINDUPDATE: // MODE_READWRITE From bc6e69c26bc836153a12c6a6a54696002806f739 Mon Sep 17 00:00:00 2001 From: Dale Whinham Date: Sat, 12 Dec 2020 20:56:02 +0000 Subject: [PATCH 5/6] minimig: Fix error return for ACTION_FINDINPUT Adapt upstream fix from a314. Original message: Using ACTION_FINDINPUT to check if a file exists wrongfully returned ERROR_DIR_NOT_FOUND instead of ERROR_OBJECT_NOT_FOUND if the file was searched for in a non-existent subdirectory. --- support/minimig/minimig_share.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support/minimig/minimig_share.cpp b/support/minimig/minimig_share.cpp index fd5381d..fb57d8a 100644 --- a/support/minimig/minimig_share.cpp +++ b/support/minimig/minimig_share.cpp @@ -566,7 +566,7 @@ static int process_request(void *reqres_buffer) if (!name[0]) { - ret = ERROR_DIR_NOT_FOUND; + ret = ERROR_OBJECT_NOT_FOUND; break; } From d48169169e98435c2dbb08fae1b51595ee19530b Mon Sep 17 00:00:00 2001 From: Dale Whinham Date: Sun, 13 Dec 2020 00:42:21 +0000 Subject: [PATCH 6/6] minimig: Fix path resolution for assigns Only nullify the key in find_path() if the name contains our device (SHARE:) or volume (MiSTer:) name. This fixes the ability to create assigns to locations on the shared filesystem. If find_path() is called with an assign-relative path, we want to preserve the key so that a relative path is constructed from the directory associated with that key. --- support/minimig/minimig_share.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/support/minimig/minimig_share.cpp b/support/minimig/minimig_share.cpp index fb57d8a..14898ea 100644 --- a/support/minimig/minimig_share.cpp +++ b/support/minimig/minimig_share.cpp @@ -27,6 +27,10 @@ static uint8_t *shmem = 0; #define REQUEST_BUFFER 4 // ~512B #define DATA_BUFFER 0x1000 // 4KB +// Must match device name in MountList and volume name from MiSTerFileSystem +#define DEVICE_NAME "SHARE" +#define VOLUME_NAME "MiSTer" + //#define DEBUG #ifdef DEBUG @@ -124,7 +128,12 @@ static char* find_path(uint32_t key, const char *name) const char* p = strchr(name, ':'); if (p) { - key = 0; + size_t root_len = p - name; + + // Don't use lock for relative path if the name contains our root + if (root_len == 0 || !strncasecmp(name, DEVICE_NAME, root_len) || !strncasecmp(name, VOLUME_NAME, root_len)) + key = 0; + name = p + 1; }