@@ -48,8 +48,9 @@ namespace Slang
4848/* static */ SlangResult File::remove (const String& fileName)
4949{
5050#ifdef _WIN32
51- // https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-deletefilea
52- if (DeleteFileA (fileName.getBuffer ()))
51+
52+ // https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-deletefilew
53+ if (DeleteFileW (fileName.toWString ()))
5354 {
5455 return SLANG_OK ;
5556 }
@@ -77,10 +78,10 @@ namespace Slang
7778 int count = MAX_PATH + 1 ;
7879 while (true )
7980 {
80- char * chars = tempPath. prepareForAppend ( count);
81+ wchar_t * wideChars = ( wchar_t *) _alloca ( count * sizeof ( wchar_t ) );
8182 // Gets the temp path env string (no guarantee it's a valid path).
82- // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha
83- DWORD ret = ::GetTempPathA (count - 1 , chars );
83+ // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppathw
84+ DWORD ret = ::GetTempPathW (count - 1 , wideChars );
8485 if (ret == 0 )
8586 {
8687 return SLANG_FAIL ;
@@ -90,7 +91,7 @@ namespace Slang
9091 count = ret + 1 ;
9192 continue ;
9293 }
93- tempPath. appendInPlace (chars, count );
94+ tempPath = String::fromWString (wideChars );
9495 break ;
9596 }
9697 }
@@ -104,19 +105,18 @@ namespace Slang
104105 String tempFileName;
105106
106107 {
107- int count = MAX_PATH + 1 ;
108- char * chars = tempFileName.prepareForAppend (count);
108+ wchar_t wideChars[MAX_PATH + 1 ];
109109
110- // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamea
110+ // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettempfilenamew
111111 // Generates a temporary file name.
112112 // Will create a file with this name.
113- DWORD ret = ::GetTempFileNameA (tempPath.getBuffer (), prefix.getBuffer (), 0 , chars );
113+ DWORD ret = ::GetTempFileNameW (tempPath.toWString (), prefix.toWString (), 0 , wideChars );
114114
115115 if (ret == 0 )
116116 {
117117 return SLANG_FAIL ;
118118 }
119- tempFileName. appendInPlace (chars, :: strlen (chars) );
119+ tempFileName = String::fromWString (wideChars );
120120 }
121121
122122 SLANG_ASSERT (File::exists (tempFileName));
@@ -768,17 +768,17 @@ SlangResult Path::remove(const String& path)
768768 {
769769 case SLANG_PATH_TYPE_FILE :
770770 {
771- // https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-deletefilea
772- if (DeleteFileA (path.getBuffer ()))
771+ // https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-deletefilew
772+ if (DeleteFileW (path.toWString ()))
773773 {
774774 return SLANG_OK ;
775775 }
776776 break ;
777777 }
778778 case SLANG_PATH_TYPE_DIRECTORY :
779779 {
780- // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-removedirectorya
781- if (RemoveDirectoryA (path.getBuffer ()))
780+ // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-removedirectoryw
781+ if (RemoveDirectoryW (path.toWString ()))
782782 {
783783 return SLANG_OK ;
784784 }
@@ -810,20 +810,26 @@ SlangResult Path::remove(const String& path)
810810 // Path::remove() doesn't support remove a non-empty directory, so we need to implement
811811 // a simple function to remove the directory recursively.
812812#ifdef _WIN32
813- // https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shfileoperationa
813+ // https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shfileoperationw
814814 // Note: the fromPath requires a double-null-terminated string.
815- String newPath = path;
816- newPath.append (' \0 ' );
817- SHFILEOPSTRUCTA file_op = {
815+ // Convert to wide string first, then manually create double-null-terminated buffer
816+ auto widePath = path.toWString ();
817+ Index widePathLen = wcslen (widePath);
818+ wchar_t * doubleNullPath = (wchar_t *)_alloca ((widePathLen + 2 ) * sizeof (wchar_t ));
819+ wcscpy (doubleNullPath, widePath);
820+ doubleNullPath[widePathLen] = L' \0 ' ; // First null terminator
821+ doubleNullPath[widePathLen + 1 ] = L' \0 ' ; // Second null terminator for SHFileOperationW
822+
823+ SHFILEOPSTRUCTW file_op = {
818824 NULL ,
819825 FO_DELETE ,
820- newPath. begin () ,
826+ doubleNullPath ,
821827 nullptr ,
822828 FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT ,
823829 false ,
824830 0 ,
825831 nullptr };
826- int ret = SHFileOperationA (&file_op);
832+ int ret = SHFileOperationW (&file_op);
827833 if (ret)
828834 {
829835 return SLANG_FAIL ;
@@ -973,13 +979,28 @@ static SlangResult _calcExectuablePath(char* outPath, size_t* ioSize)
973979 SLANG_ASSERT (bufferSize > 0 );
974980
975981#if SLANG_WINDOWS_FAMILY
976- // https://docs.microsoft.com/en-us/windows/desktop/api/libloaderapi/nf-libloaderapi-getmodulefilenamea
982+ // https://docs.microsoft.com/en-us/windows/desktop/api/libloaderapi/nf-libloaderapi-getmodulefilenamew
977983
978- DWORD res = ::GetModuleFileNameA (::GetModuleHandle (nullptr ), outPath, DWORD (bufferSize));
984+ // Use wide character version and convert back to UTF-8
985+ wchar_t * widePath = (wchar_t *)_alloca (bufferSize * sizeof (wchar_t ));
986+ DWORD res = ::GetModuleFileNameW (::GetModuleHandle (nullptr ), widePath, DWORD (bufferSize));
979987 // If it fits it's the size not including terminator. So must be less than bufferSize
980988 if (res < bufferSize)
981989 {
982- return SLANG_OK ;
990+ // Convert back to UTF-8
991+ int utf8Len = WideCharToMultiByte (
992+ CP_UTF8 ,
993+ 0 ,
994+ widePath,
995+ -1 ,
996+ outPath,
997+ (int )bufferSize,
998+ nullptr ,
999+ nullptr );
1000+ if (utf8Len > 0 )
1001+ {
1002+ return SLANG_OK ;
1003+ }
9831004 }
9841005 return SLANG_E_BUFFER_TOO_SMALL ;
9851006#elif SLANG_LINUX_FAMILY
0 commit comments