From 07e39ede20bb10185351a980fda7019645ddd038 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 4 Jun 2025 15:56:01 +0200 Subject: [PATCH] [winpr,file] Add winpr_CreateFile wrapper Allows creation of a file HANDLE from a utf-8 name --- channels/printer/client/printer_main.c | 5 +- channels/serial/client/serial_main.c | 8 +- libfreerdp/core/test/TestStreamDump.c | 2 +- winpr/include/winpr/file.h | 29 +++++-- winpr/libwinpr/file/generic.c | 83 ++++++++----------- winpr/libwinpr/file/test/TestFileDeleteFile.c | 5 +- .../file/test/TestFileFindFirstFile.c | 2 +- .../file/test/TestSetFileAttributes.c | 2 +- winpr/libwinpr/path/shell.c | 70 ++++++++++------ 9 files changed, 110 insertions(+), 96 deletions(-) diff --git a/channels/printer/client/printer_main.c b/channels/printer/client/printer_main.c index a98ea2655..3449e7818 100644 --- a/channels/printer/client/printer_main.c +++ b/channels/printer/client/printer_main.c @@ -113,7 +113,8 @@ static BOOL printer_write_setting(const char* path, prn_conf_t type, const void* return FALSE; } - file = CreateFileA(abs, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + file = + winpr_CreateFile(abs, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); free(abs); if (file == INVALID_HANDLE_VALUE) @@ -177,7 +178,7 @@ static BOOL printer_read_setting(const char* path, prn_conf_t type, void** data, return FALSE; HANDLE file = - CreateFileA(abs, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + winpr_CreateFile(abs, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); free(abs); if (file == INVALID_HANDLE_VALUE) diff --git a/channels/serial/client/serial_main.c b/channels/serial/client/serial_main.c index da82ae025..b3012c620 100644 --- a/channels/serial/client/serial_main.c +++ b/channels/serial/client/serial_main.c @@ -165,10 +165,10 @@ static UINT serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp) SharedAccess = 0; CreateDisposition = OPEN_EXISTING; #endif - serial->hComm = - CreateFile(serial->device.name, DesiredAccess, SharedAccess, NULL, /* SecurityAttributes */ - CreateDisposition, 0, /* FlagsAndAttributes */ - NULL); /* TemplateFile */ + serial->hComm = winpr_CreateFile(serial->device.name, DesiredAccess, SharedAccess, + NULL, /* SecurityAttributes */ + CreateDisposition, 0, /* FlagsAndAttributes */ + NULL); /* TemplateFile */ if (!serial->hComm || (serial->hComm == INVALID_HANDLE_VALUE)) { diff --git a/libfreerdp/core/test/TestStreamDump.c b/libfreerdp/core/test/TestStreamDump.c index b54cae9e3..047cca2a1 100644 --- a/libfreerdp/core/test/TestStreamDump.c +++ b/libfreerdp/core/test/TestStreamDump.c @@ -87,7 +87,7 @@ fail: if (fp) (void)fclose(fp); if (name) - DeleteFileA(name); + winpr_DeleteFile(name); free(name); (void)fprintf(stderr, "xxxxxxxxxxxxx %d\n", rc); return rc; diff --git a/winpr/include/winpr/file.h b/winpr/include/winpr/file.h index ec6dd4b5c..53100e447 100644 --- a/winpr/include/winpr/file.h +++ b/winpr/include/winpr/file.h @@ -264,10 +264,17 @@ extern "C" #endif WINPR_ATTR_MALLOC(CloseHandle, 1) - WINPR_API HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, - DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, - HANDLE hTemplateFile); + WINPR_API HANDLE winpr_CreateFile(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile); + + WINPR_DEPRECATED_VAR("since 3.16.0, Use winpr_CreateFile", + WINPR_ATTR_MALLOC(CloseHandle, 1) WINPR_API HANDLE CreateFileA( + LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile)); WINPR_ATTR_MALLOC(CloseHandle, 1) WINPR_API HANDLE CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, @@ -275,7 +282,8 @@ extern "C" DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); - WINPR_API BOOL DeleteFileA(LPCSTR lpFileName); + WINPR_DEPRECATED_VAR("since 3.16.0, Use winpr_DeleteFile", + WINPR_API BOOL DeleteFileA(LPCSTR lpFileName)); WINPR_API BOOL DeleteFileW(LPCWSTR lpFileName); @@ -386,7 +394,9 @@ extern "C" WINPR_API BOOL CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes); WINPR_API BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes); - WINPR_API BOOL RemoveDirectoryA(LPCSTR lpPathName); + WINPR_DEPRECATED_VAR("since 3.16.0, Use winpr_RemoveDirectory", + WINPR_API BOOL RemoveDirectoryA(LPCSTR lpPathName)); + WINPR_API BOOL RemoveDirectoryW(LPCWSTR lpPathName); WINPR_API HANDLE GetStdHandle(DWORD nStdHandle); @@ -401,11 +411,14 @@ extern "C" LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters); - WINPR_API BOOL MoveFileExA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags); + WINPR_DEPRECATED_VAR("since 3.16.0, Use winpr_MoveFileEx", + WINPR_API BOOL MoveFileExA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, + DWORD dwFlags)); WINPR_API BOOL MoveFileExW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlags); - WINPR_API BOOL MoveFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName); + WINPR_DEPRECATED_VAR("since 3.16.0, Use winpr_MoveFile", + WINPR_API BOOL MoveFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName)); WINPR_API BOOL MoveFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName); diff --git a/winpr/libwinpr/file/generic.c b/winpr/libwinpr/file/generic.c index 7c730b84f..03f360810 100644 --- a/winpr/libwinpr/file/generic.c +++ b/winpr/libwinpr/file/generic.c @@ -230,6 +230,14 @@ int InstallAioSignalHandler() HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) +{ + return winpr_CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, + dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); +} + +HANDLE winpr_CreateFile(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { if (!lpFileName) return INVALID_HANDLE_VALUE; @@ -281,8 +289,8 @@ HANDLE CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, goto fail; } - hdl = CreateFileA(lpFileNameA, dwDesiredAccess, dwShareMode, lpSecurityAttributes, - dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); + hdl = winpr_CreateFile(lpFileNameA, dwDesiredAccess, dwShareMode, lpSecurityAttributes, + dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); fail: free(lpFileNameA); return hdl; @@ -290,9 +298,7 @@ fail: BOOL DeleteFileA(LPCSTR lpFileName) { - int status = 0; - status = unlink(lpFileName); - return (status != -1) ? TRUE : FALSE; + return winpr_DeleteFile(lpFileName); } BOOL DeleteFileW(LPCWSTR lpFileName) @@ -300,13 +306,7 @@ BOOL DeleteFileW(LPCWSTR lpFileName) if (!lpFileName) return FALSE; LPSTR lpFileNameA = ConvertWCharToUtf8Alloc(lpFileName, NULL); - BOOL rc = FALSE; - - if (!lpFileNameA) - goto fail; - - rc = DeleteFileA(lpFileNameA); -fail: + BOOL rc = winpr_DeleteFile(lpFileNameA); free(lpFileNameA); return rc; } @@ -1254,14 +1254,7 @@ fail: BOOL RemoveDirectoryA(LPCSTR lpPathName) { - int ret = rmdir(lpPathName); - - if (ret != 0) - SetLastError(map_posix_err(errno)); - else - SetLastError(STATUS_SUCCESS); - - return ret == 0; + return winpr_RemoveDirectory(lpPathName); } BOOL RemoveDirectoryW(LPCWSTR lpPathName) @@ -1277,7 +1270,7 @@ BOOL RemoveDirectoryW(LPCWSTR lpPathName) goto fail; } - ret = RemoveDirectoryA(utfPathName); + ret = winpr_RemoveDirectory(utfPathName); fail: free(utfPathName); return ret; @@ -1285,33 +1278,7 @@ fail: BOOL MoveFileExA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags) { - struct stat st; - int ret = 0; - ret = stat(lpNewFileName, &st); - - if ((dwFlags & MOVEFILE_REPLACE_EXISTING) == 0) - { - if (ret == 0) - { - SetLastError(ERROR_ALREADY_EXISTS); - return FALSE; - } - } - else - { - if (ret == 0 && (st.st_mode & S_IWUSR) == 0) - { - SetLastError(ERROR_ACCESS_DENIED); - return FALSE; - } - } - - ret = rename(lpExistingFileName, lpNewFileName); - - if (ret != 0) - SetLastError(map_posix_err(errno)); - - return ret == 0; + return winpr_MoveFileEx(lpExistingFileName, lpNewFileName, dwFlags); } BOOL MoveFileExW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlags) @@ -1329,7 +1296,7 @@ BOOL MoveFileExW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlag goto fail; } - ret = MoveFileExA(lpCExistingFileName, lpCNewFileName, dwFlags); + ret = winpr_MoveFileEx(lpCExistingFileName, lpCNewFileName, dwFlags); fail: free(lpCNewFileName); free(lpCExistingFileName); @@ -1338,7 +1305,7 @@ fail: BOOL MoveFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName) { - return MoveFileExA(lpExistingFileName, lpNewFileName, 0); + return winpr_MoveFileEx(lpExistingFileName, lpNewFileName, 0); } BOOL MoveFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName) @@ -1385,3 +1352,19 @@ int UnixChangeFileMode(const char* filename, int flags) return rc; #endif } + +#if defined(_WIN32) || defined(_UWP) +HANDLE winpr_CreateFile(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) +{ + char* filename = ConvertUtf8ToWCharAlloc(lpFileName, NULL); + if (!filename) + return NULL; + + HANDLE hdl = CreateFileW(filename, dwDesiredAccess, dwShareMode, lpSecurityAttributes, + dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); + free(filename); + return hdl; +} +#endif diff --git a/winpr/libwinpr/file/test/TestFileDeleteFile.c b/winpr/libwinpr/file/test/TestFileDeleteFile.c index 40649dba5..7448ae3df 100644 --- a/winpr/libwinpr/file/test/TestFileDeleteFile.c +++ b/winpr/libwinpr/file/test/TestFileDeleteFile.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #if !defined(_WIN32) @@ -36,7 +37,7 @@ int TestFileDeleteFile(int argc, char* argv[]) WINPR_UNUSED(argc); WINPR_UNUSED(argv); - rc = DeleteFileA(invalidA); + rc = winpr_DeleteFile(invalidA); if (rc) return -1; @@ -48,7 +49,7 @@ int TestFileDeleteFile(int argc, char* argv[]) if (fd < 0) return -1; - rc = DeleteFileA(validA); + rc = winpr_DeleteFile(validA); if (!rc) return -1; diff --git a/winpr/libwinpr/file/test/TestFileFindFirstFile.c b/winpr/libwinpr/file/test/TestFileFindFirstFile.c index 2be310853..049b6ba4b 100644 --- a/winpr/libwinpr/file/test/TestFileFindFirstFile.c +++ b/winpr/libwinpr/file/test/TestFileFindFirstFile.c @@ -248,7 +248,7 @@ static int TestFileFindFirstFileA(const char* str) rc = 0; fail: - DeleteFileA(FilePath); + winpr_DeleteFile(FilePath); cleanup_layout(BasePath); ArrayList_Free(files); return rc; diff --git a/winpr/libwinpr/file/test/TestSetFileAttributes.c b/winpr/libwinpr/file/test/TestSetFileAttributes.c index b00c2ce1a..84a5b12f5 100644 --- a/winpr/libwinpr/file/test/TestSetFileAttributes.c +++ b/winpr/libwinpr/file/test/TestSetFileAttributes.c @@ -78,7 +78,7 @@ static BOOL test_SetFileAttributesA(void) rc = TRUE; fail: - DeleteFileA(name); + winpr_DeleteFile(name); free(name); return rc; } diff --git a/winpr/libwinpr/path/shell.c b/winpr/libwinpr/path/shell.c index db8aeccc4..5ea37c0fd 100644 --- a/winpr/libwinpr/path/shell.c +++ b/winpr/libwinpr/path/shell.c @@ -35,6 +35,8 @@ #include #include +#include "../file/file.h" + #include "../log.h" #define TAG WINPR_TAG("path.shell") @@ -697,36 +699,39 @@ fail: 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; - - lpExistingFileNameW = ConvertUtf8ToWCharAlloc(lpExistingFileName, NULL); - if (!lpExistingFileNameW) - goto cleanup; - lpNewFileNameW = ConvertUtf8ToWCharAlloc(lpNewFileName, NULL); - if (!lpNewFileNameW) - goto cleanup; - - result = MoveFileW(lpExistingFileNameW, lpNewFileNameW); - -cleanup: - free(lpExistingFileNameW); - free(lpNewFileNameW); - return result; -#endif + return winpr_MoveFileEx(lpExistingFileName, lpNewFileName, 0); } BOOL winpr_MoveFileEx(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags) { #ifndef _WIN32 - return MoveFileExA(lpExistingFileName, lpNewFileName, dwFlags); + struct stat st; + int ret = 0; + ret = stat(lpNewFileName, &st); + + if ((dwFlags & MOVEFILE_REPLACE_EXISTING) == 0) + { + if (ret == 0) + { + SetLastError(ERROR_ALREADY_EXISTS); + return FALSE; + } + } + else + { + if (ret == 0 && (st.st_mode & S_IWUSR) == 0) + { + SetLastError(ERROR_ACCESS_DENIED); + return FALSE; + } + } + + ret = rename(lpExistingFileName, lpNewFileName); + + if (ret != 0) + SetLastError(map_posix_err(errno)); + + return ret == 0; #else BOOL result = FALSE; LPWSTR lpExistingFileNameW = NULL; @@ -754,7 +759,11 @@ cleanup: BOOL winpr_DeleteFile(const char* lpFileName) { #ifndef _WIN32 - return DeleteFileA(lpFileName); + if (!lpFileName) + return FALSE; + + const int status = unlink(lpFileName); + return (status != -1) ? TRUE : FALSE; #else LPWSTR lpFileNameW = NULL; BOOL result = FALSE; @@ -776,7 +785,14 @@ cleanup: BOOL winpr_RemoveDirectory(LPCSTR lpPathName) { #ifndef _WIN32 - return RemoveDirectoryA(lpPathName); + int ret = rmdir(lpPathName); + + if (ret != 0) + SetLastError(map_posix_err(errno)); + else + SetLastError(STATUS_SUCCESS); + + return ret == 0; #else LPWSTR lpPathNameW = NULL; BOOL result = FALSE;