diff --git a/src/Platform.cpp b/src/Platform.cpp index 84669b4f7..c159b0fff 100644 --- a/src/Platform.cpp +++ b/src/Platform.cpp @@ -28,9 +28,14 @@ ByteString ExecutableName() { ByteString ret; #if defined(WIN) - char *name = (char *)malloc(64); + using Char = wchar_t; +#else + using Char = char; +#endif +#if defined(WIN) + wchar_t *name = (wchar_t *)malloc(sizeof(wchar_t) * 64); DWORD max = 64, res; - while ((res = GetModuleFileName(NULL, name, max)) >= max) + while ((res = GetModuleFileNameW(NULL, name, max)) >= max) { #elif defined MACOSX char *fn = (char*)malloc(64),*name = (char*)malloc(PATH_MAX); @@ -59,10 +64,10 @@ ByteString ExecutableName() #endif #ifndef MACOSX max *= 2; - char* realloced_name = (char *)realloc(name, max); + Char* realloced_name = (Char *)realloc(name, sizeof(Char) * max); assert(realloced_name != NULL); name = realloced_name; - memset(name, 0, max); + memset(name, 0, sizeof(Char) * max); } #endif if (res <= 0) @@ -70,7 +75,11 @@ ByteString ExecutableName() free(name); return ""; } +#if defined(WIN) + ret = WinNarrow(name); +#else ret = name; +#endif free(name); return ret; } @@ -81,7 +90,7 @@ void DoRestart() if (exename.length()) { #ifdef WIN - int ret = int(INT_PTR(ShellExecute(NULL, NULL, exename.c_str(), NULL, NULL, SW_SHOWNORMAL))); + int ret = int(INT_PTR(ShellExecuteW(NULL, NULL, WinWiden(exename).c_str(), NULL, NULL, SW_SHOWNORMAL))); if (ret <= 32) { fprintf(stderr, "cannot restart: ShellExecute(...) failed: code %i\n", ret); @@ -109,7 +118,7 @@ void DoRestart() void OpenURI(ByteString uri) { #if defined(WIN) - if (int(INT_PTR(ShellExecute(NULL, NULL, uri.c_str(), NULL, NULL, SW_SHOWNORMAL))) <= 32) + if (int(INT_PTR(ShellExecuteW(NULL, NULL, WinWiden(uri).c_str(), NULL, NULL, SW_SHOWNORMAL))) <= 32) { fprintf(stderr, "cannot open URI: ShellExecute(...) failed\n"); } @@ -167,4 +176,36 @@ void LoadFileInResource(int name, int type, unsigned int& size, const char*& dat #endif } +#ifdef WIN +ByteString WinNarrow(const std::wstring &source) +{ + int buffer_size = WideCharToMultiByte(CP_UTF8, 0, source.c_str(), source.size(), nullptr, 0, NULL, NULL); + if (!buffer_size) + { + return ""; + } + std::string output(buffer_size, 0); + if (!WideCharToMultiByte(CP_UTF8, 0, source.c_str(), source.size(), &output[0], buffer_size, NULL, NULL)) + { + return ""; + } + return output; +} + +std::wstring WinWiden(const ByteString &source) +{ + int buffer_size = MultiByteToWideChar(CP_UTF8, 0, source.c_str(), source.size(), nullptr, 0); + if (!buffer_size) + { + return L""; + } + std::wstring output(buffer_size, 0); + if (!MultiByteToWideChar(CP_UTF8, 0, source.c_str(), source.size(), &output[0], buffer_size)) + { + return L""; + } + return output; +} +#endif + } diff --git a/src/Platform.h b/src/Platform.h index 76dfbfb29..f0d71f3a2 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -4,6 +4,10 @@ #include "common/String.h" +#ifdef WIN +# include +#endif + namespace Platform { ByteString ExecutableName(); @@ -15,6 +19,11 @@ namespace Platform long unsigned int GetTime(); void LoadFileInResource(int name, int type, unsigned int& size, const char*& data); + +#ifdef WIN + ByteString WinNarrow(const std::wstring &source); + std::wstring WinWiden(const ByteString &source); +#endif } #endif diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 771cd3bf3..67ba7e202 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -162,57 +162,33 @@ bool Client::DoInstallation() int returnval; LONG rresult; HKEY newkey; - ByteString currentfilename2 = Platform::ExecutableName(); - // this isn't necessary but I don't feel like c++ifying this code right now - const char *currentfilename = currentfilename2.c_str(); - char *iconname = NULL; - char *opencommand = NULL; - char *protocolcommand = NULL; - //char AppDataPath[MAX_PATH]; - char *AppDataPath = NULL; - iconname = (char*)malloc(strlen(currentfilename)+6); - sprintf(iconname, "%s,-102", currentfilename); + ByteString currentfilename = Platform::ExecutableName(); + ByteString iconname = currentfilename + ",-102"; + ByteString AppDataPath = Platform::WinNarrow(_wgetcwd(NULL, 0)); + ByteString opencommand = "\"" + currentfilename + "\" open \"%%1\" ddir \"" + AppDataPath + "\""; + ByteString protocolcommand = "\"" + currentfilename + "\" ddir \"" + AppDataPath + "\" ptsave \"%%1\""; - //Create Roaming application data folder - /*if(!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, AppDataPath))) - { - returnval = 0; - goto finalise; - }*/ - - AppDataPath = _getcwd(NULL, 0); - - //Move Game executable into application data folder - //TODO: Implement - - opencommand = (char*)malloc(strlen(currentfilename)+53+strlen(AppDataPath)); - protocolcommand = (char*)malloc(strlen(currentfilename)+53+strlen(AppDataPath)); - /*if((strlen(AppDataPath)+strlen(APPDATA_SUBDIR "\\Powder Toy")) Client::DirectorySearch(ByteString directory, ByteString std::vector directoryList; #if defined(WIN) && !defined(__GNUC__) //Windows - struct _finddata_t currentFile; + struct _wfinddata_t currentFile; intptr_t findFileHandle; ByteString fileMatch = directory + "*.*"; - findFileHandle = _findfirst(fileMatch.c_str(), ¤tFile); + findFileHandle = _wfindfirst(Platform::WinWiden(fileMatch).c_str(), ¤tFile); if (findFileHandle == -1L) { #ifdef DEBUG @@ -464,11 +436,11 @@ std::vector Client::DirectorySearch(ByteString directory, ByteString } do { - ByteString currentFileName = ByteString(currentFile.name); + ByteString currentFileName = Platform::WinNarrow(currentFile.name); if(currentFileName.length()>4) directoryList.push_back(directory+currentFileName); } - while (_findnext(findFileHandle, ¤tFile) == 0); + while (_wfindnext(findFileHandle, ¤tFile) == 0); _findclose(findFileHandle); #else //Linux or MinGW @@ -519,7 +491,7 @@ std::vector Client::DirectorySearch(ByteString directory, ByteString int Client::MakeDirectory(const char * dirName) { #ifdef WIN - return _mkdir(dirName); + return _wmkdir(Platform::WinWiden(dirName).c_str()); #else return mkdir(dirName, 0755); #endif