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))
254 if (lpPattern[0] ==
'*')
256 lpTail = &lpPattern[1];
257 cchTail = strlen(lpTail);
259 if (!FilePatternFindNextWildcardA(lpTail, &dwFlags))
262 if (cchFileName < cchTail)
265 if (_stricmp(&lpFileName[cchFileName - cchTail], lpTail) == 0)
305 LPCSTR lpWildcard = FilePatternFindNextWildcardA(lpPattern, &dwFlags);
309 LPCSTR lpMatchEnd =
nullptr;
310 size_t cchNextWildcard = 0;
311 const size_t cchSubPattern = cchPattern;
312 LPCSTR lpSubPattern = lpPattern;
313 size_t cchSubFileName = cchFileName;
314 LPCSTR lpSubFileName = lpFileName;
315 size_t cchWildcard = ((dwFlags & WILDCARD_DOS) ? 2 : 1);
316 LPCSTR lpNextWildcard =
317 FilePatternFindNextWildcardA(&lpWildcard[cchWildcard], &dwNextFlags);
321 LPCSTR lpX = lpSubPattern;
323 if (lpWildcard < lpSubPattern)
325 const size_t cchX = WINPR_ASSERTING_INT_CAST(
size_t, (lpWildcard - lpSubPattern));
326 LPCSTR lpY = &lpSubPattern[cchX + cchWildcard];
328 if (lpY < lpSubPattern)
330 const size_t lpYSSubPattern = WINPR_ASSERTING_INT_CAST(
size_t, (lpY - lpSubPattern));
332 if (cchSubPattern < lpYSSubPattern)
334 const size_t cchY = cchSubPattern - lpYSSubPattern;
336 return FilePatternMatchSubExpressionA(lpSubFileName, cchSubFileName, lpX, cchX, lpY,
337 cchY, lpWildcard, &lpMatchEnd);
341 while (lpNextWildcard)
343 if (lpSubFileName < lpFileName)
347 cchFileName - WINPR_ASSERTING_INT_CAST(
size_t, (lpSubFileName - lpFileName));
348 cchNextWildcard = ((dwNextFlags & WILDCARD_DOS) ? 2 : 1);
349 LPCSTR lpX = lpSubPattern;
351 if (lpWildcard < lpSubPattern)
353 const size_t cchX = WINPR_ASSERTING_INT_CAST(
size_t, (lpWildcard - lpSubPattern));
354 LPCSTR lpY = &lpSubPattern[cchX + cchWildcard];
356 if (lpNextWildcard < lpWildcard)
359 const size_t diff = WINPR_ASSERTING_INT_CAST(
size_t, (lpNextWildcard - lpWildcard));
360 if (diff < cchWildcard)
363 const size_t cchY = diff - cchWildcard;
364 match = FilePatternMatchSubExpressionA(lpSubFileName, cchSubFileName, lpX, cchX,
365 lpY, cchY, lpWildcard, &lpMatchEnd);
370 lpSubFileName = lpMatchEnd;
371 cchWildcard = cchNextWildcard;
372 lpWildcard = lpNextWildcard;
373 dwFlags = dwNextFlags;
375 FilePatternFindNextWildcardA(&lpWildcard[cchWildcard], &dwNextFlags);
384 if (_stricmp(lpFileName, lpPattern) == 0)