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 committed by akallabeth
parent 29760a9009
commit eb6777ea69
11 changed files with 161 additions and 13 deletions

View File

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

View File

@ -335,6 +335,12 @@ extern "C"
#endif #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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -1358,3 +1358,30 @@ HANDLE GetFileHandleForFileDescriptor(int fd)
return (HANDLE)pFile; return (HANDLE)pFile;
#endif /* _WIN32 */ #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
}

View File

@ -668,3 +668,110 @@ BOOL PathIsDirectoryEmptyW(LPCWSTR pszPath)
#endif #endif
#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
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -41,9 +41,9 @@ char* WLog_Message_GetOutputFileName(int id, const char* ext)
FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog"); 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(FileName);
free(FilePath); free(FilePath);

View File

@ -29,6 +29,7 @@
#include <winpr/wtypes.h> #include <winpr/wtypes.h>
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/file.h>
#include <winpr/stream.h> #include <winpr/stream.h>
#include "../../log.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_Open(char* name, BOOL write)
{ {
wPcap* pcap = NULL; 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) if (!pcap_fp)
{ {