20#include <winpr/config.h>
23#include <winpr/handle.h>
25#include <winpr/file.h>
27#ifdef WINPR_HAVE_UNISTD_H
31#ifdef WINPR_HAVE_FCNTL_H
36#define TAG WINPR_TAG("file")
43LPSTR FilePatternFindNextWildcardA(LPCSTR lpPattern, DWORD* pFlags)
45 WINPR_ASSERT(lpPattern);
50 char* lpWildcard = strpbrk(lpPattern,
"*?~");
54 if (*lpWildcard ==
'*')
56 *pFlags = WILDCARD_STAR;
59 else if (*lpWildcard ==
'?')
61 *pFlags = WILDCARD_QM;
64 else if (*lpWildcard ==
'~')
66 if (lpWildcard[1] ==
'*')
68 *pFlags = WILDCARD_DOS_STAR;
71 else if (lpWildcard[1] ==
'?')
73 *pFlags = WILDCARD_DOS_QM;
76 else if (lpWildcard[1] ==
'.')
78 *pFlags = WILDCARD_DOS_DOT;
87static BOOL FilePatternMatchSubExpressionA(LPCSTR lpFileName,
size_t cchFileName, LPCSTR lpX,
88 size_t cchX, LPCSTR lpY,
size_t cchY, LPCSTR lpWildcard,
91 LPCSTR lpMatch =
nullptr;
96 if (*lpWildcard ==
'*')
108 if (_strnicmp(lpFileName, lpX, cchX) != 0)
124 lpMatch = strchr(&lpFileName[cchX], *lpY);
129 if (_strnicmp(lpMatch, lpY, cchY) != 0)
134 lpMatch = &lpFileName[cchFileName];
140 *ppMatchEnd = &lpMatch[cchY];
143 else if (*lpWildcard ==
'?')
158 if (cchFileName < cchX + 1)
161 if (_strnicmp(lpFileName, lpX, cchX) != 0)
175 lpMatch = strchr(&lpFileName[cchX + 1], *lpY);
180 if (_strnicmp(lpMatch, lpY, cchY) != 0)
185 lpMatch = &lpFileName[cchX + 1];
191 *ppMatchEnd = &lpMatch[cchY];
194 else if (*lpWildcard ==
'~')
196 WLog_ERR(TAG,
"warning: unimplemented '~' pattern match");
203BOOL FilePatternMatchA(LPCSTR lpFileName, LPCSTR lpPattern)
206 LPCSTR lpTail =
nullptr;
209 DWORD dwNextFlags = 0;
231 const size_t cchPattern = strlen(lpPattern);
232 const size_t cchFileName = strlen(lpFileName);
241 if ((lpPattern[0] ==
'*') && (cchPattern == 1))
249 if ((cchPattern == 3) && (strcmp(lpPattern,
"*.*") == 0))
262 if (lpPattern[0] ==
'*')
264 lpTail = &lpPattern[1];
265 cchTail = strlen(lpTail);
267 if (!FilePatternFindNextWildcardA(lpTail, &dwFlags))
270 if (cchFileName < cchTail)
273 if (_stricmp(&lpFileName[cchFileName - cchTail], lpTail) == 0)
313 LPCSTR lpWildcard = FilePatternFindNextWildcardA(lpPattern, &dwFlags);
317 LPCSTR lpMatchEnd =
nullptr;
318 size_t cchNextWildcard = 0;
319 const size_t cchSubPattern = cchPattern;
320 LPCSTR lpSubPattern = lpPattern;
321 size_t cchSubFileName = cchFileName;
322 LPCSTR lpSubFileName = lpFileName;
323 size_t cchWildcard = ((dwFlags & WILDCARD_DOS) ? 2 : 1);
324 LPCSTR lpNextWildcard =
325 FilePatternFindNextWildcardA(&lpWildcard[cchWildcard], &dwNextFlags);
329 LPCSTR lpX = lpSubPattern;
331 if (lpWildcard < lpSubPattern)
333 const size_t cchX = WINPR_ASSERTING_INT_CAST(
size_t, (lpWildcard - lpSubPattern));
334 LPCSTR lpY = &lpSubPattern[cchX + cchWildcard];
336 if (lpY < lpSubPattern)
338 const size_t lpYSSubPattern = WINPR_ASSERTING_INT_CAST(
size_t, (lpY - lpSubPattern));
340 if (cchSubPattern < lpYSSubPattern)
342 const size_t cchY = cchSubPattern - lpYSSubPattern;
344 return FilePatternMatchSubExpressionA(lpSubFileName, cchSubFileName, lpX, cchX, lpY,
345 cchY, lpWildcard, &lpMatchEnd);
349 while (lpNextWildcard)
351 if (lpSubFileName < lpFileName)
355 cchFileName - WINPR_ASSERTING_INT_CAST(
size_t, (lpSubFileName - lpFileName));
356 cchNextWildcard = ((dwNextFlags & WILDCARD_DOS) ? 2 : 1);
357 LPCSTR lpX = lpSubPattern;
359 if (lpWildcard < lpSubPattern)
361 const size_t cchX = WINPR_ASSERTING_INT_CAST(
size_t, (lpWildcard - lpSubPattern));
362 LPCSTR lpY = &lpSubPattern[cchX + cchWildcard];
364 if (lpNextWildcard < lpWildcard)
367 const size_t diff = WINPR_ASSERTING_INT_CAST(
size_t, (lpNextWildcard - lpWildcard));
368 if (diff < cchWildcard)
371 const size_t cchY = diff - cchWildcard;
372 match = FilePatternMatchSubExpressionA(lpSubFileName, cchSubFileName, lpX, cchX,
373 lpY, cchY, lpWildcard, &lpMatchEnd);
378 lpSubFileName = lpMatchEnd;
379 cchWildcard = cchNextWildcard;
380 lpWildcard = lpNextWildcard;
381 dwFlags = dwNextFlags;
383 FilePatternFindNextWildcardA(&lpWildcard[cchWildcard], &dwNextFlags);
392 if (_stricmp(lpFileName, lpPattern) == 0)