From d62714d97779091adec2893d3677c47dfc093955 Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Mon, 23 Aug 2021 10:27:56 +0200 Subject: replace unused IOFLAG_RANDOM with IOFLAG_APPEND --- src/base/system.c | 7 +++++-- src/base/system.h | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 7199cb170..5a80190d0 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -302,9 +302,10 @@ void mem_zero(void *block,unsigned size) IOHANDLE io_open(const char *filename, int flags) { + dbg_assert(flags == IOFLAG_READ || flags == IOFLAG_WRITE || flags == IOFLAG_APPEND, "flags must be read, write or append"); if(flags == IOFLAG_READ) { - #if defined(CONF_FAMILY_WINDOWS) +#if defined(CONF_FAMILY_WINDOWS) // check for filename case sensitive WIN32_FIND_DATA finddata; HANDLE handle; @@ -322,11 +323,13 @@ IOHANDLE io_open(const char *filename, int flags) return 0x0; } FindClose(handle); - #endif +#endif return (IOHANDLE)fopen(filename, "rb"); } if(flags == IOFLAG_WRITE) return (IOHANDLE)fopen(filename, "wb"); + if(flags == IOFLAG_APPEND) + return (IOHANDLE)fopen(filename, "ab"); return 0x0; } diff --git a/src/base/system.h b/src/base/system.h index 3c31854f0..f7c5dd8ef 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -179,7 +179,7 @@ int mem_has_null(const void *block, unsigned size); enum { IOFLAG_READ = 1, IOFLAG_WRITE = 2, - IOFLAG_RANDOM = 4, + IOFLAG_APPEND = 4, IOSEEK_START = 0, IOSEEK_CUR = 1, @@ -196,7 +196,7 @@ typedef struct IOINTERNAL *IOHANDLE; Parameters: filename - File to open. - flags - A set of flags. IOFLAG_READ, IOFLAG_WRITE, IOFLAG_RANDOM. + flags - A set of flags. IOFLAG_READ, IOFLAG_WRITE, IOFLAG_APPEND. Returns: Returns a handle to the file on success and 0 on failure. -- cgit v1.2.3 From 95a6248a3bb001762ff46a8ca5313de0eeb83d0e Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Sun, 22 Aug 2021 22:55:37 +0200 Subject: fix fs_listdir and fs_listdir_fileinfo with unicode on windows --- src/base/system.c | 50 +++++++++++++++++++++++++++----------------------- src/base/system.h | 6 ++---- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 5a80190d0..7faf64cab 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1483,15 +1483,18 @@ static inline time_t filetime_to_unixtime(LPFILETIME filetime) void fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user) { #if defined(CONF_FAMILY_WINDOWS) - WIN32_FIND_DATA finddata; + WIN32_FIND_DATAW finddata; HANDLE handle; - char buffer[1024*2]; + char buffer[IO_MAX_PATH_LENGTH]; + char buffer2[IO_MAX_PATH_LENGTH]; + WCHAR wBuffer[IO_MAX_PATH_LENGTH]; int length; - str_format(buffer, sizeof(buffer), "%s/*", dir); - handle = FindFirstFileA(buffer, &finddata); + str_format(buffer, sizeof(buffer), "%s/*", dir); + MultiByteToWideChar(CP_UTF8, 0, buffer, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); - if (handle == INVALID_HANDLE_VALUE) + handle = FindFirstFileW(wBuffer, &finddata); + if(handle == INVALID_HANDLE_VALUE) return; str_format(buffer, sizeof(buffer), "%s/", dir); @@ -1500,17 +1503,17 @@ void fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user) /* add all the entries */ do { - str_copy(buffer+length, finddata.cFileName, (int)sizeof(buffer)-length); - if(cb(finddata.cFileName, fs_is_dir(buffer), type, user)) + WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer2, IO_MAX_PATH_LENGTH, NULL, NULL); + str_copy(buffer+length, buffer2, (int)sizeof(buffer)-length); + if(cb(buffer2, fs_is_dir(buffer), type, user)) break; } - while (FindNextFileA(handle, &finddata)); + while(FindNextFileW(handle, &finddata)); FindClose(handle); - return; #else struct dirent *entry; - char buffer[1024*2]; + char buffer[IO_MAX_PATH_LENGTH]; int length; DIR *d = opendir(dir); @@ -1529,22 +1532,24 @@ void fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user) /* close the directory and return */ closedir(d); - return; #endif } -void fs_listdir_fileinfo(const char* dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int type, void* user) +void fs_listdir_fileinfo(const char *dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int type, void *user) { #if defined(CONF_FAMILY_WINDOWS) - WIN32_FIND_DATA finddata; + WIN32_FIND_DATAW finddata; HANDLE handle; - char buffer[1024*2]; + char buffer[IO_MAX_PATH_LENGTH]; + char buffer2[IO_MAX_PATH_LENGTH]; + WCHAR wBuffer[IO_MAX_PATH_LENGTH]; int length; - str_format(buffer, sizeof(buffer), "%s/*", dir); - handle = FindFirstFileA(buffer, &finddata); + str_format(buffer, sizeof(buffer), "%s/*", dir); + MultiByteToWideChar(CP_UTF8, 0, buffer, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); - if (handle == INVALID_HANDLE_VALUE) + handle = FindFirstFileW(wBuffer, &finddata); + if(handle == INVALID_HANDLE_VALUE) return; str_format(buffer, sizeof(buffer), "%s/", dir); @@ -1553,24 +1558,24 @@ void fs_listdir_fileinfo(const char* dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int t /* add all the entries */ do { - str_copy(buffer+length, finddata.cFileName, (int)sizeof(buffer)-length); + WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer2, IO_MAX_PATH_LENGTH, NULL, NULL); + str_copy(buffer+length, buffer2, (int)sizeof(buffer)-length); CFsFileInfo info; - info.m_pName = finddata.cFileName; + info.m_pName = buffer2; info.m_TimeCreated = filetime_to_unixtime(&finddata.ftCreationTime); info.m_TimeModified = filetime_to_unixtime(&finddata.ftLastWriteTime); if(cb(&info, fs_is_dir(buffer), type, user)) break; } - while (FindNextFileA(handle, &finddata)); + while(FindNextFileW(handle, &finddata)); FindClose(handle); - return; #else struct dirent *entry; time_t created = -1, modified = -1; - char buffer[1024*2]; + char buffer[IO_MAX_PATH_LENGTH]; int length; DIR *d = opendir(dir); @@ -1597,7 +1602,6 @@ void fs_listdir_fileinfo(const char* dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int t /* close the directory and return */ closedir(d); - return; #endif } diff --git a/src/base/system.h b/src/base/system.h index f7c5dd8ef..a2113f9fa 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -1336,13 +1336,11 @@ void fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user); typedef struct { - const char* m_pName; + const char *m_pName; time_t m_TimeCreated; // seconds since UNIX Epoch time_t m_TimeModified; // seconds since UNIX Epoch } CFsFileInfo; -/* Group: Filesystem */ - /* Function: fs_listdir_fileinfo Lists the files in a directory and gets additional file information @@ -1353,7 +1351,7 @@ typedef struct type - Type of the directory user - Pointer to give to the callback */ -typedef int (*FS_LISTDIR_CALLBACK_FILEINFO)(const CFsFileInfo* info, int is_dir, int dir_type, void *user); +typedef int (*FS_LISTDIR_CALLBACK_FILEINFO)(const CFsFileInfo *info, int is_dir, int dir_type, void *user); void fs_listdir_fileinfo(const char *dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int type, void *user); /* -- cgit v1.2.3 From d415b3f1e798b3c7914613c5de236ebb64aab555 Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Sun, 22 Aug 2021 23:05:05 +0200 Subject: fix io_open with unicode on windows --- src/base/system.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 7faf64cab..c2101fc87 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -42,6 +42,7 @@ #include #include #include + #include #else #error NOT IMPLEMENTED #endif @@ -303,34 +304,51 @@ void mem_zero(void *block,unsigned size) IOHANDLE io_open(const char *filename, int flags) { dbg_assert(flags == IOFLAG_READ || flags == IOFLAG_WRITE || flags == IOFLAG_APPEND, "flags must be read, write or append"); +#if defined(CONF_FAMILY_WINDOWS) + WCHAR wBuffer[IO_MAX_PATH_LENGTH]; if(flags == IOFLAG_READ) { -#if defined(CONF_FAMILY_WINDOWS) // check for filename case sensitive - WIN32_FIND_DATA finddata; + WIN32_FIND_DATAW finddata; HANDLE handle; - int length; + char buffer[IO_MAX_PATH_LENGTH]; - length = str_length(filename); + int length = str_length(filename); if(!filename || !length || filename[length-1] == '\\') return 0x0; - handle = FindFirstFile(filename, &finddata); + MultiByteToWideChar(CP_UTF8, 0, filename, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); + handle = FindFirstFileW(wBuffer, &finddata); if(handle == INVALID_HANDLE_VALUE) return 0x0; - else if(str_comp(filename+length-str_length(finddata.cFileName), finddata.cFileName) != 0) + WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer, IO_MAX_PATH_LENGTH, NULL, NULL); + if(str_comp(filename+length-str_length(buffer), buffer) != 0) { FindClose(handle); return 0x0; } FindClose(handle); -#endif - return (IOHANDLE)fopen(filename, "rb"); + return (IOHANDLE)_wfsopen(wBuffer, L"rb", _SH_DENYNO); + } + if(flags == IOFLAG_WRITE) + { + MultiByteToWideChar(CP_UTF8, 0, filename, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); + return (IOHANDLE)_wfsopen(wBuffer, L"wb", _SH_DENYNO); } + if(flags == IOFLAG_APPEND) + { + MultiByteToWideChar(CP_UTF8, 0, filename, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); + return (IOHANDLE)_wfsopen(wBuffer, L"ab", _SH_DENYNO); + } + return 0x0; +#else + if(flags == IOFLAG_READ) + return (IOHANDLE)fopen(filename, "rb"); if(flags == IOFLAG_WRITE) return (IOHANDLE)fopen(filename, "wb"); if(flags == IOFLAG_APPEND) return (IOHANDLE)fopen(filename, "ab"); return 0x0; +#endif } unsigned io_read(IOHANDLE io, void *buffer, unsigned size) -- cgit v1.2.3 From 543a6169c6e191af62f31f7d531b72b7fc96b42f Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Mon, 23 Aug 2021 10:27:21 +0200 Subject: fix fs_is_dir with unicode on windows --- src/base/system.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index c2101fc87..bdd6b7d71 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1724,25 +1724,22 @@ int fs_is_dir(const char *path) { #if defined(CONF_FAMILY_WINDOWS) /* TODO: do this smarter */ - WIN32_FIND_DATA finddata; + WIN32_FIND_DATAW finddata; HANDLE handle; - char buffer[1024*2]; + char buffer[IO_MAX_PATH_LENGTH]; + WCHAR wBuffer[IO_MAX_PATH_LENGTH]; str_format(buffer, sizeof(buffer), "%s/*", path); + MultiByteToWideChar(CP_UTF8, 0, buffer, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); - if ((handle = FindFirstFileA(buffer, &finddata)) == INVALID_HANDLE_VALUE) + if((handle = FindFirstFileW(wBuffer, &finddata)) == INVALID_HANDLE_VALUE) return 0; - FindClose(handle); return 1; #else struct stat sb; - if (stat(path, &sb) == -1) - return 0; - - if (S_ISDIR(sb.st_mode)) - return 1; - else + if(stat(path, &sb) == -1) return 0; + return S_ISDIR(sb.st_mode) ? 1 : 0; #endif } -- cgit v1.2.3 From aa1c393dec7d892ccab8aac50d6d80cf07362246 Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Mon, 23 Aug 2021 13:27:19 +0200 Subject: fix fs_file_time with unicode on windows --- src/base/system.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index bdd6b7d71..f7f47e830 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1837,8 +1837,12 @@ char *fs_read_str(const char *name) int fs_file_time(const char *name, time_t *created, time_t *modified) { #if defined(CONF_FAMILY_WINDOWS) - WIN32_FIND_DATA finddata; - HANDLE handle = FindFirstFile(name, &finddata); + WIN32_FIND_DATAW finddata; + HANDLE handle; + WCHAR wBuffer[IO_MAX_PATH_LENGTH]; + + MultiByteToWideChar(CP_UTF8, 0, name, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); + handle = FindFirstFileW(wBuffer, &finddata); if(handle == INVALID_HANDLE_VALUE) return 1; -- cgit v1.2.3 From 48787de8da6563fcc047b454470c2f83516cbeb1 Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Mon, 4 Oct 2021 19:44:59 +0200 Subject: fix fs_rename with unicode on windows --- src/base/system.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/base/system.c b/src/base/system.c index f7f47e830..65f96d9e0 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1802,9 +1802,19 @@ int fs_remove(const char *filename) int fs_rename(const char *oldname, const char *newname) { - if(rename(oldname, newname) != 0) +#if defined(CONF_FAMILY_WINDOWS) + WCHAR wOldname[IO_MAX_PATH_LENGTH]; + WCHAR wNewname[IO_MAX_PATH_LENGTH]; + MultiByteToWideChar(CP_UTF8, 0, oldname, IO_MAX_PATH_LENGTH, wOldname, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, newname, IO_MAX_PATH_LENGTH, wNewname, IO_MAX_PATH_LENGTH); + if(MoveFileExW(wOldname, wNewname, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) == 0) return 1; return 0; +#else + if(rename(oldname, newname)) + return 1; + return 0; +#endif } int fs_read(const char *name, void **result, unsigned *result_len) -- cgit v1.2.3 From dd3b1bba81a7d7619a1a5ab7fb82fe7cdc72501d Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Mon, 4 Oct 2021 19:49:36 +0200 Subject: fix fs_remove with unicode on windows --- src/base/system.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/base/system.c b/src/base/system.c index 65f96d9e0..a35e67f42 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1795,9 +1795,17 @@ int fs_parent_dir(char *path) int fs_remove(const char *filename) { - if(remove(filename) != 0) +#if defined(CONF_FAMILY_WINDOWS) + WCHAR wFilename[IO_MAX_PATH_LENGTH]; + MultiByteToWideChar(CP_UTF8, 0, filename, IO_MAX_PATH_LENGTH, wFilename, IO_MAX_PATH_LENGTH); + if(DeleteFileW(wFilename) == 0) return 1; return 0; +#else + if(remove(filename)) + return 1; + return 0; +#endif } int fs_rename(const char *oldname, const char *newname) -- cgit v1.2.3 From 5a7723c9d551d65e388de3d9197f55a3978a86d6 Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Thu, 4 Nov 2021 20:36:02 +0100 Subject: fix fs_storage_path with unicode on windows --- src/base/system.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index a35e67f42..365f5acee 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1626,10 +1626,12 @@ void fs_listdir_fileinfo(const char *dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int t int fs_storage_path(const char *appname, char *path, int max) { #if defined(CONF_FAMILY_WINDOWS) - char *home = getenv("APPDATA"); + WCHAR *home = _wgetenv(L"APPDATA"); + char buffer[IO_MAX_PATH_LENGTH]; if(!home) return -1; - str_format(path, max, "%s/%s", home, appname); + WideCharToMultiByte(CP_UTF8, 0, home, -1, buffer, IO_MAX_PATH_LENGTH, NULL, NULL); + str_format(path, max, "%s/%s", buffer, appname); return 0; #else char *home = getenv("HOME"); -- cgit v1.2.3 From 21e8955d88ade164d82ac52a0c2d43bdde3db491 Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Thu, 4 Nov 2021 20:38:50 +0100 Subject: fix fs_makedir with unicode on windows --- src/base/system.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 365f5acee..793e741be 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1683,8 +1683,10 @@ int fs_storage_path(const char *appname, char *path, int max) int fs_makedir(const char *path) { #if defined(CONF_FAMILY_WINDOWS) - if(_mkdir(path) == 0) - return 0; + WCHAR wBuffer[IO_MAX_PATH_LENGTH]; + MultiByteToWideChar(CP_UTF8, 0, path, -1, wBuffer, IO_MAX_PATH_LENGTH); + if(_wmkdir(wBuffer) == 0) + return 0; if(errno == EEXIST) return 0; return -1; -- cgit v1.2.3 From 8c30768db56994eb840889a904f4ac3e0eb5555d Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Thu, 4 Nov 2021 21:17:44 +0100 Subject: fix fs_getcwd with unicode on windows --- src/base/system.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/base/system.c b/src/base/system.c index 793e741be..4d2431527 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1774,7 +1774,11 @@ char *fs_getcwd(char *buffer, int buffer_size) if(buffer == 0) return 0; #if defined(CONF_FAMILY_WINDOWS) - return _getcwd(buffer, buffer_size); + WCHAR wBuffer[IO_MAX_PATH_LENGTH]; + if(_wgetcwd(wBuffer, buffer_size) == 0) + return 0; + WideCharToMultiByte(CP_UTF8, 0, wBuffer, IO_MAX_PATH_LENGTH, buffer, buffer_size, NULL, NULL); + return buffer; #else return getcwd(buffer, buffer_size); #endif -- cgit v1.2.3 From ea8e7166023a4529d8e4417c5a5eefd68d30857e Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Thu, 4 Nov 2021 21:30:51 +0100 Subject: fix fs_chdir with unicode on windows --- src/base/system.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/base/system.c b/src/base/system.c index 4d2431527..4fbc05b98 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1760,10 +1760,19 @@ int fs_chdir(const char *path) { if(fs_is_dir(path)) { +#if defined(CONF_FAMILY_WINDOWS) + WCHAR wBuffer[IO_MAX_PATH_LENGTH]; + MultiByteToWideChar(CP_UTF8, 0, path, -1, wBuffer, IO_MAX_PATH_LENGTH); + if(_wchdir(wBuffer)) + return 1; + else + return 0; +#else if(chdir(path)) return 1; else return 0; +#endif } else return 1; -- cgit v1.2.3 From 9d8858b86c9b670c9a8a3956db32ae97c221185d Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Sat, 6 Nov 2021 10:29:11 +0100 Subject: fix pnglite usage with unicode on windows --- src/engine/client/graphics_threaded.cpp | 52 +++++++++++++++------------------ 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/src/engine/client/graphics_threaded.cpp b/src/engine/client/graphics_threaded.cpp index 9cc5b3288..796f7de92 100644 --- a/src/engine/client/graphics_threaded.cpp +++ b/src/engine/client/graphics_threaded.cpp @@ -408,41 +408,35 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTexture(const char *pFilename, int CGraphics_Threaded::LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType) { - char aCompleteFilename[IO_MAX_PATH_LENGTH]; - unsigned char *pBuffer; - png_t Png; // ignore_convention - // open file for reading - png_init(0,0); // ignore_convention - + char aCompleteFilename[IO_MAX_PATH_LENGTH]; IOHANDLE File = m_pStorage->OpenFile(pFilename, IOFLAG_READ, StorageType, aCompleteFilename, sizeof(aCompleteFilename)); - if(File) - io_close(File); - else + if(!File) { dbg_msg("game/png", "failed to open file. filename='%s'", pFilename); return 0; } - int Error = png_open_file(&Png, aCompleteFilename); // ignore_convention + png_init(0, 0); // ignore_convention + png_t Png; // ignore_convention + int Error = png_open_read(&Png, 0, File); // ignore_convention if(Error != PNG_NO_ERROR) { - dbg_msg("game/png", "failed to open file. filename='%s'", aCompleteFilename); - if(Error != PNG_FILE_ERROR) - png_close_file(&Png); // ignore_convention + dbg_msg("game/png", "failed to read file. filename='%s'", aCompleteFilename); + io_close(File); return 0; } if(Png.depth != 8 || (Png.color_type != PNG_TRUECOLOR && Png.color_type != PNG_TRUECOLOR_ALPHA) || Png.width > (2<<12) || Png.height > (2<<12)) // ignore_convention { dbg_msg("game/png", "invalid format. filename='%s'", aCompleteFilename); - png_close_file(&Png); // ignore_convention + io_close(File); return 0; } - pBuffer = (unsigned char *)mem_alloc(Png.width * Png.height * Png.bpp); // ignore_convention + unsigned char *pBuffer = (unsigned char *)mem_alloc(Png.width * Png.height * Png.bpp); // ignore_convention png_get_data(&Png, pBuffer); // ignore_convention - png_close_file(&Png); // ignore_convention + io_close(File); pImg->m_Width = Png.width; // ignore_convention pImg->m_Height = Png.height; // ignore_convention @@ -483,21 +477,23 @@ void CGraphics_Threaded::ScreenshotDirect(const char *pFilename) if(Image.m_pData) { // find filename - char aWholePath[1024]; - png_t Png; // ignore_convention - + char aWholePath[IO_MAX_PATH_LENGTH]; + char aBuf[IO_MAX_PATH_LENGTH+32]; IOHANDLE File = m_pStorage->OpenFile(pFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE, aWholePath, sizeof(aWholePath)); if(File) + { + // save png + png_t Png; // ignore_convention + png_open_write(&Png, 0, File); // ignore_convention + png_set_data(&Png, Image.m_Width, Image.m_Height, 8, PNG_TRUECOLOR, (unsigned char *)Image.m_pData); // ignore_convention io_close(File); - - // save png - char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "saved screenshot to '%s'", aWholePath); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf); - png_open_file_write(&Png, aWholePath); // ignore_convention - png_set_data(&Png, Image.m_Width, Image.m_Height, 8, PNG_TRUECOLOR, (unsigned char *)Image.m_pData); // ignore_convention - png_close_file(&Png); // ignore_convention - + str_format(aBuf, sizeof(aBuf), "saved screenshot to '%s'", aWholePath); + } + else + { + str_format(aBuf, sizeof(aBuf), "failed to open file '%s'", pFilename); + } + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client/screenshot", aBuf); mem_free(Image.m_pData); } } -- cgit v1.2.3 From a954457513f1715d782d6527d4f2c86d039be3f4 Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Sat, 20 Nov 2021 11:34:04 +0100 Subject: add UNICODE defines on windows, correct WinAPI method usage --- CMakeLists.txt | 4 ++++ bam.lua | 4 ++++ src/base/system.c | 20 +++++++++++++------- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7e27eb48..b0c4de9aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2121,6 +2121,10 @@ foreach(target ${TARGETS_OWN}) target_compile_options(${target} PRIVATE /wd4267) # Possible loss of data (size_t - int on win64). target_compile_options(${target} PRIVATE /wd4800) # Implicit conversion of int to bool. endif() + if(TARGET_OS STREQUAL "windows") + target_compile_definitions(${target} PRIVATE UNICODE) # Windows headers + target_compile_definitions(${target} PRIVATE _UNICODE) # C-runtime + endif() if(OUR_FLAGS_OWN) target_compile_options(${target} PRIVATE ${OUR_FLAGS_OWN}) endif() diff --git a/bam.lua b/bam.lua index ec87f9395..e22669bd1 100644 --- a/bam.lua +++ b/bam.lua @@ -240,6 +240,10 @@ function GenerateWindowsSettings(settings, conf, target_arch, compiler) settings.cc.defines:Add("_WIN32_WINNT=0x0501") end + -- Unicode support + settings.cc.defines:Add("UNICODE") -- Windows headers + settings.cc.defines:Add("_UNICODE") -- C-runtime + local icons = SharedIcons(compiler) local manifests = SharedManifests(compiler) diff --git a/src/base/system.c b/src/base/system.c index 4fbc05b98..a4fff4832 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -213,8 +213,10 @@ static void logger_stdout(const char *line) static void logger_debugger(const char *line) { #if defined(CONF_FAMILY_WINDOWS) - OutputDebugString(line); - OutputDebugString("\n"); + WCHAR wBuffer[512]; + MultiByteToWideChar(CP_UTF8, 0, line, -1, wBuffer, sizeof(wBuffer)); + OutputDebugStringW(wBuffer); + OutputDebugStringW(L"\n"); #endif } @@ -919,7 +921,7 @@ int net_addr_from_str(NETADDR *addr, const char *string) int size; sa6.sin6_family = AF_INET6; size = (int)sizeof(sa6); - if(WSAStringToAddress(buf, AF_INET6, NULL, (struct sockaddr *)&sa6, &size) != 0) + if(WSAStringToAddressA(buf, AF_INET6, NULL, (struct sockaddr *)&sa6, &size) != 0) return -1; } #else @@ -1006,9 +1008,11 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i { #if defined(CONF_FAMILY_WINDOWS) char buf[128]; + WCHAR wBuffer[128]; int error = WSAGetLastError(); - if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, buf, sizeof(buf), 0) == 0) - buf[0] = 0; + if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, wBuffer, sizeof(wBuffer) / sizeof(WCHAR), 0) == 0) + wBuffer[0] = 0; + WideCharToMultiByte(CP_UTF8, 0, wBuffer, sizeof(wBuffer), buf, sizeof(buf), NULL, NULL); dbg_msg("net", "failed to create socket with domain %d and type %d (%d '%s')", domain, type, error, buf); #else dbg_msg("net", "failed to create socket with domain %d and type %d (%d '%s')", domain, type, errno, strerror(errno)); @@ -1045,11 +1049,13 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i { #if defined(CONF_FAMILY_WINDOWS) char buf[128]; + WCHAR wBuffer[128]; int error = WSAGetLastError(); if(error == WSAEADDRINUSE && use_random_port) continue; - if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, buf, sizeof(buf), 0) == 0) - buf[0] = 0; + if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, wBuffer, sizeof(wBuffer) / sizeof(WCHAR), 0) == 0) + wBuffer[0] = 0; + WideCharToMultiByte(CP_UTF8, 0, wBuffer, sizeof(wBuffer), buf, sizeof(buf), NULL, NULL); dbg_msg("net", "failed to bind socket with domain %d and type %d (%d '%s')", domain, type, error, buf); #else if(errno == EADDRINUSE && use_random_port) -- cgit v1.2.3 From 6423d1ed767a24cea43548b67b7d4cdc96303f6d Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Sat, 20 Nov 2021 12:20:12 +0100 Subject: only declare and attach debug logger on windows --- src/base/system.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index a4fff4832..1c77a916a 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -210,16 +210,15 @@ static void logger_stdout(const char *line) fflush(stdout); } -static void logger_debugger(const char *line) -{ #if defined(CONF_FAMILY_WINDOWS) +static void logger_win_debugger(const char *line) +{ WCHAR wBuffer[512]; MultiByteToWideChar(CP_UTF8, 0, line, -1, wBuffer, sizeof(wBuffer)); OutputDebugStringW(wBuffer); OutputDebugStringW(L"\n"); -#endif } - +#endif static IOHANDLE logfile = 0; static void logger_file(const char *line) @@ -241,7 +240,13 @@ void dbg_logger_stdout() dbg_logger(logger_stdout); } -void dbg_logger_debugger() { dbg_logger(logger_debugger); } +void dbg_logger_debugger() +{ +#if defined(CONF_FAMILY_WINDOWS) + dbg_logger(logger_win_debugger); +#endif +} + void dbg_logger_file(const char *filename) { IOHANDLE handle = io_open(filename, IOFLAG_WRITE); -- cgit v1.2.3 From 9f3b64c40e66aa2234833d973cca66026278ec12 Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Sat, 20 Nov 2021 16:53:53 +0100 Subject: fix incorrect/inconsistent buffer sizes --- src/base/system.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 1c77a916a..15daf20ef 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -214,7 +214,7 @@ static void logger_stdout(const char *line) static void logger_win_debugger(const char *line) { WCHAR wBuffer[512]; - MultiByteToWideChar(CP_UTF8, 0, line, -1, wBuffer, sizeof(wBuffer)); + MultiByteToWideChar(CP_UTF8, 0, line, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); OutputDebugStringW(wBuffer); OutputDebugStringW(L"\n"); } @@ -323,11 +323,11 @@ IOHANDLE io_open(const char *filename, int flags) int length = str_length(filename); if(!filename || !length || filename[length-1] == '\\') return 0x0; - MultiByteToWideChar(CP_UTF8, 0, filename, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, filename, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); handle = FindFirstFileW(wBuffer, &finddata); if(handle == INVALID_HANDLE_VALUE) return 0x0; - WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer, IO_MAX_PATH_LENGTH, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer, sizeof(buffer), NULL, NULL); if(str_comp(filename+length-str_length(buffer), buffer) != 0) { FindClose(handle); @@ -338,12 +338,12 @@ IOHANDLE io_open(const char *filename, int flags) } if(flags == IOFLAG_WRITE) { - MultiByteToWideChar(CP_UTF8, 0, filename, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, filename, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); return (IOHANDLE)_wfsopen(wBuffer, L"wb", _SH_DENYNO); } if(flags == IOFLAG_APPEND) { - MultiByteToWideChar(CP_UTF8, 0, filename, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, filename, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); return (IOHANDLE)_wfsopen(wBuffer, L"ab", _SH_DENYNO); } return 0x0; @@ -1017,7 +1017,7 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i int error = WSAGetLastError(); if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, wBuffer, sizeof(wBuffer) / sizeof(WCHAR), 0) == 0) wBuffer[0] = 0; - WideCharToMultiByte(CP_UTF8, 0, wBuffer, sizeof(wBuffer), buf, sizeof(buf), NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, wBuffer, -1, buf, sizeof(buf), NULL, NULL); dbg_msg("net", "failed to create socket with domain %d and type %d (%d '%s')", domain, type, error, buf); #else dbg_msg("net", "failed to create socket with domain %d and type %d (%d '%s')", domain, type, errno, strerror(errno)); @@ -1060,7 +1060,7 @@ static int priv_net_create_socket(int domain, int type, struct sockaddr *addr, i continue; if(FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, 0, wBuffer, sizeof(wBuffer) / sizeof(WCHAR), 0) == 0) wBuffer[0] = 0; - WideCharToMultiByte(CP_UTF8, 0, wBuffer, sizeof(wBuffer), buf, sizeof(buf), NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, wBuffer, -1, buf, sizeof(buf), NULL, NULL); dbg_msg("net", "failed to bind socket with domain %d and type %d (%d '%s')", domain, type, error, buf); #else if(errno == EADDRINUSE && use_random_port) @@ -1520,7 +1520,7 @@ void fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user) int length; str_format(buffer, sizeof(buffer), "%s/*", dir); - MultiByteToWideChar(CP_UTF8, 0, buffer, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, buffer, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); handle = FindFirstFileW(wBuffer, &finddata); if(handle == INVALID_HANDLE_VALUE) @@ -1532,7 +1532,7 @@ void fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user) /* add all the entries */ do { - WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer2, IO_MAX_PATH_LENGTH, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer2, sizeof(buffer2), NULL, NULL); str_copy(buffer+length, buffer2, (int)sizeof(buffer)-length); if(cb(buffer2, fs_is_dir(buffer), type, user)) break; @@ -1575,7 +1575,7 @@ void fs_listdir_fileinfo(const char *dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int t int length; str_format(buffer, sizeof(buffer), "%s/*", dir); - MultiByteToWideChar(CP_UTF8, 0, buffer, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, buffer, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); handle = FindFirstFileW(wBuffer, &finddata); if(handle == INVALID_HANDLE_VALUE) @@ -1587,7 +1587,7 @@ void fs_listdir_fileinfo(const char *dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int t /* add all the entries */ do { - WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer2, IO_MAX_PATH_LENGTH, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, finddata.cFileName, -1, buffer2, sizeof(buffer2), NULL, NULL); str_copy(buffer+length, buffer2, (int)sizeof(buffer)-length); CFsFileInfo info; @@ -1641,7 +1641,7 @@ int fs_storage_path(const char *appname, char *path, int max) char buffer[IO_MAX_PATH_LENGTH]; if(!home) return -1; - WideCharToMultiByte(CP_UTF8, 0, home, -1, buffer, IO_MAX_PATH_LENGTH, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, home, -1, buffer, sizeof(buffer), NULL, NULL); str_format(path, max, "%s/%s", buffer, appname); return 0; #else @@ -1695,7 +1695,7 @@ int fs_makedir(const char *path) { #if defined(CONF_FAMILY_WINDOWS) WCHAR wBuffer[IO_MAX_PATH_LENGTH]; - MultiByteToWideChar(CP_UTF8, 0, path, -1, wBuffer, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, path, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); if(_wmkdir(wBuffer) == 0) return 0; if(errno == EEXIST) @@ -1744,7 +1744,7 @@ int fs_is_dir(const char *path) char buffer[IO_MAX_PATH_LENGTH]; WCHAR wBuffer[IO_MAX_PATH_LENGTH]; str_format(buffer, sizeof(buffer), "%s/*", path); - MultiByteToWideChar(CP_UTF8, 0, buffer, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, buffer, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); if((handle = FindFirstFileW(wBuffer, &finddata)) == INVALID_HANDLE_VALUE) return 0; @@ -1773,7 +1773,7 @@ int fs_chdir(const char *path) { #if defined(CONF_FAMILY_WINDOWS) WCHAR wBuffer[IO_MAX_PATH_LENGTH]; - MultiByteToWideChar(CP_UTF8, 0, path, -1, wBuffer, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, path, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); if(_wchdir(wBuffer)) return 1; else @@ -1797,7 +1797,7 @@ char *fs_getcwd(char *buffer, int buffer_size) WCHAR wBuffer[IO_MAX_PATH_LENGTH]; if(_wgetcwd(wBuffer, buffer_size) == 0) return 0; - WideCharToMultiByte(CP_UTF8, 0, wBuffer, IO_MAX_PATH_LENGTH, buffer, buffer_size, NULL, NULL); + WideCharToMultiByte(CP_UTF8, 0, wBuffer, -1, buffer, buffer_size, NULL, NULL); return buffer; #else return getcwd(buffer, buffer_size); @@ -1825,7 +1825,7 @@ int fs_remove(const char *filename) { #if defined(CONF_FAMILY_WINDOWS) WCHAR wFilename[IO_MAX_PATH_LENGTH]; - MultiByteToWideChar(CP_UTF8, 0, filename, IO_MAX_PATH_LENGTH, wFilename, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, filename, -1, wFilename, sizeof(wFilename) / sizeof(WCHAR)); if(DeleteFileW(wFilename) == 0) return 1; return 0; @@ -1841,8 +1841,8 @@ int fs_rename(const char *oldname, const char *newname) #if defined(CONF_FAMILY_WINDOWS) WCHAR wOldname[IO_MAX_PATH_LENGTH]; WCHAR wNewname[IO_MAX_PATH_LENGTH]; - MultiByteToWideChar(CP_UTF8, 0, oldname, IO_MAX_PATH_LENGTH, wOldname, IO_MAX_PATH_LENGTH); - MultiByteToWideChar(CP_UTF8, 0, newname, IO_MAX_PATH_LENGTH, wNewname, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, oldname, -1, wOldname, sizeof(wOldname) / sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, newname, -1, wNewname, sizeof(wNewname) / sizeof(WCHAR)); if(MoveFileExW(wOldname, wNewname, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) == 0) return 1; return 0; @@ -1887,7 +1887,7 @@ int fs_file_time(const char *name, time_t *created, time_t *modified) HANDLE handle; WCHAR wBuffer[IO_MAX_PATH_LENGTH]; - MultiByteToWideChar(CP_UTF8, 0, name, IO_MAX_PATH_LENGTH, wBuffer, IO_MAX_PATH_LENGTH); + MultiByteToWideChar(CP_UTF8, 0, name, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); handle = FindFirstFileW(wBuffer, &finddata); if(handle == INVALID_HANDLE_VALUE) return 1; -- cgit v1.2.3 From 92f050f28dc4449bff06ee840faadca0f40caed4 Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Sun, 21 Nov 2021 10:41:23 +0100 Subject: do fs_is_dir smarter --- src/base/system.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index 15daf20ef..d9d4a8068 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1738,18 +1738,10 @@ int fs_makedir_recursive(const char *path) int fs_is_dir(const char *path) { #if defined(CONF_FAMILY_WINDOWS) - /* TODO: do this smarter */ - WIN32_FIND_DATAW finddata; - HANDLE handle; - char buffer[IO_MAX_PATH_LENGTH]; - WCHAR wBuffer[IO_MAX_PATH_LENGTH]; - str_format(buffer, sizeof(buffer), "%s/*", path); - MultiByteToWideChar(CP_UTF8, 0, buffer, -1, wBuffer, sizeof(wBuffer) / sizeof(WCHAR)); - - if((handle = FindFirstFileW(wBuffer, &finddata)) == INVALID_HANDLE_VALUE) - return 0; - FindClose(handle); - return 1; + WCHAR wPath[IO_MAX_PATH_LENGTH]; + MultiByteToWideChar(CP_UTF8, 0, path, -1, wPath, sizeof(wPath) / sizeof(WCHAR)); + DWORD attributes = GetFileAttributesW(wPath); + return attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; #else struct stat sb; if(stat(path, &sb) == -1) -- cgit v1.2.3 From be2d79b7614a502dc8334026f3f0bb624d8fd22c Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Sun, 21 Nov 2021 10:46:43 +0100 Subject: remove unused fs_getmtime in favor of fs_file_time --- src/base/system.c | 9 --------- src/base/system.h | 6 ------ 2 files changed, 15 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index d9d4a8068..ad128b137 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -1750,15 +1750,6 @@ int fs_is_dir(const char *path) #endif } -time_t fs_getmtime(const char *path) -{ - struct stat sb; - if(stat(path, &sb) == -1) - return 0; - - return sb.st_mtime; -} - int fs_chdir(const char *path) { if(fs_is_dir(path)) diff --git a/src/base/system.h b/src/base/system.h index a2113f9fa..7b6a224a8 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -1406,12 +1406,6 @@ int fs_storage_path(const char *appname, char *path, int max); */ int fs_is_dir(const char *path); -/* - Function: fs_getmtime - Gets the modification time of a file -*/ -time_t fs_getmtime(const char *path); - /* Function: fs_chdir Changes current working directory -- cgit v1.2.3 From 4f28113abd56ccb47c432078948b402cd31fe0ab Mon Sep 17 00:00:00 2001 From: Robert Müller Date: Mon, 22 Nov 2021 23:25:51 +0100 Subject: fix command line arguments with unicode on windows Co-authored-by: heinrich5991 --- src/base/system.c | 45 +++++++++++++++++++++++++++++++++++++++++++ src/base/system.h | 26 +++++++++++++++++++++++++ src/engine/client/client.cpp | 2 ++ src/engine/server/server.cpp | 2 ++ src/mastersrv/mastersrv.cpp | 17 ++++++++-------- src/test/test.cpp | 9 ++++++--- src/tools/crapnet.cpp | 2 +- src/tools/fake_server.cpp | 5 ++++- src/tools/map_resave.cpp | 40 +++++++++++++++++++------------------- src/tools/map_version.cpp | 5 ++++- src/tools/packetgen.cpp | 2 +- src/versionsrv/versionsrv.cpp | 7 ++++--- 12 files changed, 124 insertions(+), 38 deletions(-) diff --git a/src/base/system.c b/src/base/system.c index ad128b137..091a11034 100644 --- a/src/base/system.c +++ b/src/base/system.c @@ -43,6 +43,7 @@ #include #include #include + #include #else #error NOT IMPLEMENTED #endif @@ -2858,6 +2859,50 @@ int pid() #endif } +void cmdline_fix(int *argc, const char ***argv) +{ +#if defined(CONF_FAMILY_WINDOWS) + int wide_argc = 0; + WCHAR **wide_argv = CommandLineToArgvW(GetCommandLineW(), &wide_argc); + dbg_assert(wide_argv != NULL, "CommandLineToArgvW failure"); + + int total_size = 0; + + for(int i = 0; i < wide_argc; i++) + { + int size = WideCharToMultiByte(CP_UTF8, 0, wide_argv[i], -1, NULL, 0, NULL, NULL); + dbg_assert(size != 0, "WideCharToMultiByte failure"); + total_size += size; + } + + char **new_argv = (char **)malloc((wide_argc + 1) * sizeof(*new_argv)); + new_argv[0] = (char *)malloc(total_size); + mem_zero(new_argv[0], total_size); + + int remaining_size = total_size; + for(int i = 0; i < wide_argc; i++) + { + int size = WideCharToMultiByte(CP_UTF8, 0, wide_argv[i], -1, new_argv[i], remaining_size, NULL, NULL); + dbg_assert(size != 0, "WideCharToMultiByte failure"); + + remaining_size -= size; + new_argv[i + 1] = new_argv[i] + size; + } + + new_argv[wide_argc] = 0; + *argc = wide_argc; + *argv = (const char **)new_argv; +#endif +} + +void cmdline_free(int argc, const char **argv) +{ +#if defined(CONF_FAMILY_WINDOWS) + free((void *)*argv); + free((char **)argv); +#endif +} + unsigned bytes_be_to_uint(const unsigned char *bytes) { return (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<<8) | bytes[3]; diff --git a/src/base/system.h b/src/base/system.h index 7b6a224a8..1f5d7fd43 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -1784,6 +1784,32 @@ void secure_random_fill(void *bytes, unsigned length); */ int pid(); +/* + Function: cmdline_fix + Fixes the command line arguments to be encoded in UTF-8 on all + systems. + + Parameters: + argc - A pointer to the argc parameter that was passed to the main function. + argv - A pointer to the argv parameter that was passed to the main function. + + Remarks: + - You need to call cmdline_free once you're no longer using the + results. +*/ +void cmdline_fix(int *argc, const char ***argv); + +/* + Function: cmdline_free + Frees memory that was allocated by cmdline_fix. + + Parameters: + argc - The argc obtained from cmdline_fix. + argv - The argv obtained from cmdline_fix. + +*/ +void cmdline_free(int argc, const char **argv); + /* Function: bytes_be_to_uint Packs 4 big endian bytes into an unsigned diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index b9a2e0142..ad046c184 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2559,6 +2559,7 @@ extern "C" int TWMain(int argc, const char **argv) // ignore_convention int main(int argc, const char **argv) // ignore_convention #endif { + cmdline_fix(&argc, &argv); #if defined(CONF_FAMILY_WINDOWS) bool QuickEditMode = false; for(int i = 1; i < argc; i++) // ignore_convention @@ -2723,5 +2724,6 @@ int main(int argc, const char **argv) // ignore_convention delete pEngineMap; delete pEngineMasterServer; + cmdline_free(argc, argv); return 0; } diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index d3375782e..2f170fc9c 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -1819,6 +1819,7 @@ void HandleSigInt(int Param) int main(int argc, const char **argv) // ignore_convention { + cmdline_fix(&argc, &argv); #if defined(CONF_FAMILY_WINDOWS) for(int i = 1; i < argc; i++) // ignore_convention { @@ -1923,5 +1924,6 @@ int main(int argc, const char **argv) // ignore_convention delete pStorage; delete pConfigManager; + cmdline_free(argc, argv); return Ret; } diff --git a/src/mastersrv/mastersrv.cpp b/src/mastersrv/mastersrv.cpp index 624a9f3fe..e19672313 100644 --- a/src/mastersrv/mastersrv.cpp +++ b/src/mastersrv/mastersrv.cpp @@ -280,14 +280,11 @@ void ReloadBans() m_pConsole->ExecuteFile("master.cfg"); } -int main(int argc, const char **argv) // ignore_convention +int main(int argc, const char **argv) { - int64 LastBuild = 0, LastBanReload = 0; - ServerType Type = SERVERTYPE_INVALID; - NETADDR BindAddr; - dbg_logger_stdout(); - + cmdline_fix(&argc, &argv); + mem_copy(m_CountData.m_Header, SERVERBROWSE_COUNT, sizeof(SERVERBROWSE_COUNT)); int FlagMask = CFGFLAG_MASTER; @@ -307,9 +304,10 @@ int main(int argc, const char **argv) // ignore_convention pConfigManager->Init(FlagMask); m_pConsole->Init(); m_NetBan.Init(m_pConsole, pStorage); - if(argc > 1) // ignore_convention - m_pConsole->ParseArguments(argc-1, &argv[1]); // ignore_convention + if(argc > 1) + m_pConsole->ParseArguments(argc-1, &argv[1]); + NETADDR BindAddr; if(pConfig->m_Bindaddr[0] && net_host_lookup(pConfig->m_Bindaddr, &BindAddr, NETTYPE_ALL) == 0) { // got bindaddr @@ -345,6 +343,8 @@ int main(int argc, const char **argv) // ignore_convention dbg_msg("mastersrv", "started"); + int64 LastBuild = 0, LastBanReload = 0; + ServerType Type = SERVERTYPE_INVALID; while(1) { m_NetOp.Update(); @@ -460,5 +460,6 @@ int main(int argc, const char **argv) // ignore_convention thread_sleep(1); } + cmdline_free(argc, argv); return 0; } diff --git a/src/test/test.cpp b/src/test/test.cpp index c14df1dd3..ccef77b33 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -17,9 +17,12 @@ void CTestInfo::Filename(char *pBuffer, int BufferLength, const char *pSuffix) str_format(pBuffer, BufferLength, "%s%s", m_aFilenamePrefix, pSuffix); } -int main(int argc, char **argv) +int main(int argc, const char **argv) { - ::testing::InitGoogleTest(&argc, argv); + cmdline_fix(&argc, &argv); + ::testing::InitGoogleTest(&argc, const_cast(argv)); net_init(); - return RUN_ALL_TESTS(); + int Result = RUN_ALL_TESTS(); + cmdline_free(argc, argv); + return Result; } diff --git a/src/tools/crapnet.cpp b/src/tools/crapnet.cpp index 20cea2bde..146f1fb48 100644 --- a/src/tools/crapnet.cpp +++ b/src/tools/crapnet.cpp @@ -206,7 +206,7 @@ void Run(unsigned short Port, NETADDR Dest) } } -int main(int argc, char **argv) // ignore_convention +int main(int argc, const char **argv) { NETADDR Addr = {NETTYPE_IPV4, {127,0,0,1},8303}; dbg_logger_stdout(); diff --git a/src/tools/fake_server.cpp b/src/tools/fake_server.cpp index 81bb1cebb..0e1e481a8 100644 --- a/src/tools/fake_server.cpp +++ b/src/tools/fake_server.cpp @@ -148,8 +148,10 @@ static int Run() } } -int main(int argc, char **argv) +int main(int argc, const char **argv) { + cmdline_fix(&argc, &argv); + pNet = new CNetServer; while(argc) @@ -214,6 +216,7 @@ int main(int argc, char **argv) int RunReturn = Run(); delete pNet; + cmdline_free(argc, argv); return RunReturn; } diff --git a/src/tools/map_resave.cpp b/src/tools/map_resave.cpp index 0a624b0f4..45d025e39 100644 --- a/src/tools/map_resave.cpp +++ b/src/tools/map_resave.cpp @@ -6,40 +6,40 @@ int main(int argc, const char **argv) { - IStorage *pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv); - int Index, ID = 0, Type = 0, Size; - void *pPtr; - char aFileName[1024]; - CDataFileReader DataFile; - CDataFileWriter df; + cmdline_fix(&argc, &argv); + IStorage *pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv); if(!pStorage || argc != 3) return -1; - str_format(aFileName, sizeof(aFileName), "%s", argv[2]); - - if(!DataFile.Open(pStorage, argv[1], IStorage::TYPE_ALL)) + CDataFileReader Reader; + if(!Reader.Open(pStorage, argv[1], IStorage::TYPE_ALL)) return -1; - if(!df.Open(pStorage, aFileName)) + + CDataFileWriter Writer; + if(!Writer.Open(pStorage, argv[2])) return -1; // add all items - for(Index = 0; Index < DataFile.NumItems(); Index++) + for(int Index = 0; Index < Reader.NumItems(); Index++) { - pPtr = DataFile.GetItem(Index, &Type, &ID); - Size = DataFile.GetItemSize(Index); - df.AddItem(Type, ID, Size, pPtr); + int Type, ID; + void *pPtr = Reader.GetItem(Index, &Type, &ID); + int Size = Reader.GetItemSize(Index); + Writer.AddItem(Type, ID, Size, pPtr); } // add all data - for(Index = 0; Index < DataFile.NumData(); Index++) + for(int Index = 0; Index < Reader.NumData(); Index++) { - pPtr = DataFile.GetData(Index); - Size = DataFile.GetDataSize(Index); - df.AddData(Size, pPtr); + void *pPtr = Reader.GetData(Index); + int Size = Reader.GetDataSize(Index); + Writer.AddData(Size, pPtr); } - DataFile.Close(); - df.Finish(); + Reader.Close(); + Writer.Finish(); + + cmdline_free(argc, argv); return 0; } diff --git a/src/tools/map_version.cpp b/src/tools/map_version.cpp index fbeb27d74..55b28c3a4 100644 --- a/src/tools/map_version.cpp +++ b/src/tools/map_version.cpp @@ -46,8 +46,10 @@ io_write(s_File, aBuf, str_length(aBuf)); return 0; } -int main(int argc, const char **argv) // ignore_convention +int main(int argc, const char **argv) { + cmdline_fix(&argc, &argv); + IKernel *pKernel = IKernel::Create(); s_pStorage = CreateStorage("Teeworlds", IStorage::STORAGETYPE_BASIC, argc, argv); s_pEngineMap = CreateEngineMap(); @@ -67,5 +69,6 @@ int main(int argc, const char **argv) // ignore_convention io_close(s_File); } + cmdline_free(argc, argv); return 0; } diff --git a/src/tools/packetgen.cpp b/src/tools/packetgen.cpp index 0d3f5c0e2..25fa7ebf8 100644 --- a/src/tools/packetgen.cpp +++ b/src/tools/packetgen.cpp @@ -28,7 +28,7 @@ void Run(NETADDR Dest) } } -int main(int argc, char **argv) +int main(int argc, const char **argv) { NETADDR Dest = {NETTYPE_IPV4, {127,0,0,1}, 8303}; Run(Dest); diff --git a/src/versionsrv/versionsrv.cpp b/src/versionsrv/versionsrv.cpp index 698251060..1413d8baa 100644 --- a/src/versionsrv/versionsrv.cpp +++ b/src/versionsrv/versionsrv.cpp @@ -79,11 +79,10 @@ void SendVer(NETADDR *pAddr, TOKEN ResponseToken) g_NetOp.Send(&p, ResponseToken); } -int main(int argc, const char **argv) // ignore_convention +int main(int argc, const char **argv) { - NETADDR BindAddr; - dbg_logger_stdout(); + cmdline_fix(&argc, &argv); int FlagMask = 0; IKernel *pKernel = IKernel::Create(); @@ -100,6 +99,7 @@ int main(int argc, const char **argv) // ignore_convention pConfigManager->Init(FlagMask); pConsole->Init(); + NETADDR BindAddr; mem_zero(&BindAddr, sizeof(BindAddr)); BindAddr.type = NETTYPE_ALL; BindAddr.port = VERSIONSRV_PORT; @@ -155,5 +155,6 @@ int main(int argc, const char **argv) // ignore_convention thread_sleep(1); } + cmdline_free(argc, argv); return 0; } -- cgit v1.2.3