ntdll: Correct filename-pattern behaviour
Costas Christofi
christofi.cos at gmail.com
Thu Jan 5 04:42:36 CST 2012
Small fix for match_filename() in /dll/ntdll/directory.c, so the
matching complies with Windows behaviour.
This lets us match cases such as "foo123 -> *?" and "foo123 ->
f*??*?3". In the current version of Wine, both of these will
incorrectly return false, even though the patterns should normally
match (and do match under Windows).
Note that this patch provides a generic solution for the bug
identified in this thread on the MGE forums:
http://sourceforge.net/projects/morrgraphext/forums/forum/866295/topic/3832169
Costas
-------------- next part --------------
From 965a22c1f51ff47650df65b17f0a86913d4d14e2 Mon Sep 17 00:00:00 2001
From: Costas Christofi <christofi.cos at gmail.com>
Date: Thu, 5 Jan 2012 10:52:06 +0200
Subject: match_filename() now able to handle patterns of types
"foo123 -> *?" and "foo123 -> f*??*?3",
which are used in some Windows applications.
---
dlls/ntdll/directory.c | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 65c8b8f..3fba4b7 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1170,6 +1170,7 @@ static ULONG hash_short_file_name( const UNICODE_STRING *name, LPWSTR buffer )
static BOOLEAN match_filename( const UNICODE_STRING *name_str, const UNICODE_STRING *mask_str )
{
int mismatch;
+ int symnum, charnum;
const WCHAR *name = name_str->Buffer;
const WCHAR *mask = mask_str->Buffer;
const WCHAR *name_end = name + name_str->Length / sizeof(WCHAR);
@@ -1189,11 +1190,23 @@ static BOOLEAN match_filename( const UNICODE_STRING *name_str, const UNICODE_STR
if (mask == mask_end) return TRUE; /* end of mask is all '*', so match */
lastjoker = mask;
- /* skip to the next match after the joker(s) */
+ /* skip a sequence of mixed '?'s and '*'s, but keep count of the '?'s */
+ symnum = 0, charnum = 0;
+ while (mask < mask_end && (*mask == '?' || *mask == '*'))
+ {
+ if (*mask == '?') symnum++;
+ mask++;
+ }
+
+ /* skip to the next match after the joker(s), and count chars skipped */
if (is_case_sensitive)
- while (name < name_end && (*name != *mask)) name++;
+ while (name < name_end && (*name != *mask)) { name++; charnum++; }
else
- while (name < name_end && (toupperW(*name) != toupperW(*mask))) name++;
+ while (name < name_end && (toupperW(*name) != toupperW(*mask))) { name++; charnum++; }
+
+ /* ensure that enough chars were skipped to satisfy the '?'s */
+ if (symnum > charnum) return FALSE;
+
next_to_retry = name;
break;
case '?':
--
1.7.4.1
More information about the wine-patches
mailing list