mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-21 04:33:56 +00:00
Improvements to NtQueryDirectoryFileEx
This commit is contained in:
@@ -41,9 +41,7 @@ namespace utils
|
||||
|
||||
bool operator()(const std::string_view lhs, const std::string_view rhs) const
|
||||
{
|
||||
return std::ranges::equal(lhs, rhs, [](const char c1, const char c2) {
|
||||
return string::char_to_lower(c1) == string::char_to_lower(c2);
|
||||
});
|
||||
return string::equals_ignore_case(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -149,4 +149,20 @@ namespace utils::string
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
template <class Elem, class Traits, class Alloc>
|
||||
bool equals_ignore_case(const std::basic_string<Elem, Traits, Alloc>& lhs,
|
||||
const std::basic_string<Elem, Traits, Alloc>& rhs)
|
||||
{
|
||||
return std::ranges::equal(lhs, rhs,
|
||||
[](const auto c1, const auto c2) { return char_to_lower(c1) == char_to_lower(c2); });
|
||||
}
|
||||
|
||||
template <class Elem, class Traits>
|
||||
bool equals_ignore_case(const std::basic_string_view<Elem, Traits>& lhs,
|
||||
const std::basic_string_view<Elem, Traits>& rhs)
|
||||
{
|
||||
return std::ranges::equal(lhs, rhs,
|
||||
[](const auto c1, const auto c2) { return char_to_lower(c1) == char_to_lower(c2); });
|
||||
}
|
||||
}
|
||||
|
||||
99
src/common/utils/wildcard.hpp
Normal file
99
src/common/utils/wildcard.hpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace utils::wildcard
|
||||
{
|
||||
inline bool is_wildcard(char16_t c)
|
||||
{
|
||||
return c == '*' || c == '?' || c == '>' || c == '<' || c == '\"';
|
||||
}
|
||||
|
||||
inline bool has_wildcard(const std::u16string_view mask)
|
||||
{
|
||||
return std::ranges::any_of(mask, is_wildcard);
|
||||
}
|
||||
|
||||
inline bool match_filename(std::u16string_view name, std::u16string_view mask)
|
||||
{
|
||||
if (mask.empty() || mask == u"*" || mask == u"*.*")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t name_pos = 0;
|
||||
size_t mask_pos = 0;
|
||||
|
||||
size_t star_mask_pos = std::u16string_view::npos;
|
||||
size_t star_name_pos = 0;
|
||||
|
||||
while (name_pos < name.size())
|
||||
{
|
||||
if (mask_pos < mask.size())
|
||||
{
|
||||
char16_t mask_char = mask[mask_pos];
|
||||
char16_t name_char = name[name_pos];
|
||||
|
||||
bool char_matches;
|
||||
if (mask_char == u'?' || mask_char == u'>')
|
||||
{
|
||||
char_matches = true;
|
||||
}
|
||||
else if (mask_char == u'"')
|
||||
{
|
||||
char_matches = name_char == u'.';
|
||||
}
|
||||
else
|
||||
{
|
||||
char_matches = string::char_to_lower(name_char) == string::char_to_lower(mask_char);
|
||||
}
|
||||
|
||||
// Advance if current characters match
|
||||
if (char_matches)
|
||||
{
|
||||
name_pos++;
|
||||
mask_pos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this is a wildcard, skip all consecutive wildcards and save position for backtracking
|
||||
if (mask[mask_pos] == u'*' || mask[mask_pos] == u'<')
|
||||
{
|
||||
mask_pos++;
|
||||
while (mask_pos < mask.size() && (mask[mask_pos] == u'*' || mask[mask_pos] == u'<'))
|
||||
{
|
||||
mask_pos++;
|
||||
}
|
||||
|
||||
if (mask_pos == mask.size())
|
||||
{
|
||||
// There is no need to continue because all that remained were star masks.
|
||||
return true;
|
||||
}
|
||||
|
||||
star_mask_pos = mask_pos;
|
||||
star_name_pos = name_pos;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// The current characters didn't match...
|
||||
// If we had a wildcard earlier, backtrack to it and try to match at the next position
|
||||
if (star_mask_pos != std::u16string_view::npos)
|
||||
{
|
||||
mask_pos = star_mask_pos;
|
||||
name_pos = ++star_name_pos;
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip any remaining wildcards in the mask
|
||||
while (mask_pos < mask.size() && (mask[mask_pos] == u'*' || mask[mask_pos] == u'<'))
|
||||
{
|
||||
mask_pos++;
|
||||
}
|
||||
|
||||
return mask_pos == mask.size();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user