4#include <winpr/handle.h>
7#include <winpr/tchar.h>
8#include <winpr/collections.h>
9#include <winpr/windows.h>
11static const CHAR testFile1A[] =
"TestFile1A";
13static BOOL create_fileA(
const char* FilePath)
16 CreateFileA(FilePath, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
17 if (hdl == INVALID_HANDLE_VALUE)
19 (void)CloseHandle(hdl);
23static BOOL create_fileW(
const WCHAR* FilePath)
26 CreateFileW(FilePath, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
27 if (hdl == INVALID_HANDLE_VALUE)
29 (void)CloseHandle(hdl);
33static BOOL create_layout_files(
size_t level,
const char* BasePath, wArrayList* files)
35 for (
size_t x = 0; x < 10; x++)
37 CHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
38 strncpy(FilePath, BasePath, ARRAYSIZE(FilePath));
40 CHAR name[64] = { 0 };
41 (void)_snprintf(name, ARRAYSIZE(name),
"%zd-TestFile%zd", level, x);
42 NativePathCchAppendA(FilePath, PATHCCH_MAX_CCH, name);
44 if (create_fileA(FilePath))
45 ArrayList_Append(files, FilePath);
50static BOOL create_layout_directories(
size_t level,
size_t max_level,
const char* BasePath,
53 if (level >= max_level)
56 CHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
57 strncpy(FilePath, BasePath, ARRAYSIZE(FilePath));
58 PathCchConvertStyleA(FilePath, ARRAYSIZE(FilePath), PATH_STYLE_NATIVE);
59 if (!winpr_PathMakePath(FilePath, NULL))
61 ArrayList_Append(files, FilePath);
63 if (!create_layout_files(level + 1, BasePath, files))
66 for (
size_t x = 0; x < 10; x++)
68 CHAR CurFilePath[PATHCCH_MAX_CCH] = { 0 };
69 strncpy(CurFilePath, FilePath, ARRAYSIZE(CurFilePath));
71 PathCchConvertStyleA(CurFilePath, ARRAYSIZE(CurFilePath), PATH_STYLE_NATIVE);
73 CHAR name[64] = { 0 };
74 (void)_snprintf(name, ARRAYSIZE(name),
"%zd-TestPath%zd", level, x);
75 NativePathCchAppendA(CurFilePath, PATHCCH_MAX_CCH, name);
77 if (!create_layout_directories(level + 1, max_level, CurFilePath, files))
83static BOOL create_layout(
const char* BasePath, wArrayList* files)
85 CHAR BasePathNative[PATHCCH_MAX_CCH] = { 0 };
86 memcpy(BasePathNative, BasePath,
sizeof(BasePathNative));
87 PathCchConvertStyleA(BasePathNative, ARRAYSIZE(BasePathNative), PATH_STYLE_NATIVE);
89 return create_layout_directories(0, 3, BasePathNative, files);
92static void cleanup_layout(
const char* BasePath)
94 winpr_RemoveDirectory_RecursiveA(BasePath);
97static BOOL find_first_file_success(
const char* FilePath)
101 HANDLE hFind = FindFirstFileA(FilePath, &FindData);
102 if (hFind == INVALID_HANDLE_VALUE)
104 printf(
"FindFirstFile failure: %s (INVALID_HANDLE_VALUE -1)\n", FilePath);
108 printf(
"FindFirstFile: %s\n", FindData.cFileName);
110 if (strcmp(FindData.cFileName, testFile1A) != 0)
112 printf(
"FindFirstFile failure: Expected: %s, Actual: %s\n", testFile1A, FindData.cFileName);
117 if (hFind != INVALID_HANDLE_VALUE)
122static BOOL list_directory_dot(
const char* BasePath, wArrayList* files)
125 CHAR BasePathDot[PATHCCH_MAX_CCH] = { 0 };
126 memcpy(BasePathDot, BasePath, ARRAYSIZE(BasePathDot));
127 PathCchConvertStyleA(BasePathDot, ARRAYSIZE(BasePathDot), PATH_STYLE_NATIVE);
128 NativePathCchAppendA(BasePathDot, PATHCCH_MAX_CCH,
".");
130 HANDLE hFind = FindFirstFileA(BasePathDot, &FindData);
131 if (hFind == INVALID_HANDLE_VALUE)
137 if (strcmp(FindData.cFileName,
".") != 0)
139 }
while (FindNextFile(hFind, &FindData));
150static BOOL list_directory_star(
const char* BasePath, wArrayList* files)
152 CHAR BasePathDot[PATHCCH_MAX_CCH] = { 0 };
153 memcpy(BasePathDot, BasePath, ARRAYSIZE(BasePathDot));
154 PathCchConvertStyleA(BasePathDot, ARRAYSIZE(BasePathDot), PATH_STYLE_NATIVE);
155 NativePathCchAppendA(BasePathDot, PATHCCH_MAX_CCH,
"*");
157 HANDLE hFind = FindFirstFileA(BasePathDot, &FindData);
158 if (hFind == INVALID_HANDLE_VALUE)
162 size_t dotdotcount = 0;
165 if (strcmp(FindData.cFileName,
".") == 0)
167 else if (strcmp(FindData.cFileName,
"..") == 0)
171 }
while (FindNextFile(hFind, &FindData));
174 const char sep = PathGetSeparatorA(PATH_STYLE_NATIVE);
176 const size_t baselen = strlen(BasePath);
177 const size_t total = ArrayList_Count(files);
178 for (
size_t x = 0; x < total; x++)
180 const char* path = ArrayList_GetItem(files, x);
181 const size_t pathlen = strlen(path);
182 if (pathlen < baselen)
184 const char* skip = &path[baselen];
187 const char* end = strrchr(skip, sep);
198static BOOL find_first_file_fail(
const char* FilePath)
201 HANDLE hFind = FindFirstFileA(FilePath, &FindData);
202 if (hFind == INVALID_HANDLE_VALUE)
209static int TestFileFindFirstFileA(
const char* str)
213 printf(
"[%s] basepath: '%s'\n", __func__, str);
217 CHAR BasePath[PATHCCH_MAX_CCH] = { 0 };
219 strncpy(BasePath, str, ARRAYSIZE(BasePath));
221 const size_t length = strnlen(BasePath, PATHCCH_MAX_CCH - 1);
223 CHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
224 CopyMemory(FilePath, BasePath, length *
sizeof(CHAR));
226 PathCchConvertStyleA(BasePath, length, PATH_STYLE_WINDOWS);
228 wArrayList* files = ArrayList_New(FALSE);
231 wObject* obj = ArrayList_Object(files);
232 obj->fnObjectFree = winpr_ObjectStringFree;
233 obj->fnObjectNew = winpr_ObjectStringClone;
235 if (!create_layout(BasePath, files))
238 NativePathCchAppendA(FilePath, PATHCCH_MAX_CCH, testFile1A);
240 printf(
"Finding file: %s\n", FilePath);
242 if (!find_first_file_fail(FilePath))
245 if (!create_fileA(FilePath))
248 if (!find_first_file_success(FilePath))
251 CHAR BasePathInvalid[PATHCCH_MAX_CCH] = { 0 };
252 memcpy(BasePathInvalid, BasePath, ARRAYSIZE(BasePathInvalid));
253 PathCchAddBackslashA(BasePathInvalid, PATHCCH_MAX_CCH);
255 if (!find_first_file_fail(BasePathInvalid))
258 if (!list_directory_dot(BasePath, files))
261 if (!list_directory_star(BasePath, files))
266 winpr_DeleteFile(FilePath);
267 cleanup_layout(BasePath);
268 ArrayList_Free(files);
272WINPR_ATTR_FORMAT_ARG(1, 0)
273static
int printf1W(const
char* WINPR_FORMAT_ARG fmt, const WCHAR* arg1)
275 char* var1 = ConvertWCharToUtf8Alloc(arg1, NULL);
276 const int rc = printf(fmt, var1);
281WINPR_ATTR_FORMAT_ARG(1, 0)
282static
int printf2W(const
char* WINPR_FORMAT_ARG fmt, const WCHAR* arg1, const WCHAR* arg2)
284 char* var1 = ConvertWCharToUtf8Alloc(arg1, NULL);
285 char* var2 = ConvertWCharToUtf8Alloc(arg2, NULL);
286 const int rc = printf(fmt, var1, var2);
292static int TestFileFindFirstFileW(
const char* str)
294 WCHAR buffer[32] = { 0 };
295 const WCHAR* testFile1W = InitializeConstWCharFromUtf8(
"TestFile1W", buffer, ARRAYSIZE(buffer));
300 WCHAR BasePath[PATHCCH_MAX_CCH] = { 0 };
302 printf(
"[%s] basepath: '%s'\n", __func__, str);
303 (void)ConvertUtf8ToWChar(str, BasePath, ARRAYSIZE(BasePath));
305 const size_t length = _wcsnlen(BasePath, PATHCCH_MAX_CCH - 1);
307 WCHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
308 CopyMemory(FilePath, BasePath, length *
sizeof(WCHAR));
310 PathCchConvertStyleW(BasePath, length, PATH_STYLE_WINDOWS);
311 NativePathCchAppendW(FilePath, PATHCCH_MAX_CCH, testFile1W);
313 HANDLE hFind = INVALID_HANDLE_VALUE;
314 if (!create_fileW(FilePath))
317 printf1W(
"Finding file: %s\n", FilePath);
320 hFind = FindFirstFileW(FilePath, &FindData);
322 if (hFind == INVALID_HANDLE_VALUE)
324 printf1W(
"FindFirstFile failure: %s (INVALID_HANDLE_VALUE -1)\n", FilePath);
328 printf1W(
"FindFirstFile: %s\n", FindData.cFileName);
330 if (_wcscmp(FindData.cFileName, testFile1W) != 0)
332 printf2W(
"FindFirstFile failure: Expected: %s, Actual: %s\n", testFile1W,
339 DeleteFileW(FilePath);
344int TestFileFindFirstFile(
int argc,
char* argv[])
346 char* str = GetKnownSubPath(KNOWN_PATH_TEMP,
"TestFileFindFirstFile");
354 if (winpr_PathMakePath(str, NULL))
356 rc1 = TestFileFindFirstFileA(str);
357 rc2 = TestFileFindFirstFileW(str);
358 winpr_RemoveDirectory(str);
This struct contains function pointer to initialize/free objects.