Get_unicode_filename() can malloc() the return string

This commit is contained in:
Thomas Bernard 2019-01-15 17:18:34 +01:00
parent a69ad46902
commit 75c93b0ce4
No known key found for this signature in database
GPG Key ID: 0FF11B67A5C0863C
3 changed files with 69 additions and 30 deletions

View File

@ -731,19 +731,24 @@ void Get_full_filename(char * output_name, const char * file_name, const char *
/** /**
* Convert a file name to unicode characters * Convert a file name to unicode characters
* *
* If the parametter is null, the buffer is malloc'ed
*
* @param filename_unicode the output buffer of MAX_PATH_CHARACTERS wide characters * @param filename_unicode the output buffer of MAX_PATH_CHARACTERS wide characters
* @param filename the input file name * @param filename the input file name
* @param directory the input file directory * @param directory the input file directory
* @return 0 if no conversion has taken place. * @return NULL if no conversion has taken place.
* @return 1 if the unicode filename has been retrieved * @return filename_unicode if the unicode filename has been retrieved
*/ */
int Get_Unicode_Filename(word * filename_unicode, const char * filename, const char * directory) word * Get_Unicode_Filename(word * filename_unicode, const char * filename, const char * directory)
{ {
#if defined(WIN32) #if defined(WIN32)
int i = 0, j = 0; int i = 0;
WCHAR shortPath[MAX_PATH_CHARACTERS]; DWORD len;
WCHAR longPath[MAX_PATH_CHARACTERS]; WCHAR * shortPath;
WCHAR * longPath;
WCHAR * sep;
shortPath = (WCHAR *)malloc(sizeof(WCHAR) * (strlen(filename) + strlen(directory) + 2));
// copy the full path to a wide character buffer : // copy the full path to a wide character buffer :
while (directory[0] != '\0') while (directory[0] != '\0')
shortPath[i++] = *directory++; shortPath[i++] = *directory++;
@ -752,42 +757,75 @@ int Get_Unicode_Filename(word * filename_unicode, const char * filename, const c
while (filename[0] != '\0') while (filename[0] != '\0')
shortPath[i++] = *filename++; shortPath[i++] = *filename++;
shortPath[i++] = 0; shortPath[i++] = 0;
if (GetLongPathNameW(shortPath, longPath, MAX_PATH_CHARACTERS) == 0) len = GetLongPathNameW(shortPath, NULL, 0);
return 0; if (len == 0)
i = 0;
while (longPath[j] != 0)
{ {
if (longPath[j] == '\\') free(shortPath);
i = 0; return NULL;
else
filename_unicode[i++] = longPath[j];
j++;
} }
filename_unicode[i++] = 0; longPath = (WCHAR *)malloc(len * sizeof(WCHAR));
return 1; if (GetLongPathNameW(shortPath, longPath, len) == 0)
{
free(shortPath);
return NULL;
}
free(shortPath);
sep = wcsrchr(longPath, '\\');
if (sep == NULL)
{
if (filename_unicode == NULL)
return (word *)longPath;
memcpy(filename_unicode, longPath, sizeof(word) * len);
}
else
{
sep++;
len = wcslen(sep) + 1;
if (filename_unicode == NULL)
filename_unicode = (word *)malloc(sizeof(word) * len);
memcpy(filename_unicode, sep, sizeof(word) * len);
}
free(longPath);
return filename_unicode;
#elif defined(ENABLE_FILENAMES_ICONV) #elif defined(ENABLE_FILENAMES_ICONV)
int allocated_memory = 0;
char * input = (char *)filename; char * input = (char *)filename;
size_t inbytesleft = strlen(filename); size_t inbytesleft = strlen(filename);
char * output = (char *)filename_unicode; char * output;
size_t outbytesleft = (MAX_PATH_CHARACTERS - 1) * 2; size_t outbytesleft;
size_t r;
(void)directory; // unused (void)directory; // unused
if (cd_utf16 != (iconv_t)-1) if (cd_utf16 == (iconv_t)-1)
return NULL;
if (filename_unicode == NULL)
{ {
size_t r = iconv(cd_utf16, &input, &inbytesleft, &output, &outbytesleft); filename_unicode = malloc(sizeof(word) * (inbytesleft + 1));
if (filename_unicode == NULL)
return NULL;
allocated_memory = 1;
outbytesleft = inbytesleft * 2;
}
else
outbytesleft = (MAX_PATH_CHARACTERS - 1) * 2;
output = (char *)filename_unicode;
r = iconv(cd_utf16, &input, &inbytesleft, &output, &outbytesleft);
if (r != (size_t)-1) if (r != (size_t)-1)
{ {
output[0] = '\0'; output[0] = '\0';
output[1] = '\0'; output[1] = '\0';
return 1; return filename_unicode;
} }
} if (allocated_memory)
return 0; free(filename_unicode);
return NULL;
#else #else
(void)filename_unicode; (void)filename_unicode;
(void)filename; (void)filename;
(void)directory; (void)directory;
// not implemented // not implemented
return 0; return NULL;
#endif #endif
} }

View File

@ -156,7 +156,7 @@ void For_each_directory_entry(const char * directory_name, void * pdata, T_File_
/// The point is simply to insert a PATH_SEPARATOR when needed. /// The point is simply to insert a PATH_SEPARATOR when needed.
void Get_full_filename(char * output_name, const char * file_name, const char * directory_name); void Get_full_filename(char * output_name, const char * file_name, const char * directory_name);
int Get_Unicode_Filename(word * filename_unicode, const char * filename, const char * directory); word * Get_Unicode_Filename(word * filename_unicode, const char * filename, const char * directory);
/// ///
/// Appends a file or directory name to an existing directory name. /// Appends a file or directory name to an existing directory name.

View File

@ -69,6 +69,7 @@
#ifndef _MSC_VER #ifndef _MSC_VER
#include <unistd.h> #include <unistd.h>
#else #else
#define strdup _strdup
#if _MSC_VER < 1900 #if _MSC_VER < 1900
#define snprintf _snprintf #define snprintf _snprintf
#endif #endif