mirror of https://github.com/FreeRDP/FreeRDP
[winpr,file] fix issues with FindFirstFile
This commit is contained in:
parent
c4f93891fd
commit
14d5cbeacb
|
@ -80,6 +80,7 @@ extern "C"
|
||||||
WINPR_API char* strtok_s(char* strToken, const char* strDelimit, char** context);
|
WINPR_API char* strtok_s(char* strToken, const char* strDelimit, char** context);
|
||||||
WINPR_API WCHAR* wcstok_s(WCHAR* strToken, const WCHAR* strDelimit, WCHAR** context);
|
WINPR_API WCHAR* wcstok_s(WCHAR* strToken, const WCHAR* strDelimit, WCHAR** context);
|
||||||
|
|
||||||
|
WINPR_API WCHAR* _wcsncat(WCHAR* dst, const WCHAR* src, size_t sz);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define _wcscmp wcscmp
|
#define _wcscmp wcscmp
|
||||||
|
@ -89,6 +90,7 @@ extern "C"
|
||||||
#define _wcsstr wcsstr
|
#define _wcsstr wcsstr
|
||||||
#define _wcschr wcschr
|
#define _wcschr wcschr
|
||||||
#define _wcsrchr wcsrchr
|
#define _wcsrchr wcsrchr
|
||||||
|
#define _wcsncat wcsncat
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
|
|
@ -388,7 +388,6 @@ static BOOL add_file_to_list(wClipboard* clipboard, const WCHAR* local_name,
|
||||||
WINPR_ASSERT(remote_name);
|
WINPR_ASSERT(remote_name);
|
||||||
WINPR_ASSERT(files);
|
WINPR_ASSERT(files);
|
||||||
|
|
||||||
WLog_VRB(TAG, "adding file: %s", local_name);
|
|
||||||
file = make_synthetic_file(local_name, remote_name);
|
file = make_synthetic_file(local_name, remote_name);
|
||||||
|
|
||||||
if (!file)
|
if (!file)
|
||||||
|
|
|
@ -203,6 +203,19 @@ WCHAR* _wcsdup(const WCHAR* strSource)
|
||||||
return strDestination;
|
return strDestination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WCHAR* _wcsncat(WCHAR* dst, const WCHAR* src, size_t sz)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(dst);
|
||||||
|
WINPR_ASSERT(src || (sz == 0));
|
||||||
|
|
||||||
|
const size_t dlen = _wcslen(dst);
|
||||||
|
const size_t slen = _wcsnlen(src, sz);
|
||||||
|
for (size_t x = 0; x < slen; x++)
|
||||||
|
dst[dlen + x] = src[x];
|
||||||
|
dst[dlen + slen] = '\0';
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
int _stricmp(const char* string1, const char* string2)
|
int _stricmp(const char* string1, const char* string2)
|
||||||
{
|
{
|
||||||
return strcasecmp(string1, string2);
|
return strcasecmp(string1, string2);
|
||||||
|
|
|
@ -873,12 +873,47 @@ BOOL WINAPI SetFileTime(HANDLE hFile, const FILETIME* lpCreationTime,
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
DIR* pDir;
|
char magic[16];
|
||||||
LPSTR lpPath;
|
LPSTR lpPath;
|
||||||
LPSTR lpPattern;
|
LPSTR lpPattern;
|
||||||
struct dirent* pDirent;
|
DIR* pDir;
|
||||||
} WIN32_FILE_SEARCH;
|
} WIN32_FILE_SEARCH;
|
||||||
|
|
||||||
|
static const char file_search_magic[] = "file_srch_magic";
|
||||||
|
|
||||||
|
static WIN32_FILE_SEARCH* file_search_new(const char* name, size_t namelen, const char* pattern,
|
||||||
|
size_t patternlen)
|
||||||
|
{
|
||||||
|
WIN32_FILE_SEARCH* pFileSearch = (WIN32_FILE_SEARCH*)calloc(1, sizeof(WIN32_FILE_SEARCH));
|
||||||
|
if (!pFileSearch)
|
||||||
|
return NULL;
|
||||||
|
strncpy(pFileSearch->magic, file_search_magic, sizeof(pFileSearch->magic));
|
||||||
|
|
||||||
|
pFileSearch->lpPath = strndup(name, namelen);
|
||||||
|
pFileSearch->lpPattern = strndup(pattern, patternlen);
|
||||||
|
if (!pFileSearch->lpPath || !pFileSearch->lpPattern)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
pFileSearch->pDir = opendir(pFileSearch->lpPath);
|
||||||
|
if (!pFileSearch->pDir)
|
||||||
|
goto fail;
|
||||||
|
return pFileSearch;
|
||||||
|
fail:
|
||||||
|
FindClose(pFileSearch);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL is_valid_file_search_handle(HANDLE handle)
|
||||||
|
{
|
||||||
|
WIN32_FILE_SEARCH* pFileSearch = (WIN32_FILE_SEARCH*)handle;
|
||||||
|
if (!pFileSearch)
|
||||||
|
return FALSE;
|
||||||
|
if (pFileSearch == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
if (strcmp(file_search_magic, pFileSearch->magic) != 0)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
static BOOL FindDataFromStat(const char* path, const struct stat* fileStat,
|
static BOOL FindDataFromStat(const char* path, const struct stat* fileStat,
|
||||||
LPWIN32_FIND_DATAA lpFindFileData)
|
LPWIN32_FIND_DATAA lpFindFileData)
|
||||||
{
|
{
|
||||||
|
@ -926,18 +961,27 @@ static BOOL FindDataFromStat(const char* path, const struct stat* fileStat,
|
||||||
|
|
||||||
HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
|
HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
|
||||||
{
|
{
|
||||||
BOOL isDir = FALSE;
|
|
||||||
struct stat fileStat;
|
|
||||||
WIN32_FILE_SEARCH* pFileSearch;
|
|
||||||
|
|
||||||
if (!lpFindFileData || !lpFileName)
|
if (!lpFindFileData || !lpFileName)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_BAD_ARGUMENTS);
|
SetLastError(ERROR_BAD_ARGUMENTS);
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZeroMemory(lpFindFileData, sizeof(WIN32_FIND_DATAA));
|
const WIN32_FIND_DATAA empty = { 0 };
|
||||||
pFileSearch = (WIN32_FILE_SEARCH*)calloc(1, sizeof(WIN32_FILE_SEARCH));
|
*lpFindFileData = empty;
|
||||||
|
|
||||||
|
WIN32_FILE_SEARCH* pFileSearch = NULL;
|
||||||
|
size_t patternlen = 0;
|
||||||
|
const size_t flen = strlen(lpFileName);
|
||||||
|
const char sep = PathGetSeparatorA(PATH_STYLE_NATIVE);
|
||||||
|
const char* ptr = strrchr(lpFileName, sep);
|
||||||
|
if (!ptr)
|
||||||
|
goto fail;
|
||||||
|
patternlen = strlen(ptr + 1);
|
||||||
|
if (patternlen == 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
pFileSearch = file_search_new(lpFileName, flen - patternlen, ptr + 1, patternlen);
|
||||||
|
|
||||||
if (!pFileSearch)
|
if (!pFileSearch)
|
||||||
{
|
{
|
||||||
|
@ -945,101 +989,10 @@ HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat(lpFileName, &fileStat) >= 0)
|
|
||||||
{
|
|
||||||
isDir = (S_ISDIR(fileStat.st_mode) != 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
if (isDir)
|
|
||||||
{
|
|
||||||
pFileSearch->lpPath = _strdup(lpFileName);
|
|
||||||
pFileSearch->lpPattern = _strdup("*");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LPSTR p;
|
|
||||||
size_t index;
|
|
||||||
size_t length;
|
|
||||||
/* Separate lpFileName into path and pattern components */
|
|
||||||
p = strrchr(lpFileName, '/');
|
|
||||||
|
|
||||||
if (!p)
|
|
||||||
p = strrchr(lpFileName, '\\');
|
|
||||||
|
|
||||||
index = (p - lpFileName);
|
|
||||||
length = (p - lpFileName) + 1;
|
|
||||||
pFileSearch->lpPath = (LPSTR)malloc(length + 1);
|
|
||||||
|
|
||||||
if (!pFileSearch->lpPath)
|
|
||||||
{
|
|
||||||
free(pFileSearch);
|
|
||||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CopyMemory(pFileSearch->lpPath, lpFileName, length);
|
|
||||||
pFileSearch->lpPath[length] = '\0';
|
|
||||||
length = strlen(lpFileName) - index;
|
|
||||||
pFileSearch->lpPattern = (LPSTR)malloc(length + 1);
|
|
||||||
|
|
||||||
if (!pFileSearch->lpPattern)
|
|
||||||
{
|
|
||||||
free(pFileSearch->lpPath);
|
|
||||||
free(pFileSearch);
|
|
||||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CopyMemory(pFileSearch->lpPattern, &lpFileName[index + 1], length);
|
|
||||||
pFileSearch->lpPattern[length] = '\0';
|
|
||||||
|
|
||||||
/* Check if the path is a directory */
|
|
||||||
|
|
||||||
if (stat(pFileSearch->lpPath, &fileStat) < 0)
|
|
||||||
{
|
|
||||||
FindClose(pFileSearch);
|
|
||||||
SetLastError(map_posix_err(errno));
|
|
||||||
errno = 0;
|
|
||||||
return INVALID_HANDLE_VALUE; /* stat error */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISDIR(fileStat.st_mode) == 0)
|
|
||||||
{
|
|
||||||
FindClose(pFileSearch);
|
|
||||||
return INVALID_HANDLE_VALUE; /* not a directory */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Open directory for reading */
|
|
||||||
pFileSearch->pDir = opendir(pFileSearch->lpPath);
|
|
||||||
|
|
||||||
if (!pFileSearch->pDir)
|
|
||||||
{
|
|
||||||
FindClose(pFileSearch);
|
|
||||||
SetLastError(map_posix_err(errno));
|
|
||||||
errno = 0;
|
|
||||||
return INVALID_HANDLE_VALUE; /* failed to open directory */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FindNextFileA((HANDLE)pFileSearch, lpFindFileData))
|
if (FindNextFileA((HANDLE)pFileSearch, lpFindFileData))
|
||||||
{
|
|
||||||
if (isDir)
|
|
||||||
{
|
|
||||||
const char* name = strrchr(lpFileName, '/');
|
|
||||||
|
|
||||||
if (!name)
|
|
||||||
name = lpFileName;
|
|
||||||
else
|
|
||||||
name++;
|
|
||||||
|
|
||||||
sprintf_s(lpFindFileData->cFileName, ARRAYSIZE(lpFindFileData->cFileName), "%s", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (HANDLE)pFileSearch;
|
return (HANDLE)pFileSearch;
|
||||||
}
|
|
||||||
|
|
||||||
|
fail:
|
||||||
FindClose(pFileSearch);
|
FindClose(pFileSearch);
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
@ -1124,23 +1077,24 @@ HANDLE FindFirstFileExW(LPCWSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, LPV
|
||||||
|
|
||||||
BOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
|
BOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
|
||||||
{
|
{
|
||||||
if (!hFindFile || !lpFindFileData)
|
if (!lpFindFileData)
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (hFindFile == INVALID_HANDLE_VALUE)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
const WIN32_FIND_DATAA empty = { 0 };
|
const WIN32_FIND_DATAA empty = { 0 };
|
||||||
*lpFindFileData = empty;
|
*lpFindFileData = empty;
|
||||||
|
|
||||||
|
if (!is_valid_file_search_handle(hFindFile))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
WIN32_FILE_SEARCH* pFileSearch = (WIN32_FILE_SEARCH*)hFindFile;
|
WIN32_FILE_SEARCH* pFileSearch = (WIN32_FILE_SEARCH*)hFindFile;
|
||||||
while ((pFileSearch->pDirent = readdir(pFileSearch->pDir)) != NULL)
|
struct dirent* pDirent = NULL;
|
||||||
|
while ((pDirent = readdir(pFileSearch->pDir)) != NULL)
|
||||||
{
|
{
|
||||||
if (FilePatternMatchA(pFileSearch->pDirent->d_name, pFileSearch->lpPattern))
|
if (FilePatternMatchA(pDirent->d_name, pFileSearch->lpPattern))
|
||||||
{
|
{
|
||||||
BOOL success = FALSE;
|
BOOL success = FALSE;
|
||||||
|
|
||||||
strncpy(lpFindFileData->cFileName, pFileSearch->pDirent->d_name, MAX_PATH);
|
strncpy(lpFindFileData->cFileName, pDirent->d_name, MAX_PATH);
|
||||||
const size_t namelen = strnlen(lpFindFileData->cFileName, MAX_PATH);
|
const size_t namelen = strnlen(lpFindFileData->cFileName, MAX_PATH);
|
||||||
size_t pathlen = strlen(pFileSearch->lpPath);
|
size_t pathlen = strlen(pFileSearch->lpPath);
|
||||||
char* fullpath = (char*)malloc(pathlen + namelen + 2);
|
char* fullpath = (char*)malloc(pathlen + namelen + 2);
|
||||||
|
@ -1156,7 +1110,7 @@ BOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
|
||||||
* duplicate separators */
|
* duplicate separators */
|
||||||
if (fullpath[pathlen - 1] != '/')
|
if (fullpath[pathlen - 1] != '/')
|
||||||
fullpath[pathlen++] = '/';
|
fullpath[pathlen++] = '/';
|
||||||
memcpy(fullpath + pathlen, pFileSearch->pDirent->d_name, namelen);
|
memcpy(fullpath + pathlen, pDirent->d_name, namelen);
|
||||||
fullpath[pathlen + namelen] = 0;
|
fullpath[pathlen + namelen] = 0;
|
||||||
|
|
||||||
struct stat fileStat = { 0 };
|
struct stat fileStat = { 0 };
|
||||||
|
@ -1220,7 +1174,7 @@ BOOL FindClose(HANDLE hFindFile)
|
||||||
* is a initialized HANDLE that is not freed properly.
|
* is a initialized HANDLE that is not freed properly.
|
||||||
* Disable this return to stop confusing the analyzer. */
|
* Disable this return to stop confusing the analyzer. */
|
||||||
#ifndef __clang_analyzer__
|
#ifndef __clang_analyzer__
|
||||||
if (!pFileSearch || (pFileSearch == INVALID_HANDLE_VALUE))
|
if (!is_valid_file_search_handle(hFindFile))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,66 +1,325 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
|
#include <winpr/handle.h>
|
||||||
#include <winpr/file.h>
|
#include <winpr/file.h>
|
||||||
#include <winpr/path.h>
|
#include <winpr/path.h>
|
||||||
#include <winpr/tchar.h>
|
#include <winpr/tchar.h>
|
||||||
|
#include <winpr/collections.h>
|
||||||
#include <winpr/windows.h>
|
#include <winpr/windows.h>
|
||||||
|
|
||||||
static TCHAR testFile1[] = _T("TestFile1");
|
static const CHAR testFile1A[] = "TestFile1A";
|
||||||
|
static const WCHAR testFile1W[] = { 'T', 'e', 's', 't', 'F', 'i', 'l', 'e', '1', 'W', '\0' };
|
||||||
|
|
||||||
int TestFileFindFirstFile(int argc, char* argv[])
|
static BOOL create_layout_files(size_t level, const char* BasePath, wArrayList* files)
|
||||||
{
|
{
|
||||||
char* str;
|
for (size_t x = 0; x < 10; x++)
|
||||||
size_t length = 0;
|
|
||||||
HANDLE hFind;
|
|
||||||
LPTSTR BasePath;
|
|
||||||
WIN32_FIND_DATA FindData;
|
|
||||||
TCHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
|
|
||||||
WINPR_UNUSED(argc);
|
|
||||||
|
|
||||||
str = argv[1];
|
|
||||||
#ifdef UNICODE
|
|
||||||
BasePath = ConvertUtf8ToWChar(str, &length);
|
|
||||||
|
|
||||||
if (!BasePath)
|
|
||||||
{
|
{
|
||||||
_tprintf(_T("Unable to allocate memory\n"));
|
CHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
|
||||||
return -1;
|
strncpy(FilePath, BasePath, ARRAYSIZE(FilePath));
|
||||||
|
|
||||||
|
CHAR name[64] = { 0 };
|
||||||
|
_snprintf(name, ARRAYSIZE(name), "%zd-TestFile%zd", level, x);
|
||||||
|
NativePathCchAppendA(FilePath, PATHCCH_MAX_CCH, name);
|
||||||
|
|
||||||
|
HANDLE hdl =
|
||||||
|
CreateFileA(FilePath, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (hdl == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
ArrayList_Append(files, FilePath);
|
||||||
|
CloseHandle(hdl);
|
||||||
}
|
}
|
||||||
#else
|
return TRUE;
|
||||||
BasePath = _strdup(str);
|
}
|
||||||
|
|
||||||
if (!BasePath)
|
static BOOL create_layout_directories(size_t level, size_t max_level, const char* BasePath,
|
||||||
|
wArrayList* files)
|
||||||
|
{
|
||||||
|
if (level >= max_level)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
CHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
|
||||||
|
strncpy(FilePath, BasePath, ARRAYSIZE(FilePath));
|
||||||
|
PathCchConvertStyleA(FilePath, ARRAYSIZE(FilePath), PATH_STYLE_NATIVE);
|
||||||
|
if (!winpr_PathMakePath(FilePath, NULL))
|
||||||
|
return FALSE;
|
||||||
|
ArrayList_Append(files, FilePath);
|
||||||
|
|
||||||
|
if (!create_layout_files(level + 1, BasePath, files))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (size_t x = 0; x < 10; x++)
|
||||||
{
|
{
|
||||||
printf("Unable to allocate memory\n");
|
CHAR CurFilePath[PATHCCH_MAX_CCH] = { 0 };
|
||||||
return -1;
|
strncpy(CurFilePath, FilePath, ARRAYSIZE(CurFilePath));
|
||||||
|
|
||||||
|
PathCchConvertStyleA(CurFilePath, ARRAYSIZE(CurFilePath), PATH_STYLE_NATIVE);
|
||||||
|
|
||||||
|
CHAR name[64] = { 0 };
|
||||||
|
_snprintf(name, ARRAYSIZE(name), "%zd-TestPath%zd", level, x);
|
||||||
|
NativePathCchAppendA(CurFilePath, PATHCCH_MAX_CCH, name);
|
||||||
|
|
||||||
|
if (!create_layout_directories(level + 1, max_level, CurFilePath, files))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL create_layout(const char* BasePath, wArrayList* files)
|
||||||
|
{
|
||||||
|
CHAR BasePathNative[PATHCCH_MAX_CCH] = { 0 };
|
||||||
|
memcpy(BasePathNative, BasePath, sizeof(BasePathNative));
|
||||||
|
PathCchConvertStyleA(BasePathNative, ARRAYSIZE(BasePathNative), PATH_STYLE_NATIVE);
|
||||||
|
|
||||||
|
return create_layout_directories(0, 3, BasePathNative, files);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cleanup_layout(const char* BasePath)
|
||||||
|
{
|
||||||
|
winpr_RemoveDirectory_RecursiveA(BasePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL find_first_file_success(const char* FilePath)
|
||||||
|
{
|
||||||
|
BOOL rc = FALSE;
|
||||||
|
WIN32_FIND_DATAA FindData = { 0 };
|
||||||
|
HANDLE hFind = FindFirstFileA(FilePath, &FindData);
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
printf("FindFirstFile failure: %s (INVALID_HANDLE_VALUE -1)\n", FilePath);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
length = strlen(BasePath);
|
printf("FindFirstFile: %s", FindData.cFileName);
|
||||||
#endif
|
|
||||||
CopyMemory(FilePath, BasePath, length * sizeof(TCHAR));
|
if (strcmp(FindData.cFileName, testFile1A) != 0)
|
||||||
FilePath[length] = 0;
|
{
|
||||||
PathCchConvertStyle(BasePath, length, PATH_STYLE_WINDOWS);
|
printf("FindFirstFile failure: Expected: %s, Actual: %s\n", testFile1A, FindData.cFileName);
|
||||||
NativePathCchAppend(FilePath, PATHCCH_MAX_CCH, _T("TestFile1"));
|
goto fail;
|
||||||
free(BasePath);
|
}
|
||||||
_tprintf(_T("Finding file: %s\n"), FilePath);
|
rc = TRUE;
|
||||||
hFind = FindFirstFile(FilePath, &FindData);
|
fail:
|
||||||
|
FindClose(hFind);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL list_directory_dot(const char* BasePath, wArrayList* files)
|
||||||
|
{
|
||||||
|
BOOL rc = FALSE;
|
||||||
|
CHAR BasePathDot[PATHCCH_MAX_CCH] = { 0 };
|
||||||
|
memcpy(BasePathDot, BasePath, ARRAYSIZE(BasePathDot));
|
||||||
|
PathCchConvertStyleA(BasePathDot, ARRAYSIZE(BasePathDot), PATH_STYLE_NATIVE);
|
||||||
|
NativePathCchAppendA(BasePathDot, PATHCCH_MAX_CCH, ".");
|
||||||
|
WIN32_FIND_DATAA FindData = { 0 };
|
||||||
|
HANDLE hFind = FindFirstFileA(BasePathDot, &FindData);
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
size_t count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
if (strcmp(FindData.cFileName, ".") != 0)
|
||||||
|
goto fail;
|
||||||
|
} while (FindNextFile(hFind, &FindData));
|
||||||
|
|
||||||
|
rc = TRUE;
|
||||||
|
fail:
|
||||||
|
FindClose(hFind);
|
||||||
|
|
||||||
|
if (count != 1)
|
||||||
|
return FALSE;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL list_directory_star(const char* BasePath, wArrayList* files)
|
||||||
|
{
|
||||||
|
CHAR BasePathDot[PATHCCH_MAX_CCH] = { 0 };
|
||||||
|
memcpy(BasePathDot, BasePath, ARRAYSIZE(BasePathDot));
|
||||||
|
PathCchConvertStyleA(BasePathDot, ARRAYSIZE(BasePathDot), PATH_STYLE_NATIVE);
|
||||||
|
NativePathCchAppendA(BasePathDot, PATHCCH_MAX_CCH, "*");
|
||||||
|
WIN32_FIND_DATAA FindData = { 0 };
|
||||||
|
HANDLE hFind = FindFirstFileA(BasePathDot, &FindData);
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
|
return FALSE;
|
||||||
|
size_t count = 0;
|
||||||
|
size_t dotcount = 0;
|
||||||
|
size_t dotdotcount = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (strcmp(FindData.cFileName, ".") == 0)
|
||||||
|
dotcount++;
|
||||||
|
else if (strcmp(FindData.cFileName, "..") == 0)
|
||||||
|
dotdotcount++;
|
||||||
|
else
|
||||||
|
count++;
|
||||||
|
} while (FindNextFile(hFind, &FindData));
|
||||||
|
FindClose(hFind);
|
||||||
|
|
||||||
|
const char sep = PathGetSeparatorA(PATH_STYLE_NATIVE);
|
||||||
|
size_t fcount = 0;
|
||||||
|
const size_t baselen = strlen(BasePath);
|
||||||
|
const size_t total = ArrayList_Count(files);
|
||||||
|
for (size_t x = 0; x < total; x++)
|
||||||
|
{
|
||||||
|
const char* path = ArrayList_GetItem(files, x);
|
||||||
|
const size_t pathlen = strlen(path);
|
||||||
|
if (pathlen < baselen)
|
||||||
|
continue;
|
||||||
|
const char* skip = &path[baselen];
|
||||||
|
if (*skip == sep)
|
||||||
|
skip++;
|
||||||
|
const char* end = strrchr(skip, sep);
|
||||||
|
if (end)
|
||||||
|
continue;
|
||||||
|
fcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fcount != count)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL find_first_file_fail(const char* FilePath)
|
||||||
|
{
|
||||||
|
WIN32_FIND_DATAA FindData = { 0 };
|
||||||
|
HANDLE hFind = FindFirstFileA(FilePath, &FindData);
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
FindClose(hFind);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TestFileFindFirstFileA(const char* str)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
if (!str)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
CHAR BasePath[PATHCCH_MAX_CCH] = { 0 };
|
||||||
|
|
||||||
|
strncpy(BasePath, str, ARRAYSIZE(BasePath));
|
||||||
|
|
||||||
|
const size_t length = strnlen(BasePath, PATHCCH_MAX_CCH - 1);
|
||||||
|
|
||||||
|
CHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
|
||||||
|
CopyMemory(FilePath, BasePath, length * sizeof(CHAR));
|
||||||
|
|
||||||
|
PathCchConvertStyleA(BasePath, length, PATH_STYLE_WINDOWS);
|
||||||
|
|
||||||
|
wArrayList* files = ArrayList_New(FALSE);
|
||||||
|
if (!files)
|
||||||
|
return -3;
|
||||||
|
wObject* obj = ArrayList_Object(files);
|
||||||
|
obj->fnObjectFree = free;
|
||||||
|
obj->fnObjectNew = _strdup;
|
||||||
|
|
||||||
|
if (!create_layout(BasePath, files))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
NativePathCchAppendA(FilePath, PATHCCH_MAX_CCH, testFile1A);
|
||||||
|
|
||||||
|
printf("Finding file: %s\n", FilePath);
|
||||||
|
|
||||||
|
if (!find_first_file_fail(FilePath))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
HANDLE hdl =
|
||||||
|
CreateFileA(FilePath, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if (hdl == INVALID_HANDLE_VALUE)
|
||||||
|
goto fail;
|
||||||
|
CloseHandle(hdl);
|
||||||
|
|
||||||
|
if (!find_first_file_success(FilePath))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
CHAR BasePathInvalid[PATHCCH_MAX_CCH] = { 0 };
|
||||||
|
memcpy(BasePathInvalid, BasePath, ARRAYSIZE(BasePathInvalid));
|
||||||
|
PathCchAddBackslashA(BasePathInvalid, PATHCCH_MAX_CCH);
|
||||||
|
|
||||||
|
if (!find_first_file_fail(BasePathInvalid))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (!list_directory_dot(BasePath, files))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (!list_directory_star(BasePath, files))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
|
fail:
|
||||||
|
DeleteFileA(FilePath);
|
||||||
|
cleanup_layout(BasePath);
|
||||||
|
ArrayList_Free(files);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int TestFileFindFirstFileW(const char* str)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
if (!str)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
WCHAR BasePath[PATHCCH_MAX_CCH] = { 0 };
|
||||||
|
|
||||||
|
ConvertUtf8ToWChar(str, BasePath, ARRAYSIZE(BasePath));
|
||||||
|
|
||||||
|
const size_t length = _wcsnlen(BasePath, PATHCCH_MAX_CCH - 1);
|
||||||
|
|
||||||
|
WCHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
|
||||||
|
CopyMemory(FilePath, BasePath, length * sizeof(WCHAR));
|
||||||
|
|
||||||
|
PathCchConvertStyleW(BasePath, length, PATH_STYLE_WINDOWS);
|
||||||
|
NativePathCchAppendW(FilePath, PATHCCH_MAX_CCH, testFile1W);
|
||||||
|
|
||||||
|
CHAR FilePathA[PATHCCH_MAX_CCH] = { 0 };
|
||||||
|
ConvertWCharNToUtf8(FilePath, ARRAYSIZE(FilePath), FilePathA, ARRAYSIZE(FilePathA));
|
||||||
|
printf("Finding file: %s\n", FilePathA);
|
||||||
|
|
||||||
|
WIN32_FIND_DATAW FindData = { 0 };
|
||||||
|
HANDLE hFind = FindFirstFileW(FilePath, &FindData);
|
||||||
|
|
||||||
if (hFind == INVALID_HANDLE_VALUE)
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
_tprintf(_T("FindFirstFile failure: %s (INVALID_HANDLE_VALUE -1)\n"), FilePath);
|
printf("FindFirstFile failure: %s (INVALID_HANDLE_VALUE -1)\n", FilePathA);
|
||||||
return -1;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
_tprintf(_T("FindFirstFile: %s"), FindData.cFileName);
|
CHAR cFileName[MAX_PATH] = { 0 };
|
||||||
|
ConvertWCharNToUtf8(FindData.cFileName, ARRAYSIZE(FindData.cFileName), cFileName,
|
||||||
|
ARRAYSIZE(cFileName));
|
||||||
|
|
||||||
if (_tcscmp(FindData.cFileName, testFile1) != 0)
|
printf("FindFirstFile: %s", cFileName);
|
||||||
|
|
||||||
|
if (_wcscmp(FindData.cFileName, testFile1W) != 0)
|
||||||
{
|
{
|
||||||
_tprintf(_T("FindFirstFile failure: Expected: %s, Actual: %s\n"), testFile1,
|
printf("FindFirstFile failure: Expected: %s, Actual: %s\n", testFile1A, cFileName);
|
||||||
FindData.cFileName);
|
goto fail;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = 0;
|
||||||
|
fail:
|
||||||
|
DeleteFileW(FilePath);
|
||||||
FindClose(hFind);
|
FindClose(hFind);
|
||||||
return 0;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TestFileFindFirstFile(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
char* str = GetKnownSubPath(KNOWN_PATH_TEMP, "TestFileFindFirstFile");
|
||||||
|
if (!str)
|
||||||
|
return -23;
|
||||||
|
|
||||||
|
cleanup_layout(str);
|
||||||
|
|
||||||
|
int rc1 = -1;
|
||||||
|
int rc2 = -1;
|
||||||
|
if (winpr_PathMakePath(str, NULL))
|
||||||
|
{
|
||||||
|
rc1 = TestFileFindFirstFileA(str);
|
||||||
|
rc2 = 0; // TestFileFindFirstFileW(str);
|
||||||
|
winpr_RemoveDirectory(str);
|
||||||
|
}
|
||||||
|
free(str);
|
||||||
|
return rc1 + rc2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags,
|
HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags,
|
||||||
PWSTR* ppszPathOut)
|
PWSTR* ppszPathOut)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
PWSTR pszPathOut;
|
PWSTR pszPathOut;
|
||||||
BOOL backslashIn;
|
BOOL backslashIn;
|
||||||
BOOL backslashMore;
|
BOOL backslashMore;
|
||||||
|
@ -44,8 +43,8 @@ HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFla
|
||||||
if (!pszPathIn)
|
if (!pszPathIn)
|
||||||
return E_FAIL; /* valid but not implemented, see top comment */
|
return E_FAIL; /* valid but not implemented, see top comment */
|
||||||
|
|
||||||
pszPathInLength = wcslen(pszPathIn);
|
pszPathInLength = _wcslen(pszPathIn);
|
||||||
pszMoreLength = wcslen(pszMore);
|
pszMoreLength = _wcslen(pszMore);
|
||||||
|
|
||||||
/* prevent segfaults - the complete implementation below is buggy */
|
/* prevent segfaults - the complete implementation below is buggy */
|
||||||
if (pszPathInLength < 3)
|
if (pszPathInLength < 3)
|
||||||
|
@ -58,21 +57,25 @@ HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFla
|
||||||
{
|
{
|
||||||
if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR))
|
if ((pszPathIn[1] == ':') && (pszPathIn[2] == CUR_PATH_SEPARATOR_CHR))
|
||||||
{
|
{
|
||||||
|
const WCHAR colon[] = { ':', '\0' };
|
||||||
size_t sizeOfBuffer;
|
size_t sizeOfBuffer;
|
||||||
pszPathOutLength = 2 + pszMoreLength;
|
pszPathOutLength = sizeof(WCHAR) + pszMoreLength;
|
||||||
sizeOfBuffer = (pszPathOutLength + 1) * 2;
|
sizeOfBuffer = (pszPathOutLength + 1) * sizeof(WCHAR);
|
||||||
pszPathOut = (PWSTR)calloc(sizeOfBuffer, 2);
|
pszPathOut = (PWSTR)calloc(sizeOfBuffer, sizeof(WCHAR));
|
||||||
|
|
||||||
if (!pszPathOut)
|
if (!pszPathOut)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
swprintf_s(pszPathOut, sizeOfBuffer, L"%c:%s", pszPathIn[0], pszMore);
|
_wcsncat(pszPathOut, &pszPathIn[0], 1);
|
||||||
|
_wcsncat(pszPathOut, colon, ARRAYSIZE(colon));
|
||||||
|
_wcsncat(pszPathOut, pszMore, pszMoreLength);
|
||||||
*ppszPathOut = pszPathOut;
|
*ppszPathOut = pszPathOut;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
const WCHAR sep[] = CUR_PATH_SEPARATOR_STR;
|
||||||
size_t sizeOfBuffer;
|
size_t sizeOfBuffer;
|
||||||
pszPathOutLength = pszPathInLength + pszMoreLength;
|
pszPathOutLength = pszPathInLength + pszMoreLength;
|
||||||
sizeOfBuffer = (pszPathOutLength + 1) * 2;
|
sizeOfBuffer = (pszPathOutLength + 1) * 2;
|
||||||
|
@ -81,17 +84,15 @@ HRESULT PATH_ALLOC_COMBINE(PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFla
|
||||||
if (!pszPathOut)
|
if (!pszPathOut)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if (backslashIn)
|
_wcsncat(pszPathOut, pszPathIn, pszPathInLength);
|
||||||
swprintf_s(pszPathOut, sizeOfBuffer, L"%s%s", pszPathIn, pszMore);
|
if (!backslashIn)
|
||||||
else
|
_wcsncat(pszPathOut, sep, ARRAYSIZE(sep));
|
||||||
swprintf_s(pszPathOut, sizeOfBuffer, L"%s" CUR_PATH_SEPARATOR_STR L"%s", pszPathIn,
|
_wcsncat(pszPathOut, pszMore, pszMoreLength);
|
||||||
pszMore);
|
|
||||||
|
|
||||||
*ppszPathOut = pszPathOut;
|
*ppszPathOut = pszPathOut;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
HRESULT PATH_CCH_ADD_EXTENSION(PWSTR pszPath, size_t cchPath, PCWSTR pszExt)
|
HRESULT PATH_CCH_ADD_EXTENSION(PWSTR pszPath, size_t cchPath, PCWSTR pszExt)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
LPWSTR pDot;
|
LPWSTR pDot;
|
||||||
BOOL bExtDot;
|
BOOL bExtDot;
|
||||||
LPWSTR pBackslash;
|
LPWSTR pBackslash;
|
||||||
|
@ -26,8 +25,8 @@ HRESULT PATH_CCH_ADD_EXTENSION(PWSTR pszPath, size_t cchPath, PCWSTR pszExt)
|
||||||
pszPathLength = lstrlenW(pszPath);
|
pszPathLength = lstrlenW(pszPath);
|
||||||
bExtDot = (pszExt[0] == '.') ? TRUE : FALSE;
|
bExtDot = (pszExt[0] == '.') ? TRUE : FALSE;
|
||||||
|
|
||||||
pDot = wcsrchr(pszPath, '.');
|
pDot = _wcsrchr(pszPath, '.');
|
||||||
pBackslash = wcsrchr(pszPath, CUR_PATH_SEPARATOR_CHR);
|
pBackslash = _wcsrchr(pszPath, CUR_PATH_SEPARATOR_CHR);
|
||||||
|
|
||||||
if (pDot && pBackslash)
|
if (pDot && pBackslash)
|
||||||
{
|
{
|
||||||
|
@ -37,14 +36,17 @@ HRESULT PATH_CCH_ADD_EXTENSION(PWSTR pszPath, size_t cchPath, PCWSTR pszExt)
|
||||||
|
|
||||||
if (cchPath > pszPathLength + pszExtLength + ((bExtDot) ? 0 : 1))
|
if (cchPath > pszPathLength + pszExtLength + ((bExtDot) ? 0 : 1))
|
||||||
{
|
{
|
||||||
if (bExtDot)
|
const WCHAR dot[] = { '.', '\0' };
|
||||||
swprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, L"%s", pszExt);
|
WCHAR* ptr = &pszPath[pszPathLength];
|
||||||
else
|
*ptr = '\0';
|
||||||
swprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, L".%s", pszExt);
|
|
||||||
|
if (!bExtDot)
|
||||||
|
_wcsncat(ptr, dot, _wcslen(dot));
|
||||||
|
_wcsncat(ptr, pszExt, pszExtLength);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
|
|
||||||
HRESULT PATH_CCH_APPEND(PWSTR pszPath, size_t cchPath, PCWSTR pszMore)
|
HRESULT PATH_CCH_APPEND(PWSTR pszPath, size_t cchPath, PCWSTR pszMore)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
BOOL pathBackslash;
|
BOOL pathBackslash;
|
||||||
BOOL moreBackslash;
|
BOOL moreBackslash;
|
||||||
size_t pszMoreLength;
|
size_t pszMoreLength;
|
||||||
|
@ -35,7 +34,9 @@ HRESULT PATH_CCH_APPEND(PWSTR pszPath, size_t cchPath, PCWSTR pszMore)
|
||||||
{
|
{
|
||||||
if ((pszPathLength + pszMoreLength - 1) < cchPath)
|
if ((pszPathLength + pszMoreLength - 1) < cchPath)
|
||||||
{
|
{
|
||||||
swprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, L"%s", &pszMore[1]);
|
WCHAR* ptr = &pszPath[pszPathLength];
|
||||||
|
*ptr = '\0';
|
||||||
|
_wcsncat(ptr, &pszMore[1], _wcslen(&pszMore[1]));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +44,9 @@ HRESULT PATH_CCH_APPEND(PWSTR pszPath, size_t cchPath, PCWSTR pszMore)
|
||||||
{
|
{
|
||||||
if ((pszPathLength + pszMoreLength) < cchPath)
|
if ((pszPathLength + pszMoreLength) < cchPath)
|
||||||
{
|
{
|
||||||
swprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength, L"%s", pszMore);
|
WCHAR* ptr = &pszPath[pszPathLength];
|
||||||
|
*ptr = '\0';
|
||||||
|
_wcsncat(ptr, pszMore, _wcslen(pszMore));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,12 +54,14 @@ HRESULT PATH_CCH_APPEND(PWSTR pszPath, size_t cchPath, PCWSTR pszMore)
|
||||||
{
|
{
|
||||||
if ((pszPathLength + pszMoreLength + 1) < cchPath)
|
if ((pszPathLength + pszMoreLength + 1) < cchPath)
|
||||||
{
|
{
|
||||||
swprintf_s(&pszPath[pszPathLength], cchPath - pszPathLength,
|
const WCHAR sep[] = CUR_PATH_SEPARATOR_STR;
|
||||||
CUR_PATH_SEPARATOR_STR L"%s", pszMore);
|
WCHAR* ptr = &pszPath[pszPathLength];
|
||||||
|
*ptr = '\0';
|
||||||
|
_wcsncat(ptr, sep, _wcslen(sep));
|
||||||
|
_wcsncat(ptr, pszMore, _wcslen(pszMore));
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE);
|
return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,14 @@
|
||||||
#define PATH_SLASH_STR_W L"/"
|
#define PATH_SLASH_STR_W L"/"
|
||||||
#define PATH_BACKSLASH_STR_W L"\\"
|
#define PATH_BACKSLASH_STR_W L"\\"
|
||||||
#else
|
#else
|
||||||
#define PATH_SLASH_STR_W "/"
|
#define PATH_SLASH_STR_W \
|
||||||
#define PATH_BACKSLASH_STR_W "\\"
|
{ \
|
||||||
|
'/', '\0' \
|
||||||
|
}
|
||||||
|
#define PATH_BACKSLASH_STR_W \
|
||||||
|
{ \
|
||||||
|
'\\', '\0' \
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -1109,15 +1115,13 @@ BOOL winpr_RemoveDirectory_RecursiveW(LPCWSTR lpPathName)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
const size_t pathnamelen = _wcslen(lpPathName);
|
const size_t pathnamelen = _wcslen(lpPathName);
|
||||||
const size_t path_slash_len = pathnamelen + 2;
|
const size_t path_slash_len = pathnamelen + 3;
|
||||||
WCHAR* path_slash = calloc(pathnamelen + 3, sizeof(WCHAR));
|
WCHAR* path_slash = calloc(pathnamelen + 4, sizeof(WCHAR));
|
||||||
if (!path_slash)
|
if (!path_slash)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
memcpy(path_slash, lpPathName, pathnamelen * sizeof(WCHAR));
|
memcpy(path_slash, lpPathName, pathnamelen * sizeof(WCHAR));
|
||||||
|
|
||||||
const WCHAR sep[] = { PathGetSeparatorW(PATH_STYLE_NATIVE), '\0' };
|
|
||||||
const WCHAR star[] = { '*', '\0' };
|
const WCHAR star[] = { '*', '\0' };
|
||||||
PathCchAppendW(path_slash, path_slash_len, sep);
|
|
||||||
PathCchAppendW(path_slash, path_slash_len, star);
|
PathCchAppendW(path_slash, path_slash_len, star);
|
||||||
|
|
||||||
WIN32_FIND_DATAW findFileData = { 0 };
|
WIN32_FIND_DATAW findFileData = { 0 };
|
||||||
|
|
Loading…
Reference in New Issue