Fix Windows Unicode file path handling issues (+add winpr_fopen wrapper)

This commit is contained in:
Marc-André Moreau 2021-05-25 13:27:13 -04:00 коммит произвёл akallabeth
Родитель 29760a9009
Коммит eb6777ea69
11 изменённых файлов: 161 добавлений и 13 удалений

Просмотреть файл

@ -521,6 +521,8 @@ extern "C"
WINPR_API int GetNamePipeFileDescriptor(HANDLE hNamedPipe);
WINPR_API HANDLE GetFileHandleForFileDescriptor(int fd);
WINPR_API FILE* winpr_fopen(const char* path, const char* mode);
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -335,6 +335,12 @@ extern "C"
#endif
WINPR_API BOOL winpr_MoveFile(LPCSTR lpExistingFileName, LPCSTR lpNewFileName);
WINPR_API BOOL winpr_DeleteFile(const char* lpFileName);
WINPR_API BOOL winpr_RemoveDirectory(LPCSTR lpPathName);
WINPR_API BOOL winpr_PathFileExists(const char* pszPath);
WINPR_API BOOL winpr_PathMakePath(const char* path, LPSECURITY_ATTRIBUTES lpAttributes);
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -1358,3 +1358,30 @@ HANDLE GetFileHandleForFileDescriptor(int fd)
return (HANDLE)pFile;
#endif /* _WIN32 */
}
FILE* winpr_fopen(const char* path, const char* mode)
{
#ifndef _WIN32
return fopen(path, mode);
#else
LPWSTR lpPathW = NULL;
LPWSTR lpModeW = NULL;
FILE* result = NULL;
if (!path || !mode)
return NULL;
if (ConvertToUnicode(CP_UTF8, 0, path, -1, &lpPathW, 0) < 1)
goto cleanup;
if (ConvertToUnicode(CP_UTF8, 0, mode, -1, &lpModeW, 0) < 1)
goto cleanup;
result = _wfopen(lpPathW, lpModeW);
cleanup:
free(lpPathW);
free(lpModeW);
return result;
#endif
}

Просмотреть файл

@ -668,3 +668,110 @@ BOOL PathIsDirectoryEmptyW(LPCWSTR pszPath)
#endif
#endif
BOOL winpr_MoveFile(LPCSTR lpExistingFileName, LPCSTR lpNewFileName)
{
#ifndef _WIN32
return MoveFileA(lpExistingFileName, lpNewFileName);
#else
BOOL result = FALSE;
LPWSTR lpExistingFileNameW = NULL;
LPWSTR lpNewFileNameW = NULL;
if (!lpExistingFileName || !lpNewFileName)
return FALSE;
if (ConvertToUnicode(CP_UTF8, 0, lpExistingFileName, -1, &lpExistingFileNameW, 0) < 1)
goto cleanup;
if (ConvertToUnicode(CP_UTF8, 0, lpNewFileName, -1, &lpNewFileNameW, 0) < 1)
goto cleanup;
result = MoveFileW(lpExistingFileNameW, lpNewFileNameW);
cleanup:
free(lpExistingFileNameW);
free(lpNewFileNameW);
return result;
#endif
}
BOOL winpr_DeleteFile(const char* lpFileName)
{
#ifndef _WIN32
return DeleteFileA(lpFileName);
#else
LPWSTR lpFileNameW = NULL;
BOOL result = FALSE;
if (lpFileName)
{
if (ConvertToUnicode(CP_UTF8, 0, lpFileName, -1, &lpFileNameW, 0) < 1)
goto cleanup;
}
result = DeleteFileW(lpFileNameW);
cleanup:
free(lpFileNameW);
return result;
#endif
}
BOOL winpr_RemoveDirectory(LPCSTR lpPathName)
{
#ifndef _WIN32
return RemoveDirectoryA(lpPathName);
#else
LPWSTR lpPathNameW = NULL;
BOOL result = FALSE;
if (lpPathName)
{
if (ConvertToUnicode(CP_UTF8, 0, lpPathName, -1, &lpPathNameW, 0) < 1)
goto cleanup;
}
result = RemoveDirectoryW(lpPathNameW);
cleanup:
free(lpPathNameW);
return result;
#endif
}
BOOL winpr_PathFileExists(const char* pszPath)
{
#ifndef _WIN32
return PathFileExistsA(pszPath);
#else
WCHAR* pszPathW = NULL;
BOOL result = FALSE;
if (ConvertToUnicode(CP_UTF8, 0, pszPath, -1, &pszPathW, 0) < 1)
return FALSE;
result = PathFileExistsW(pszPathW);
free(pszPathW);
return result;
#endif
}
BOOL winpr_PathMakePath(const char* path, LPSECURITY_ATTRIBUTES lpAttributes)
{
#ifndef _WIN32
return PathMakePathA(path, lpAttributes);
#else
WCHAR* pathW = NULL;
BOOL result = FALSE;
if (ConvertToUnicode(CP_UTF8, 0, path, -1, &pathW, 0) < 1)
return FALSE;
result = SHCreateDirectoryExW(NULL, pathW, lpAttributes) == ERROR_SUCCESS;
free(pathW);
return result;
#endif
}

Просмотреть файл

@ -25,6 +25,7 @@
#include <winpr/wtypes.h>
#include <winpr/crt.h>
#include <winpr/file.h>
#include <winpr/image.h>
@ -414,7 +415,8 @@ int winpr_image_read(wImage* image, const char* filename)
FILE* fp;
BYTE sig[8];
int status = -1;
fp = fopen(filename, "rb");
fp = winpr_fopen(filename, "rb");
if (!fp)
{

Просмотреть файл

@ -28,6 +28,7 @@
#include <errno.h>
#include <winpr/wtypes.h>
#include <winpr/crt.h>
#include <winpr/file.h>
#include <winpr/ini.h>
@ -117,9 +118,9 @@ static BOOL IniFile_Open_File(wIniFile* ini, const char* filename)
return FALSE;
if (ini->readOnly)
ini->fp = fopen(filename, "rb");
ini->fp = winpr_fopen(filename, "rb");
else
ini->fp = fopen(filename, "w+b");
ini->fp = winpr_fopen(filename, "w+b");
if (!ini->fp)
return FALSE;

Просмотреть файл

@ -70,14 +70,14 @@ static BOOL WLog_BinaryAppender_Open(wLog* log, wLogAppender* appender)
return FALSE;
}
if (!PathFileExistsA(binaryAppender->FilePath))
if (!winpr_PathFileExists(binaryAppender->FilePath))
{
if (!PathMakePathA(binaryAppender->FilePath, 0))
if (!winpr_PathMakePath(binaryAppender->FilePath, 0))
return FALSE;
UnixChangeFileMode(binaryAppender->FilePath, 0xFFFF);
}
binaryAppender->FileDescriptor = fopen(binaryAppender->FullFileName, "a+");
binaryAppender->FileDescriptor = winpr_fopen(binaryAppender->FullFileName, "a+");
if (!binaryAppender->FileDescriptor)
return FALSE;

Просмотреть файл

@ -25,6 +25,8 @@
#include "wlog/DataMessage.h"
#include <winpr/file.h>
#include "../../log.h"
#define TAG WINPR_TAG("utils.wlog")
@ -33,7 +35,7 @@ BOOL WLog_DataMessage_Write(char* filename, void* data, int length)
FILE* fp;
BOOL ret = TRUE;
fp = fopen(filename, "w+b");
fp = winpr_fopen(filename, "w+b");
if (!fp)
{

Просмотреть файл

@ -96,15 +96,15 @@ static BOOL WLog_FileAppender_Open(wLog* log, wLogAppender* appender)
return FALSE;
}
if (!PathFileExistsA(fileAppender->FilePath))
if (!winpr_PathFileExists(fileAppender->FilePath))
{
if (!PathMakePathA(fileAppender->FilePath, 0))
if (!winpr_PathMakePath(fileAppender->FilePath, 0))
return FALSE;
UnixChangeFileMode(fileAppender->FilePath, 0xFFFF);
}
fileAppender->FileDescriptor = fopen(fileAppender->FullFileName, "a+");
fileAppender->FileDescriptor = winpr_fopen(fileAppender->FullFileName, "a+");
if (!fileAppender->FileDescriptor)
return FALSE;

Просмотреть файл

@ -41,9 +41,9 @@ char* WLog_Message_GetOutputFileName(int id, const char* ext)
FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog");
if (!PathFileExistsA(FilePath))
if (!winpr_PathFileExists(FilePath))
{
if (!PathMakePathA(FilePath, NULL))
if (!winpr_PathMakePath(FilePath, NULL))
{
free(FileName);
free(FilePath);

Просмотреть файл

@ -29,6 +29,7 @@
#include <winpr/wtypes.h>
#include <winpr/crt.h>
#include <winpr/file.h>
#include <winpr/stream.h>
#include "../../log.h"
@ -187,7 +188,7 @@ static BOOL Pcap_Write_Record(wPcap* pcap, wPcapRecord* record)
wPcap* Pcap_Open(char* name, BOOL write)
{
wPcap* pcap = NULL;
FILE* pcap_fp = fopen(name, write ? "w+b" : "rb");
FILE* pcap_fp = winpr_fopen(name, write ? "w+b" : "rb");
if (!pcap_fp)
{