diff --git a/scripts/resources/windows/mame/mame.man b/scripts/resources/windows/mame/mame.man index cd2705c8886..e07705a39c7 100644 --- a/scripts/resources/windows/mame/mame.man +++ b/scripts/resources/windows/mame/mame.man @@ -8,8 +8,9 @@ - - true + + true + true diff --git a/scripts/resources/windows/mess/mess.man b/scripts/resources/windows/mess/mess.man index d03a874f8fb..7feef51ce9f 100644 --- a/scripts/resources/windows/mess/mess.man +++ b/scripts/resources/windows/mess/mess.man @@ -8,8 +8,9 @@ - - true + + true + true diff --git a/src/devices/bus/nubus/nubus_image.cpp b/src/devices/bus/nubus/nubus_image.cpp index 9d75788c469..5cdaabeb995 100644 --- a/src/devices/bus/nubus/nubus_image.cpp +++ b/src/devices/bus/nubus/nubus_image.cpp @@ -6,12 +6,26 @@ HFS images, including floppy images (DD and HD) and vMac/Basilisk HDD volumes up to 256 MB in size. + TODO: + * Get get directory and get listing commands have no way to indicate + that the path/name is too long for the buffer. + * The set directory command doesn't work well with host filesystems that + have roots (e.g. Windows drive letters). + * The set directory command assumes '/' is a valid host directory + separator character. + * The get listing commands have no way to indicate whether an entry is + a directory. + ***************************************************************************/ #include "emu.h" #include "nubus_image.h" + #include "osdcore.h" +#include + + #define IMAGE_ROM_REGION "image_rom" #define IMAGE_DISK0_TAG "nb_disk" @@ -189,10 +203,9 @@ void nubus_image_device::device_start() m_image = subdevice(IMAGE_DISK0_TAG); - filectx.curdir[0] = '.'; - filectx.curdir[1] = '\0'; - filectx.dirp = nullptr; - filectx.fd = nullptr; + filectx.curdir = "."; + filectx.dirp.reset(); + filectx.fd.reset(); } //------------------------------------------------- @@ -249,55 +262,51 @@ void nubus_image_device::file_cmd_w(uint32_t data) { // data = ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8) | ((data & 0xff000000) >> 24); filectx.curcmd = data; - switch(data) { + switch (data) { case kFileCmdGetDir: - strcpy((char*)filectx.filename, (char*)filectx.curdir); + strncpy(filectx.filename, filectx.curdir.c_str(), ARRAY_LENGTH(filectx.filename)); break; case kFileCmdSetDir: if ((filectx.filename[0] == '/') || (filectx.filename[0] == '$')) { - strcpy((char*)filectx.curdir, (char*)filectx.filename); + filectx.curdir.assign(std::begin(filectx.filename), std::find(std::begin(filectx.filename), std::end(filectx.filename), '\0')); } else { - strcat((char*)filectx.curdir, "/"); - strcat((char*)filectx.curdir, (char*)filectx.filename); + filectx.curdir += '/'; + filectx.curdir.append(std::begin(filectx.filename), std::find(std::begin(filectx.filename), std::end(filectx.filename), '\0')); } break; case kFileCmdGetFirstListing: - filectx.dirp = osd::directory::open((const char *)filectx.curdir); + filectx.dirp = osd::directory::open(filectx.curdir); [[fallthrough]]; case kFileCmdGetNextListing: if (filectx.dirp) { osd::directory::entry const *const dp = filectx.dirp->read(); - if(dp) { - strncpy((char*)filectx.filename, dp->name, sizeof(filectx.filename)); + if (dp) { + strncpy(filectx.filename, dp->name, ARRAY_LENGTH(filectx.filename)); } else { - memset(filectx.filename, 0, sizeof(filectx.filename)); + std::fill(std::begin(filectx.filename), std::end(filectx.filename), '\0'); } } else { - memset(filectx.filename, 0, sizeof(filectx.filename)); + std::fill(std::begin(filectx.filename), std::end(filectx.filename), '\0'); } break; case kFileCmdGetFile: { - std::string fullpath; - fullpath.reserve(1024); - fullpath.assign((const char *)filectx.curdir); - fullpath.append(PATH_SEPARATOR); - fullpath.append((const char*)filectx.filename); - if(osd_file::open(fullpath, OPEN_FLAG_READ, filectx.fd, filectx.filelen) != osd_file::error::NONE) + std::string fullpath(filectx.curdir); + fullpath += PATH_SEPARATOR; + fullpath.append(std::begin(filectx.filename), std::find(std::begin(filectx.filename), std::end(filectx.filename), '\0')); + if (osd_file::open(fullpath, OPEN_FLAG_READ, filectx.fd, filectx.filelen) != osd_file::error::NONE) osd_printf_error("Error opening %s\n", fullpath); filectx.bytecount = 0; } break; case kFileCmdPutFile: { - std::string fullpath; - fullpath.reserve(1024); - fullpath.assign((const char *)filectx.curdir); - fullpath.append(PATH_SEPARATOR); - fullpath.append((const char*)filectx.filename); + std::string fullpath(filectx.curdir); + fullpath += PATH_SEPARATOR; + fullpath.append(std::begin(filectx.filename), std::find(std::begin(filectx.filename), std::end(filectx.filename), '\0')); uint64_t filesize; // unused, but it's an output from the open call - if(osd_file::open(fullpath, OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, filectx.fd, filesize) != osd_file::error::NONE) + if (osd_file::open(fullpath, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, filectx.fd, filesize) != osd_file::error::NONE) osd_printf_error("Error opening %s\n", fullpath); filectx.bytecount = 0; } @@ -356,12 +365,10 @@ uint32_t nubus_image_device::file_len_r() void nubus_image_device::file_name_w(offs_t offset, uint32_t data) { - ((uint32_t*)(filectx.filename))[offset] = big_endianize_int32(data); + reinterpret_cast(filectx.filename)[offset] = big_endianize_int32(data); } uint32_t nubus_image_device::file_name_r(offs_t offset) { - uint32_t ret; - ret = big_endianize_int32(((uint32_t*)(filectx.filename))[offset]); - return ret; + return big_endianize_int32(reinterpret_cast(filectx.filename)[offset]); } diff --git a/src/devices/bus/nubus/nubus_image.h b/src/devices/bus/nubus/nubus_image.h index 9ead3fd1a53..c6dcf6db388 100644 --- a/src/devices/bus/nubus/nubus_image.h +++ b/src/devices/bus/nubus/nubus_image.h @@ -38,8 +38,8 @@ protected: struct nbfilectx { uint32_t curcmd; - uint8_t filename[128]; - uint8_t curdir[1024]; + char filename[128]; + std::string curdir; osd::directory::ptr dirp; osd_file::ptr fd; uint64_t filelen; diff --git a/src/devices/cpu/drccache.cpp b/src/devices/cpu/drccache.cpp index 44ff2cf9371..e75305cc6ba 100644 --- a/src/devices/cpu/drccache.cpp +++ b/src/devices/cpu/drccache.cpp @@ -14,6 +14,10 @@ #include +// this improves performance of some emulated systems but doesn't work on W^X hosts +//#define MAME_DRC_CACHE_RWX + + namespace { template constexpr T *ALIGN_PTR_UP(T *p, U align) @@ -59,7 +63,11 @@ drc_cache::drc_cache(size_t bytes) : std::fill(std::begin(m_free), std::end(m_free), nullptr); std::fill(std::begin(m_nearfree), std::end(m_nearfree), nullptr); +#if defined(MAME_DRC_CACHE_RWX) + m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE | osd::virtual_memory_allocation::EXECUTE); +#else // defined(MAME_DRC_CACHE_RWX) m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); +#endif // defined(MAME_DRC_CACHE_RWX) } @@ -84,11 +92,7 @@ void drc_cache::flush() // just reset the top back to the base and re-seed m_top = m_base; - if (m_executable) - { - m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); - m_executable = false; - } + codegen_init(); } @@ -174,11 +178,7 @@ void *drc_cache::alloc_temporary(size_t bytes) return nullptr; // otherwise, update the cache top - if (m_executable) - { - m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); - m_executable = false; - } + codegen_init(); m_top = ALIGN_PTR_UP(ptr + bytes, CACHE_ALIGNMENT); return ptr; } @@ -209,7 +209,9 @@ void drc_cache::codegen_init() { if (m_executable) { +#if !defined(MAME_DRC_CACHE_RWX) m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); +#endif // !defined(MAME_DRC_CACHE_RWX) m_executable = false; } } @@ -219,7 +221,9 @@ void drc_cache::codegen_complete() { if (!m_executable) { +#if !defined(MAME_DRC_CACHE_RWX) m_cache.set_access(m_base - m_near, ALIGN_PTR_UP(m_top, m_cache.page_size()) - m_base, osd::virtual_memory_allocation::READ_EXECUTE); +#endif // !defined(MAME_DRC_CACHE_RWX) m_executable = true; } } @@ -240,11 +244,7 @@ drccodeptr *drc_cache::begin_codegen(uint32_t reserve_bytes) return nullptr; // otherwise, return a pointer to the cache top - if (m_executable) - { - m_cache.set_access(0, m_size, osd::virtual_memory_allocation::READ_WRITE); - m_executable = false; - } + codegen_init(); m_codegen = m_top; return &m_top; } diff --git a/src/frontend/mame/ui/dirmenu.cpp b/src/frontend/mame/ui/dirmenu.cpp index bda3c74cf62..6a7fa0c1aef 100644 --- a/src/frontend/mame/ui/dirmenu.cpp +++ b/src/frontend/mame/ui/dirmenu.cpp @@ -384,13 +384,12 @@ void menu_add_change_folder::handle() void menu_add_change_folder::populate(float &customtop, float &custombottom) { // open a path - const char *volume_name = nullptr; file_enumerator path(m_current_path.c_str()); const osd::directory::entry *dirent; int folders_count = 0; // add the drives - for (int i = 0; (volume_name = osd_get_volume_name(i)) != nullptr; ++i) + for (std::string const &volume_name : osd_get_volume_names()) item_append(volume_name, "[DRIVE]", 0, (void *)(uintptr_t)++folders_count); // add the directories diff --git a/src/frontend/mame/ui/filesel.cpp b/src/frontend/mame/ui/filesel.cpp index 0c38129ed9f..88d6027339e 100644 --- a/src/frontend/mame/ui/filesel.cpp +++ b/src/frontend/mame/ui/filesel.cpp @@ -413,8 +413,7 @@ void menu_file_selector::populate(float &customtop, float &custombottom) selected_entry = &append_entry(SELECTOR_ENTRY_TYPE_SOFTWARE_LIST, "", ""); // add the drives - int i = 0; - for (char const *volume_name = osd_get_volume_name(i); volume_name; volume_name = osd_get_volume_name(++i)) + for (std::string const &volume_name : osd_get_volume_names()) append_entry(SELECTOR_ENTRY_TYPE_DRIVE, volume_name, volume_name); // mark first filename entry diff --git a/src/osd/modules/debugger/debugimgui.cpp b/src/osd/modules/debugger/debugimgui.cpp index 6b1c52a7281..f30d07bc93b 100644 --- a/src/osd/modules/debugger/debugimgui.cpp +++ b/src/osd/modules/debugger/debugimgui.cpp @@ -993,13 +993,12 @@ void debug_imgui::refresh_filelist() { int x = 0; // add drives - const char *volume_name; - while((volume_name = osd_get_volume_name(x))!=nullptr) + for(std::string const &volume_name : osd_get_volume_names()) { file_entry temp; temp.type = file_entry_type::DRIVE; - temp.basename = std::string(volume_name); - temp.fullpath = std::string(volume_name); + temp.basename = volume_name; + temp.fullpath = volume_name; m_filelist.emplace_back(std::move(temp)); x++; } diff --git a/src/osd/modules/file/posixfile.cpp b/src/osd/modules/file/posixfile.cpp index a35f0fbd6d4..ffdd4c4d477 100644 --- a/src/osd/modules/file/posixfile.cpp +++ b/src/osd/modules/file/posixfile.cpp @@ -469,12 +469,22 @@ bool osd_is_absolute_path(std::string const &path) // osd_get_volume_name //============================================================ -const char *osd_get_volume_name(int idx) +std::string osd_get_volume_name(int idx) { if (idx == 0) return "/"; else - return nullptr; + return std::string(); +} + + +//============================================================ +// osd_get_volume_names +//============================================================ + +std::vector osd_get_volume_names() +{ + return std::vector{ "/" }; } diff --git a/src/osd/modules/file/stdfile.cpp b/src/osd/modules/file/stdfile.cpp index 74b4208505c..96d7e53ebbe 100644 --- a/src/osd/modules/file/stdfile.cpp +++ b/src/osd/modules/file/stdfile.cpp @@ -20,6 +20,7 @@ namespace { + class std_osd_file : public osd_file { public: @@ -245,8 +246,19 @@ bool osd_is_absolute_path(std::string const &path) // osd_get_volume_name //============================================================ -const char *osd_get_volume_name(int idx) +std::string osd_get_volume_name(int idx) { // we don't expose volumes - return nullptr; + return std::string(); +} + + +//============================================================ +// osd_get_volume_names +//============================================================ + +std::vector osd_get_volume_names() +{ + // we don't expose volumes + return std::vector(); } diff --git a/src/osd/modules/file/winfile.cpp b/src/osd/modules/file/winfile.cpp index b0869b7c70f..4c265be613d 100644 --- a/src/osd/modules/file/winfile.cpp +++ b/src/osd/modules/file/winfile.cpp @@ -20,6 +20,7 @@ #include #include +#include // standard windows headers #include @@ -31,6 +32,7 @@ namespace { + //============================================================ // TYPE DEFINITIONS //============================================================ @@ -399,16 +401,19 @@ std::unique_ptr osd_stat(const std::string &path) osd_file::error osd_get_full_path(std::string &dst, std::string const &path) { - // convert the path to TCHARs - osd::text::tstring t_path = osd::text::to_tstring(path); + // get the length of the full path + std::wstring const w_path(osd::text::to_wstring(path)); + DWORD const length(GetFullPathNameW(w_path.c_str(), 0, nullptr, nullptr)); + if (!length) + return win_error_to_file_error(GetLastError()); - // canonicalize the path - TCHAR buffer[MAX_PATH]; - if (!GetFullPathName(t_path.c_str(), ARRAY_LENGTH(buffer), buffer, nullptr)) + // allocate a buffer and get the canonical path + std::unique_ptr buffer(std::make_unique(length)); + if (!GetFullPathNameW(w_path.c_str(), length, buffer.get(), nullptr)) return win_error_to_file_error(GetLastError()); // convert the result back to UTF-8 - osd::text::from_tstring(dst, buffer); + osd::text::from_wstring(dst, buffer.get()); return osd_file::error::NONE; } @@ -420,8 +425,7 @@ osd_file::error osd_get_full_path(std::string &dst, std::string const &path) bool osd_is_absolute_path(std::string const &path) { - osd::text::tstring t_path = osd::text::to_tstring(path); - return !PathIsRelative(t_path.c_str()); + return !PathIsRelativeW(osd::text::to_wstring(path).c_str()); } @@ -430,20 +434,57 @@ bool osd_is_absolute_path(std::string const &path) // osd_get_volume_name //============================================================ -const char *osd_get_volume_name(int idx) +std::string osd_get_volume_name(int idx) { - static char szBuffer[128]; - const char *p; + std::vector buffer; + DWORD length(GetLogicalDriveStringsW(0, nullptr)); + while (length && (buffer.size() < (length + 1))) + { + buffer.clear(); + buffer.resize(length + 1); + length = GetLogicalDriveStringsW(length, &buffer[0]); + } + if (!length) + return std::string(); - GetLogicalDriveStringsA(ARRAY_LENGTH(szBuffer), szBuffer); - - p = szBuffer; - while(idx--) { - p += strlen(p) + 1; - if (!*p) return nullptr; + wchar_t const *p(&buffer[0]); + while (idx-- && *p) + { + while (*p++) { } } - return p; + std::string result; + osd::text::from_wstring(result, p); + return result; +} + + +//============================================================ +// osd_get_volume_names +//============================================================ + +std::vector osd_get_volume_names() +{ + std::vector result; + std::vector buffer; + DWORD length(GetLogicalDriveStringsW(0, nullptr)); + while (length && (buffer.size() < (length + 1))) + { + buffer.clear(); + buffer.resize(length + 1); + length = GetLogicalDriveStringsW(length, &buffer[0]); + } + if (!length) + return result; + + wchar_t const *p(&buffer[0]); + std::wstring vol; + while (*p) + { + osd::text::from_wstring(result.emplace_back(), p); + while (*p++) { } + } + return result; } diff --git a/src/osd/modules/file/winrtfile.cpp b/src/osd/modules/file/winrtfile.cpp index 8e6ed4e5f43..cab2c75d5a5 100644 --- a/src/osd/modules/file/winrtfile.cpp +++ b/src/osd/modules/file/winrtfile.cpp @@ -380,9 +380,19 @@ bool osd_is_absolute_path(std::string const &path) // osd_get_volume_name //============================================================ -const char *osd_get_volume_name(int idx) +std::string osd_get_volume_name(int idx) { - return nullptr; + return std::string(); +} + + +//============================================================ +// osd_get_volume_names +//============================================================ + +std::vector osd_get_volume_names() +{ + return std::vector(); } diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp index 3e57f689506..8859de8f6e4 100644 --- a/src/osd/modules/input/input_rawinput.cpp +++ b/src/osd/modules/input/input_rawinput.cpp @@ -81,8 +81,8 @@ public: std::wstring enum_key(int index) const { - WCHAR keyname[MAX_PATH]; - DWORD namelen = MAX_PATH; + WCHAR keyname[256]; + DWORD namelen = ARRAY_LENGTH(keyname); if (RegEnumKeyEx(m_key, index, keyname, &namelen, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS) return std::wstring(keyname, namelen); else diff --git a/src/osd/osdfile.h b/src/osd/osdfile.h index 7ee384560b7..ffd4346d7c0 100644 --- a/src/osd/osdfile.h +++ b/src/osd/osdfile.h @@ -16,6 +16,7 @@ #include #include #include +#include /*************************************************************************** @@ -312,9 +313,15 @@ osd_file::error osd_get_full_path(std::string &dst, std::string const &path); /// \brief Retrieves the volume name. /// -/// \param [in] idx Order number of volume. -/// \return Pointer to volume name. -const char *osd_get_volume_name(int idx); +/// \param [in] idx Index number of volume. +/// \return Volume name or empty string of out of range. +std::string osd_get_volume_name(int idx); + + +/// \brief Retrieves volume names. +/// +/// \return Names of all mounted volumes. +std::vector osd_get_volume_names(); #endif // MAME_OSD_OSDFILE_H diff --git a/src/osd/windows/winutil.cpp b/src/osd/windows/winutil.cpp index b662974cfd1..a9358c67737 100644 --- a/src/osd/windows/winutil.cpp +++ b/src/osd/windows/winutil.cpp @@ -103,15 +103,19 @@ BOOL win_is_gui_application() //============================================================ void osd_subst_env(std::string &dst, const std::string &src) { - TCHAR buffer[MAX_PATH]; - - osd::text::tstring t_src = osd::text::to_tstring(src); -#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) - ExpandEnvironmentStrings(t_src.c_str(), buffer, ARRAY_LENGTH(buffer)); -#else - wcsncpy(buffer, t_src.c_str(), ARRAY_LENGTH(buffer)); -#endif - osd::text::from_tstring(dst, buffer); + std::wstring const w_src = osd::text::to_wstring(src); + std::vector buffer(w_src.size() + 2); + DWORD length(ExpandEnvironmentStringsW(w_src.c_str(), &buffer[0], buffer.size())); + while (length && (buffer.size() < length)) + { + buffer.clear(); + buffer.resize(length + 1); + length = ExpandEnvironmentStringsW(w_src.c_str(), &buffer[0], buffer.size()); + } + if (length) + osd::text::from_wstring(dst, &buffer[0]); + else + dst.clear(); } //-------------------------------------------------