4 #include <winpr/handle.h>
5 #include <winpr/file.h>
6 #include <winpr/path.h>
7 #include <winpr/tchar.h>
8 #include <winpr/collections.h>
9 #include <winpr/windows.h>
11 static const CHAR testFile1A[] =
"TestFile1A";
13 static BOOL create_layout_files(
size_t level,
const char* BasePath, wArrayList* files)
15 for (
size_t x = 0; x < 10; x++)
17 CHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
18 strncpy(FilePath, BasePath, ARRAYSIZE(FilePath));
20 CHAR name[64] = { 0 };
21 (void)_snprintf(name, ARRAYSIZE(name),
"%zd-TestFile%zd", level, x);
22 NativePathCchAppendA(FilePath, PATHCCH_MAX_CCH, name);
25 CreateFileA(FilePath, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
26 if (hdl == INVALID_HANDLE_VALUE)
28 ArrayList_Append(files, FilePath);
29 (void)CloseHandle(hdl);
34 static BOOL create_layout_directories(
size_t level,
size_t max_level,
const char* BasePath,
37 if (level >= max_level)
40 CHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
41 strncpy(FilePath, BasePath, ARRAYSIZE(FilePath));
42 PathCchConvertStyleA(FilePath, ARRAYSIZE(FilePath), PATH_STYLE_NATIVE);
43 if (!winpr_PathMakePath(FilePath, NULL))
45 ArrayList_Append(files, FilePath);
47 if (!create_layout_files(level + 1, BasePath, files))
50 for (
size_t x = 0; x < 10; x++)
52 CHAR CurFilePath[PATHCCH_MAX_CCH] = { 0 };
53 strncpy(CurFilePath, FilePath, ARRAYSIZE(CurFilePath));
55 PathCchConvertStyleA(CurFilePath, ARRAYSIZE(CurFilePath), PATH_STYLE_NATIVE);
57 CHAR name[64] = { 0 };
58 (void)_snprintf(name, ARRAYSIZE(name),
"%zd-TestPath%zd", level, x);
59 NativePathCchAppendA(CurFilePath, PATHCCH_MAX_CCH, name);
61 if (!create_layout_directories(level + 1, max_level, CurFilePath, files))
67 static BOOL create_layout(
const char* BasePath, wArrayList* files)
69 CHAR BasePathNative[PATHCCH_MAX_CCH] = { 0 };
70 memcpy(BasePathNative, BasePath,
sizeof(BasePathNative));
71 PathCchConvertStyleA(BasePathNative, ARRAYSIZE(BasePathNative), PATH_STYLE_NATIVE);
73 return create_layout_directories(0, 3, BasePathNative, files);
76 static void cleanup_layout(
const char* BasePath)
78 winpr_RemoveDirectory_RecursiveA(BasePath);
81 static BOOL find_first_file_success(
const char* FilePath)
85 HANDLE hFind = FindFirstFileA(FilePath, &FindData);
86 if (hFind == INVALID_HANDLE_VALUE)
88 printf(
"FindFirstFile failure: %s (INVALID_HANDLE_VALUE -1)\n", FilePath);
92 printf(
"FindFirstFile: %s", FindData.cFileName);
94 if (strcmp(FindData.cFileName, testFile1A) != 0)
96 printf(
"FindFirstFile failure: Expected: %s, Actual: %s\n", testFile1A, FindData.cFileName);
101 if (hFind != INVALID_HANDLE_VALUE)
106 static BOOL list_directory_dot(
const char* BasePath, wArrayList* files)
109 CHAR BasePathDot[PATHCCH_MAX_CCH] = { 0 };
110 memcpy(BasePathDot, BasePath, ARRAYSIZE(BasePathDot));
111 PathCchConvertStyleA(BasePathDot, ARRAYSIZE(BasePathDot), PATH_STYLE_NATIVE);
112 NativePathCchAppendA(BasePathDot, PATHCCH_MAX_CCH,
".");
114 HANDLE hFind = FindFirstFileA(BasePathDot, &FindData);
115 if (hFind == INVALID_HANDLE_VALUE)
121 if (strcmp(FindData.cFileName,
".") != 0)
123 }
while (FindNextFile(hFind, &FindData));
134 static BOOL list_directory_star(
const char* BasePath, wArrayList* files)
136 CHAR BasePathDot[PATHCCH_MAX_CCH] = { 0 };
137 memcpy(BasePathDot, BasePath, ARRAYSIZE(BasePathDot));
138 PathCchConvertStyleA(BasePathDot, ARRAYSIZE(BasePathDot), PATH_STYLE_NATIVE);
139 NativePathCchAppendA(BasePathDot, PATHCCH_MAX_CCH,
"*");
141 HANDLE hFind = FindFirstFileA(BasePathDot, &FindData);
142 if (hFind == INVALID_HANDLE_VALUE)
146 size_t dotdotcount = 0;
149 if (strcmp(FindData.cFileName,
".") == 0)
151 else if (strcmp(FindData.cFileName,
"..") == 0)
155 }
while (FindNextFile(hFind, &FindData));
158 const char sep = PathGetSeparatorA(PATH_STYLE_NATIVE);
160 const size_t baselen = strlen(BasePath);
161 const size_t total = ArrayList_Count(files);
162 for (
size_t x = 0; x < total; x++)
164 const char* path = ArrayList_GetItem(files, x);
165 const size_t pathlen = strlen(path);
166 if (pathlen < baselen)
168 const char* skip = &path[baselen];
171 const char* end = strrchr(skip, sep);
182 static BOOL find_first_file_fail(
const char* FilePath)
185 HANDLE hFind = FindFirstFileA(FilePath, &FindData);
186 if (hFind == INVALID_HANDLE_VALUE)
193 static int TestFileFindFirstFileA(
const char* str)
199 CHAR BasePath[PATHCCH_MAX_CCH] = { 0 };
201 strncpy(BasePath, str, ARRAYSIZE(BasePath));
203 const size_t length = strnlen(BasePath, PATHCCH_MAX_CCH - 1);
205 CHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
206 CopyMemory(FilePath, BasePath, length *
sizeof(CHAR));
208 PathCchConvertStyleA(BasePath, length, PATH_STYLE_WINDOWS);
210 wArrayList* files = ArrayList_New(FALSE);
213 wObject* obj = ArrayList_Object(files);
214 obj->fnObjectFree = winpr_ObjectStringFree;
215 obj->fnObjectNew = winpr_ObjectStringClone;
217 if (!create_layout(BasePath, files))
220 NativePathCchAppendA(FilePath, PATHCCH_MAX_CCH, testFile1A);
222 printf(
"Finding file: %s\n", FilePath);
224 if (!find_first_file_fail(FilePath))
228 CreateFileA(FilePath, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
229 if (hdl == INVALID_HANDLE_VALUE)
231 (void)CloseHandle(hdl);
233 if (!find_first_file_success(FilePath))
236 CHAR BasePathInvalid[PATHCCH_MAX_CCH] = { 0 };
237 memcpy(BasePathInvalid, BasePath, ARRAYSIZE(BasePathInvalid));
238 PathCchAddBackslashA(BasePathInvalid, PATHCCH_MAX_CCH);
240 if (!find_first_file_fail(BasePathInvalid))
243 if (!list_directory_dot(BasePath, files))
246 if (!list_directory_star(BasePath, files))
251 DeleteFileA(FilePath);
252 cleanup_layout(BasePath);
253 ArrayList_Free(files);
257 static int TestFileFindFirstFileW(
const char* str)
259 WCHAR buffer[32] = { 0 };
260 const WCHAR* testFile1W = InitializeConstWCharFromUtf8(
"TestFile1W", buffer, ARRAYSIZE(buffer));
265 WCHAR BasePath[PATHCCH_MAX_CCH] = { 0 };
267 (void)ConvertUtf8ToWChar(str, BasePath, ARRAYSIZE(BasePath));
269 const size_t length = _wcsnlen(BasePath, PATHCCH_MAX_CCH - 1);
271 WCHAR FilePath[PATHCCH_MAX_CCH] = { 0 };
272 CopyMemory(FilePath, BasePath, length *
sizeof(WCHAR));
274 PathCchConvertStyleW(BasePath, length, PATH_STYLE_WINDOWS);
275 NativePathCchAppendW(FilePath, PATHCCH_MAX_CCH, testFile1W);
277 CHAR FilePathA[PATHCCH_MAX_CCH] = { 0 };
278 (void)ConvertWCharNToUtf8(FilePath, ARRAYSIZE(FilePath), FilePathA, ARRAYSIZE(FilePathA));
279 printf(
"Finding file: %s\n", FilePathA);
282 HANDLE hFind = FindFirstFileW(FilePath, &FindData);
284 if (hFind == INVALID_HANDLE_VALUE)
286 printf(
"FindFirstFile failure: %s (INVALID_HANDLE_VALUE -1)\n", FilePathA);
290 CHAR cFileName[MAX_PATH] = { 0 };
291 (void)ConvertWCharNToUtf8(FindData.cFileName, ARRAYSIZE(FindData.cFileName), cFileName,
292 ARRAYSIZE(cFileName));
294 printf(
"FindFirstFile: %s", cFileName);
296 if (_wcscmp(FindData.cFileName, testFile1W) != 0)
298 printf(
"FindFirstFile failure: Expected: %s, Actual: %s\n", testFile1A, cFileName);
304 DeleteFileW(FilePath);
309 int TestFileFindFirstFile(
int argc,
char* argv[])
311 char* str = GetKnownSubPath(KNOWN_PATH_TEMP,
"TestFileFindFirstFile");
319 if (winpr_PathMakePath(str, NULL))
321 rc1 = TestFileFindFirstFileA(str);
323 winpr_RemoveDirectory(str);
This struct contains function pointer to initialize/free objects.