4#include <winpr/handle.h>
7#include <winpr/tchar.h>
8#include <winpr/collections.h>
9#include <winpr/windows.h>
11#define TEST_MAX_PATH 4096
13static const CHAR testFile1A[] =
"TestFile1A";
15static BOOL create_fileA(
const char* FilePath)
17 HANDLE hdl = winpr_CreateFile(FilePath, GENERIC_ALL, 0,
nullptr, CREATE_ALWAYS,
18 FILE_ATTRIBUTE_NORMAL,
nullptr);
19 if (hdl == INVALID_HANDLE_VALUE)
21 (void)CloseHandle(hdl);
25static BOOL create_fileW(
const WCHAR* FilePath)
27 HANDLE hdl = CreateFileW(FilePath, GENERIC_ALL, 0,
nullptr, CREATE_ALWAYS,
28 FILE_ATTRIBUTE_NORMAL,
nullptr);
29 if (hdl == INVALID_HANDLE_VALUE)
31 (void)CloseHandle(hdl);
35static BOOL create_layout_files(
size_t level,
const char* BasePath, wArrayList* files)
38 for (
size_t x = 0; x < 10; x++)
40 CHAR FilePath[TEST_MAX_PATH] = WINPR_C_ARRAY_INIT;
41 strncpy(FilePath, BasePath, ARRAYSIZE(FilePath));
43 CHAR name[64] = WINPR_C_ARRAY_INIT;
44 (void)_snprintf(name, ARRAYSIZE(name),
"%zd-TestFile%zd", level, x);
45 if (FAILED(NativePathCchAppendA(FilePath, TEST_MAX_PATH, name)))
48 if (create_fileA(FilePath))
50 if (!ArrayList_Append(files, FilePath))
57static BOOL create_layout_directories(
size_t level,
size_t max_level,
const char* BasePath,
60 if (level >= max_level)
63 CHAR FilePath[TEST_MAX_PATH] = WINPR_C_ARRAY_INIT;
64 strncpy(FilePath, BasePath, ARRAYSIZE(FilePath));
65 if (FAILED(PathCchConvertStyleA(FilePath, ARRAYSIZE(FilePath), PATH_STYLE_NATIVE)))
67 if (!winpr_PathMakePath(FilePath,
nullptr))
69 ArrayList_Append(files, FilePath);
71 if (!create_layout_files(level + 1, BasePath, files))
74 for (
size_t x = 0; x < 10; x++)
76 CHAR CurFilePath[TEST_MAX_PATH] = WINPR_C_ARRAY_INIT;
77 strncpy(CurFilePath, FilePath, ARRAYSIZE(CurFilePath));
79 if (FAILED(PathCchConvertStyleA(CurFilePath, ARRAYSIZE(CurFilePath), PATH_STYLE_NATIVE)))
82 CHAR name[64] = WINPR_C_ARRAY_INIT;
83 (void)_snprintf(name, ARRAYSIZE(name),
"%zd-TestPath%zd", level, x);
84 if (FAILED(NativePathCchAppendA(CurFilePath, TEST_MAX_PATH, name)))
87 if (!create_layout_directories(level + 1, max_level, CurFilePath, files))
93static BOOL create_layout(
const char* BasePath, wArrayList* files)
95 CHAR BasePathNative[TEST_MAX_PATH] = WINPR_C_ARRAY_INIT;
96 memcpy(BasePathNative, BasePath,
sizeof(BasePathNative));
97 if (FAILED(PathCchConvertStyleA(BasePathNative, ARRAYSIZE(BasePathNative), PATH_STYLE_NATIVE)))
100 return create_layout_directories(0, 3, BasePathNative, files);
103static void cleanup_layout(
const char* BasePath)
105 winpr_RemoveDirectory_RecursiveA(BasePath);
108static BOOL find_first_file_success(
const char* FilePath)
112 HANDLE hFind = FindFirstFileA(FilePath, &FindData);
113 if (hFind == INVALID_HANDLE_VALUE)
115 printf(
"FindFirstFile failure: %s (INVALID_HANDLE_VALUE -1)\n", FilePath);
119 printf(
"FindFirstFile: %s\n", FindData.cFileName);
121 if (strcmp(FindData.cFileName, testFile1A) != 0)
123 printf(
"FindFirstFile failure: Expected: %s, Actual: %s\n", testFile1A, FindData.cFileName);
128 if (hFind != INVALID_HANDLE_VALUE)
133static BOOL list_directory_dot(
const char* BasePath, wArrayList* files)
136 CHAR BasePathDot[TEST_MAX_PATH] = WINPR_C_ARRAY_INIT;
137 memcpy(BasePathDot, BasePath, ARRAYSIZE(BasePathDot));
138 if (FAILED(PathCchConvertStyleA(BasePathDot, ARRAYSIZE(BasePathDot), PATH_STYLE_NATIVE)))
140 if (FAILED(NativePathCchAppendA(BasePathDot, TEST_MAX_PATH,
".")))
143 HANDLE hFind = FindFirstFileA(BasePathDot, &FindData);
144 if (hFind == INVALID_HANDLE_VALUE)
150 if (strcmp(FindData.cFileName,
".") != 0)
152 }
while (FindNextFile(hFind, &FindData));
163static BOOL list_directory_star(
const char* BasePath, wArrayList* files)
165 CHAR BasePathDot[TEST_MAX_PATH] = WINPR_C_ARRAY_INIT;
166 memcpy(BasePathDot, BasePath, ARRAYSIZE(BasePathDot));
168 if (FAILED(PathCchConvertStyleA(BasePathDot, ARRAYSIZE(BasePathDot), PATH_STYLE_NATIVE)))
171 if (FAILED(NativePathCchAppendA(BasePathDot, TEST_MAX_PATH,
"*")))
175 HANDLE hFind = FindFirstFileA(BasePathDot, &FindData);
176 if (hFind == INVALID_HANDLE_VALUE)
180 size_t dotdotcount = 0;
183 if (strcmp(FindData.cFileName,
".") == 0)
185 else if (strcmp(FindData.cFileName,
"..") == 0)
189 }
while (FindNextFile(hFind, &FindData));
192 const char sep = PathGetSeparatorA(PATH_STYLE_NATIVE);
194 const size_t baselen = strlen(BasePath);
195 const size_t total = ArrayList_Count(files);
196 for (
size_t x = 0; x < total; x++)
198 const char* path = ArrayList_GetItem(files, x);
199 const size_t pathlen = strlen(path);
200 if (pathlen < baselen)
202 const char* skip = &path[baselen];
205 const char* end = strrchr(skip, sep);
211 return (fcount == count);
214static BOOL find_first_file_fail(
const char* FilePath)
217 HANDLE hFind = FindFirstFileA(FilePath, &FindData);
218 if (hFind == INVALID_HANDLE_VALUE)
225static int TestFileFindFirstFileA(
const char* str)
229 printf(
"[%s] basepath: '%s'\n", __func__, str);
233 CHAR BasePath[TEST_MAX_PATH] = WINPR_C_ARRAY_INIT;
235 strncpy(BasePath, str, ARRAYSIZE(BasePath));
237 const size_t length = strnlen(BasePath, TEST_MAX_PATH - 1);
239 CHAR FilePath[TEST_MAX_PATH] = WINPR_C_ARRAY_INIT;
240 CopyMemory(FilePath, BasePath, length *
sizeof(CHAR));
242 if (FAILED(PathCchConvertStyleA(BasePath, length, PATH_STYLE_WINDOWS)))
245 wArrayList* files = ArrayList_New(FALSE);
248 wObject* obj = ArrayList_Object(files);
252 if (!create_layout(BasePath, files))
255 if (FAILED(NativePathCchAppendA(FilePath, TEST_MAX_PATH, testFile1A)))
258 printf(
"Finding file: %s\n", FilePath);
260 if (!find_first_file_fail(FilePath))
263 if (!create_fileA(FilePath))
266 if (!find_first_file_success(FilePath))
269 CHAR BasePathInvalid[TEST_MAX_PATH] = WINPR_C_ARRAY_INIT;
270 (void)_snprintf(BasePathInvalid, ARRAYSIZE(BasePathInvalid),
"%s\\", BasePath);
272 if (!find_first_file_fail(BasePathInvalid))
275 if (!list_directory_dot(BasePath, files))
278 if (!list_directory_star(BasePath, files))
283 winpr_DeleteFile(FilePath);
284 cleanup_layout(BasePath);
285 ArrayList_Free(files);
289WINPR_ATTR_FORMAT_ARG(1, 0)
290static
int printf1W(const
char* WINPR_FORMAT_ARG fmt, const WCHAR* arg1)
292 char* var1 = ConvertWCharToUtf8Alloc(arg1,
nullptr);
293 const int rc = printf(fmt, var1);
298WINPR_ATTR_FORMAT_ARG(1, 0)
299static
int printf2W(const
char* WINPR_FORMAT_ARG fmt, const WCHAR* arg1, const WCHAR* arg2)
301 char* var1 = ConvertWCharToUtf8Alloc(arg1,
nullptr);
302 char* var2 = ConvertWCharToUtf8Alloc(arg2,
nullptr);
303 const int rc = printf(fmt, var1, var2);
309static int TestFileFindFirstFileW(
const char* str)
311 WCHAR buffer[32] = WINPR_C_ARRAY_INIT;
312 const WCHAR* testFile1W = InitializeConstWCharFromUtf8(
"TestFile1W", buffer, ARRAYSIZE(buffer));
317 WCHAR BasePath[TEST_MAX_PATH] = WINPR_C_ARRAY_INIT;
319 printf(
"[%s] basepath: '%s'\n", __func__, str);
320 (void)ConvertUtf8ToWChar(str, BasePath, ARRAYSIZE(BasePath));
322 const size_t length = _wcsnlen(BasePath, TEST_MAX_PATH - 1);
324 WCHAR FilePath[TEST_MAX_PATH] = WINPR_C_ARRAY_INIT;
325 CopyMemory(FilePath, BasePath, length *
sizeof(WCHAR));
327 HANDLE hFind = INVALID_HANDLE_VALUE;
328 if (FAILED(PathCchConvertStyleW(BasePath, length, PATH_STYLE_WINDOWS)))
330 if (FAILED(NativePathCchAppendW(FilePath, TEST_MAX_PATH, testFile1W)))
333 if (!create_fileW(FilePath))
336 printf1W(
"Finding file: %s\n", FilePath);
339 hFind = FindFirstFileW(FilePath, &FindData);
341 if (hFind == INVALID_HANDLE_VALUE)
343 printf1W(
"FindFirstFile failure: %s (INVALID_HANDLE_VALUE -1)\n", FilePath);
347 printf1W(
"FindFirstFile: %s\n", FindData.cFileName);
349 if (_wcscmp(FindData.cFileName, testFile1W) != 0)
351 printf2W(
"FindFirstFile failure: Expected: %s, Actual: %s\n", testFile1W,
358 DeleteFileW(FilePath);
363int TestFileFindFirstFile(
int argc,
char* argv[])
365 char* str = GetKnownSubPath(KNOWN_PATH_TEMP,
"TestFileFindFirstFile");
373 if (winpr_PathMakePath(str,
nullptr))
375 rc1 = TestFileFindFirstFileA(str);
376 rc2 = TestFileFindFirstFileW(str);
377 winpr_RemoveDirectory(str);
This struct contains function pointer to initialize/free objects.
OBJECT_FREE_FN fnObjectFree
WINPR_ATTR_NODISCARD OBJECT_NEW_FN fnObjectNew