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 LPSTR lpWildcard =
nullptr;
47 lpWildcard = strpbrk(lpPattern,
"*?~");
51 if (*lpWildcard ==
'*')
53 *pFlags = WILDCARD_STAR;
56 else if (*lpWildcard ==
'?')
58 *pFlags = WILDCARD_QM;
61 else if (*lpWildcard ==
'~')
63 if (lpWildcard[1] ==
'*')
65 *pFlags = WILDCARD_DOS_STAR;
68 else if (lpWildcard[1] ==
'?')
70 *pFlags = WILDCARD_DOS_QM;
73 else if (lpWildcard[1] ==
'.')
75 *pFlags = WILDCARD_DOS_DOT;
84static BOOL FilePatternMatchSubExpressionA(LPCSTR lpFileName,
size_t cchFileName, LPCSTR lpX,
85 size_t cchX, LPCSTR lpY,
size_t cchY, LPCSTR lpWildcard,
88 LPCSTR lpMatch =
nullptr;
93 if (*lpWildcard ==
'*')
105 if (_strnicmp(lpFileName, lpX, cchX) != 0)
121 lpMatch = strchr(&lpFileName[cchX], *lpY);
126 if (_strnicmp(lpMatch, lpY, cchY) != 0)
131 lpMatch = &lpFileName[cchFileName];
137 *ppMatchEnd = &lpMatch[cchY];
140 else if (*lpWildcard ==
'?')
155 if (cchFileName < cchX + 1)
158 if (_strnicmp(lpFileName, lpX, cchX) != 0)
172 lpMatch = strchr(&lpFileName[cchX + 1], *lpY);
177 if (_strnicmp(lpMatch, lpY, cchY) != 0)
182 lpMatch = &lpFileName[cchX + 1];
188 *ppMatchEnd = &lpMatch[cchY];
191 else if (*lpWildcard ==
'~')
193 WLog_ERR(TAG,
"warning: unimplemented '~' pattern match");
200BOOL FilePatternMatchA(LPCSTR lpFileName, LPCSTR lpPattern)
203 LPCSTR lpTail =
nullptr;
206 DWORD dwNextFlags = 0;
228 const size_t cchPattern = strlen(lpPattern);
229 const size_t cchFileName = strlen(lpFileName);
238 if ((lpPattern[0] ==
'*') && (cchPattern == 1))
251 if (lpPattern[0] ==
'*')
253 lpTail = &lpPattern[1];
254 cchTail = strlen(lpTail);
256 if (!FilePatternFindNextWildcardA(lpTail, &dwFlags))
259 if (cchFileName < cchTail)
262 if (_stricmp(&lpFileName[cchFileName - cchTail], lpTail) == 0)
302 LPCSTR lpWildcard = FilePatternFindNextWildcardA(lpPattern, &dwFlags);
306 LPCSTR lpMatchEnd =
nullptr;
307 size_t cchNextWildcard = 0;
308 const size_t cchSubPattern = cchPattern;
309 LPCSTR lpSubPattern = lpPattern;
310 size_t cchSubFileName = cchFileName;
311 LPCSTR lpSubFileName = lpFileName;
312 size_t cchWildcard = ((dwFlags & WILDCARD_DOS) ? 2 : 1);
313 LPCSTR lpNextWildcard =
314 FilePatternFindNextWildcardA(&lpWildcard[cchWildcard], &dwNextFlags);
318 LPCSTR lpX = lpSubPattern;
320 if (lpWildcard < lpSubPattern)
322 const size_t cchX = WINPR_ASSERTING_INT_CAST(
size_t, (lpWildcard - lpSubPattern));
323 LPCSTR lpY = &lpSubPattern[cchX + cchWildcard];
325 if (lpY < lpSubPattern)
327 const size_t lpYSSubPattern = WINPR_ASSERTING_INT_CAST(
size_t, (lpY - lpSubPattern));
329 if (cchSubPattern < lpYSSubPattern)
331 const size_t cchY = cchSubPattern - lpYSSubPattern;
333 return FilePatternMatchSubExpressionA(lpSubFileName, cchSubFileName, lpX, cchX, lpY,
334 cchY, lpWildcard, &lpMatchEnd);
338 while (lpNextWildcard)
340 if (lpSubFileName < lpFileName)
344 cchFileName - WINPR_ASSERTING_INT_CAST(
size_t, (lpSubFileName - lpFileName));
345 cchNextWildcard = ((dwNextFlags & WILDCARD_DOS) ? 2 : 1);
346 LPCSTR lpX = lpSubPattern;
348 if (lpWildcard < lpSubPattern)
350 const size_t cchX = WINPR_ASSERTING_INT_CAST(
size_t, (lpWildcard - lpSubPattern));
351 LPCSTR lpY = &lpSubPattern[cchX + cchWildcard];
353 if (lpNextWildcard < lpWildcard)
356 const size_t diff = WINPR_ASSERTING_INT_CAST(
size_t, (lpNextWildcard - lpWildcard));
357 if (diff < cchWildcard)
360 const size_t cchY = diff - cchWildcard;
361 match = FilePatternMatchSubExpressionA(lpSubFileName, cchSubFileName, lpX, cchX,
362 lpY, cchY, lpWildcard, &lpMatchEnd);
367 lpSubFileName = lpMatchEnd;
368 cchWildcard = cchNextWildcard;
369 lpWildcard = lpNextWildcard;
370 dwFlags = dwNextFlags;
372 FilePatternFindNextWildcardA(&lpWildcard[cchWildcard], &dwNextFlags);
381 if (_stricmp(lpFileName, lpPattern) == 0)