mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
sys: FspCompareUnicodeString
This commit is contained in:
parent
09ab9de32c
commit
69257949ac
@ -566,7 +566,7 @@ BOOLEAN FspFileNameIsPrefix(
|
|||||||
#else
|
#else
|
||||||
#define FspFileNameUpcase(D,S,U) (ASSERT(0 == (U)), RtlUpcaseUnicodeString(D,S,FALSE))
|
#define FspFileNameUpcase(D,S,U) (ASSERT(0 == (U)), RtlUpcaseUnicodeString(D,S,FALSE))
|
||||||
#define FspEaNameUpcase(D,S,U) (ASSERT(0 == (U)), RtlUpperString(D,S))
|
#define FspEaNameUpcase(D,S,U) (ASSERT(0 == (U)), RtlUpperString(D,S))
|
||||||
#define FspFileNameCompare(N1,N2,I,U) (ASSERT(0 == (U)), RtlCompareUnicodeString(N1,N2,I))
|
#define FspFileNameCompare(N1,N2,I,U) (ASSERT(0 == (U)), FspCompareUnicodeString(N1,N2,I))
|
||||||
#define FspFileNameIsPrefix(N1,N2,I,U) (ASSERT(0 == (U)), RtlPrefixUnicodeString(N1,N2,I))
|
#define FspFileNameIsPrefix(N1,N2,I,U) (ASSERT(0 == (U)), RtlPrefixUnicodeString(N1,N2,I))
|
||||||
#endif
|
#endif
|
||||||
NTSTATUS FspFileNameInExpression(
|
NTSTATUS FspFileNameInExpression(
|
||||||
@ -733,6 +733,12 @@ VOID FspIrpHookReset(PIRP Irp);
|
|||||||
PVOID FspIrpHookContext(PVOID Context);
|
PVOID FspIrpHookContext(PVOID Context);
|
||||||
NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
|
NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
|
||||||
|
|
||||||
|
/* utility: string compare */
|
||||||
|
LONG FspCompareUnicodeString(
|
||||||
|
PCUNICODE_STRING String1,
|
||||||
|
PCUNICODE_STRING String2,
|
||||||
|
BOOLEAN CaseInsensitive);
|
||||||
|
|
||||||
/* silos */
|
/* silos */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -131,6 +131,10 @@ NTSTATUS FspIrpHook(PIRP Irp, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID Ow
|
|||||||
VOID FspIrpHookReset(PIRP Irp);
|
VOID FspIrpHookReset(PIRP Irp);
|
||||||
PVOID FspIrpHookContext(PVOID Context);
|
PVOID FspIrpHookContext(PVOID Context);
|
||||||
NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
|
NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
|
||||||
|
LONG FspCompareUnicodeString(
|
||||||
|
PCUNICODE_STRING String1,
|
||||||
|
PCUNICODE_STRING String2,
|
||||||
|
BOOLEAN CaseInsensitive);
|
||||||
|
|
||||||
#ifdef ALLOC_PRAGMA
|
#ifdef ALLOC_PRAGMA
|
||||||
#pragma alloc_text(PAGE, FspIsNtDdiVersionAvailable)
|
#pragma alloc_text(PAGE, FspIsNtDdiVersionAvailable)
|
||||||
@ -174,6 +178,7 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
|
|||||||
#pragma alloc_text(PAGE, FspSafeMdlDelete)
|
#pragma alloc_text(PAGE, FspSafeMdlDelete)
|
||||||
#pragma alloc_text(PAGE, FspIrpHook)
|
#pragma alloc_text(PAGE, FspIrpHook)
|
||||||
#pragma alloc_text(PAGE, FspIrpHookReset)
|
#pragma alloc_text(PAGE, FspIrpHookReset)
|
||||||
|
#pragma alloc_text(PAGE, FspCompareUnicodeString)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const LONG Delays[] =
|
static const LONG Delays[] =
|
||||||
@ -1493,3 +1498,82 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
|
|||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
USHORT FspUpcaseAscii(USHORT c)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Bit-twiddling upper case char:
|
||||||
|
*
|
||||||
|
* - Let signbit(x) = x & 0x100 (treat bit 0x100 as "signbit").
|
||||||
|
* - 'A' <= c && c <= 'Z' <=> s = signbit(c - 'A') ^ signbit(c - ('Z' + 1)) == 1
|
||||||
|
* - c >= 'A' <=> c - 'A' >= 0 <=> signbit(c - 'A') = 0
|
||||||
|
* - c <= 'Z' <=> c - ('Z' + 1) < 0 <=> signbit(c - ('Z' + 1)) = 1
|
||||||
|
* - Bit 0x20 = 0x100 >> 3 toggles uppercase to lowercase and vice-versa.
|
||||||
|
*
|
||||||
|
* This is actually faster than `(c - 'a' <= 'z' - 'a') ? (c & ~0x20) : c`, even
|
||||||
|
* when compiled using cmov conditional moves at least on this system (i7-1065G7).
|
||||||
|
*
|
||||||
|
* See https://godbolt.org/z/ebv131Wrh
|
||||||
|
*/
|
||||||
|
USHORT s = ((c - 'a') ^ (c - ('z' + 1))) & 0x100;
|
||||||
|
return c & ~(s >> 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
static
|
||||||
|
LONG FspCompareUnicodeStringReal(
|
||||||
|
PCUNICODE_STRING S1,
|
||||||
|
PCUNICODE_STRING S2,
|
||||||
|
BOOLEAN CaseInsensitive)
|
||||||
|
#else
|
||||||
|
LONG FspCompareUnicodeString(
|
||||||
|
PCUNICODE_STRING S1,
|
||||||
|
PCUNICODE_STRING S2,
|
||||||
|
BOOLEAN CaseInsensitive)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
LONG LResult = S1->Length - S2->Length;
|
||||||
|
PWCH P1 = S1->Buffer;
|
||||||
|
PWCH P2 = S2->Buffer;
|
||||||
|
PWCH EndP1 = P1 + (0 >= LResult ? S1->Length : S2->Length) / sizeof(WCHAR);
|
||||||
|
|
||||||
|
if (CaseInsensitive)
|
||||||
|
{
|
||||||
|
for (; EndP1 != P1; ++P1, ++P2)
|
||||||
|
{
|
||||||
|
USHORT C1 = *P1, C2 = *P2;
|
||||||
|
if (0xff80 & (C1 | C2))
|
||||||
|
return RtlCompareUnicodeString(S1, S2, TRUE);
|
||||||
|
C1 = FspUpcaseAscii(C1);
|
||||||
|
C2 = FspUpcaseAscii(C2);
|
||||||
|
if (C1 != C2)
|
||||||
|
return C1 - C2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; EndP1 != P1; ++P1, ++P2)
|
||||||
|
{
|
||||||
|
USHORT C1 = *P1, C2 = *P2;
|
||||||
|
if (C1 != C2)
|
||||||
|
return C1 - C2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return LResult;
|
||||||
|
}
|
||||||
|
#if DBG
|
||||||
|
LONG FspCompareUnicodeString(
|
||||||
|
PCUNICODE_STRING S1,
|
||||||
|
PCUNICODE_STRING S2,
|
||||||
|
BOOLEAN CaseInsensitive)
|
||||||
|
{
|
||||||
|
LONG Result0 = FspCompareUnicodeStringReal(S1, S2, CaseInsensitive);
|
||||||
|
LONG Result1 = RtlCompareUnicodeString(S1, S2, CaseInsensitive);
|
||||||
|
ASSERT((0 < Result0) - (0 > Result0) == (0 < Result1) - (0 > Result1));
|
||||||
|
return Result0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -30,25 +30,25 @@ pushd fsbench
|
|||||||
set OptFiles=1000 2000 3000 4000 5000
|
set OptFiles=1000 2000 3000 4000 5000
|
||||||
if X%2==Xbaseline set OptFiles=10000
|
if X%2==Xbaseline set OptFiles=10000
|
||||||
for %%a in (%OptFiles%) do (
|
for %%a in (%OptFiles%) do (
|
||||||
call :csv %%a "%fsbench% --empty-cache --files=%%a file_*"
|
call :csv %%a "%fsbench% --empty-cache=C --files=%%a file_*"
|
||||||
)
|
)
|
||||||
|
|
||||||
set OptRdwrCc=100 200 300 400 500
|
set OptRdwrCc=100 200 300 400 500
|
||||||
if X%2==Xbaseline set OptRdwrCc=1000
|
if X%2==Xbaseline set OptRdwrCc=1000
|
||||||
for %%a in (%OptRdwrCc%) do (
|
for %%a in (%OptRdwrCc%) do (
|
||||||
call :csv %%a "%fsbench% --empty-cache --rdwr-cc=%%a rdwr_cc_*"
|
call :csv %%a "%fsbench% --empty-cache=C --rdwr-cc=%%a rdwr_cc_*"
|
||||||
)
|
)
|
||||||
|
|
||||||
set OptRdwrNc=100 200 300 400 500
|
set OptRdwrNc=100 200 300 400 500
|
||||||
if X%2==Xbaseline set OptRdwrNc=100
|
if X%2==Xbaseline set OptRdwrNc=100
|
||||||
for %%a in (%OptRdwrNc%) do (
|
for %%a in (%OptRdwrNc%) do (
|
||||||
call :csv %%a "%fsbench% --empty-cache --rdwr-nc=%%a rdwr_nc_*"
|
call :csv %%a "%fsbench% --empty-cache=C --rdwr-nc=%%a rdwr_nc_*"
|
||||||
)
|
)
|
||||||
|
|
||||||
set OptMmap=100 200 300 400 500
|
set OptMmap=100 200 300 400 500
|
||||||
if X%2==Xbaseline set OptMmap=1000
|
if X%2==Xbaseline set OptMmap=1000
|
||||||
for %%a in (%OptMmap%) do (
|
for %%a in (%OptMmap%) do (
|
||||||
call :csv %%a "%fsbench% --empty-cache --mmap=%%a mmap_*"
|
call :csv %%a "%fsbench% --empty-cache=C --mmap=%%a mmap_*"
|
||||||
)
|
)
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
Loading…
x
Reference in New Issue
Block a user