The function is called a lot, I believe something like this would improve its performance in general.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/ntdll/unix/file.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 957d9f3b801..b1b09e80e5a 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -250,9 +250,12 @@ static pthread_mutex_t mnt_mutex = PTHREAD_MUTEX_INITIALIZER; /* check if a given Unicode char is OK in a DOS short name */ static inline BOOL is_invalid_dos_char( WCHAR ch ) { - static const WCHAR invalid_chars[] = { INVALID_DOS_CHARS,'~','.',0 }; - if (ch > 0x7f) return TRUE; - return wcschr( invalid_chars, ch ) != NULL; + static const char is_invalid[0x7f] = + { + ['*'] = 1, ['?'] = 1, ['<'] = 1, ['>'] = 1, ['|'] = 1, ['"'] = 1, ['+'] = 1, ['='] = 1, + [','] = 1, [';'] = 1, ['['] = 1, [']'] = 1, [' '] = 1, ['~'] = 1, ['.'] = 1, + }; + return ch <= 0x7f ? is_invalid[ch] : TRUE; }
/* check if the device can be a mounted volume */
From: Rémi Bernon rbernon@codeweavers.com
Instead of costly wcschr. --- dlls/ntdll/unix/file.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index b1b09e80e5a..097346b475d 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -258,6 +258,16 @@ static inline BOOL is_invalid_dos_char( WCHAR ch ) return ch <= 0x7f ? is_invalid[ch] : TRUE; }
+static inline BOOL is_invalid_8dot3_char( WCHAR ch ) +{ + static const char is_invalid[0x7f] = + { + ['*'] = 1, ['?'] = 1, ['<'] = 1, ['>'] = 1, ['|'] = 1, ['"'] = 1, ['+'] = 1, ['='] = 1, + [','] = 1, [';'] = 1, ['['] = 1, [']'] = 1, [' '] = 1, [':'] = 1, ['/'] = 1, ['\'] = 1, + }; + return ch <= 0x7f ? is_invalid[ch] : TRUE; +} + /* check if the device can be a mounted volume */ static inline BOOL is_valid_mounted_device( const struct stat *st ) { @@ -1461,7 +1471,6 @@ static BOOLEAN match_filename( const WCHAR *name, int length, const UNICODE_STRI */ static BOOLEAN is_legal_8dot3_name( const WCHAR *name, int len ) { - static const WCHAR invalid_chars[] = { INVALID_DOS_CHARS,':','/','\',0 }; int i, dot = -1;
if (len > 12) return FALSE; @@ -1471,8 +1480,7 @@ static BOOLEAN is_legal_8dot3_name( const WCHAR *name, int len )
for (i = 0; i < len; i++) { - if (name[i] > 0x7f) return FALSE; - if (wcschr( invalid_chars, name[i] )) return FALSE; + if (is_invalid_8dot3_char( name[i] )) return FALSE; if (name[i] == '.') { if (dot != -1) return FALSE;
From: Rémi Bernon rbernon@codeweavers.com
To lookup invalid NT chars, instead of costly wcschr. --- dlls/ntdll/unix/file.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 097346b475d..ed949da103c 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -268,6 +268,16 @@ static inline BOOL is_invalid_8dot3_char( WCHAR ch ) return ch <= 0x7f ? is_invalid[ch] : TRUE; }
+static inline BOOL is_invalid_nt_char( WCHAR ch ) +{ + static const char is_invalid[0x7f] = + { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + ['*'] = 1, ['?'] = 1, ['<'] = 1, ['>'] = 1, ['|'] = 1, ['"'] = 1, + }; + return ch <= 0x7f ? is_invalid[ch] : FALSE; +} + /* check if the device can be a mounted volume */ static inline BOOL is_valid_mounted_device( const struct stat *st ) { @@ -3474,7 +3484,6 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char UINT disposition ) { static const WCHAR unixW[] = {'u','n','i','x'}; - static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 };
NTSTATUS status = STATUS_SUCCESS; const WCHAR *name; @@ -3501,8 +3510,7 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char for (pos = 0; pos < name_len && pos <= MAX_DIR_ENTRY_LEN; pos++) { if (name[pos] == '\') break; - if (name[pos] < 32 || wcschr( invalid_charsW, name[pos] )) - return STATUS_OBJECT_NAME_INVALID; + if (is_invalid_nt_char( name[pos] )) return STATUS_OBJECT_NAME_INVALID; prefix[pos] = (name[pos] >= 'A' && name[pos] <= 'Z') ? name[pos] + 'a' - 'A' : name[pos]; } if (pos > MAX_DIR_ENTRY_LEN) return STATUS_OBJECT_NAME_INVALID;
From: Rémi Bernon rbernon@codeweavers.com
To lookup invalid unix chars, instead of costly wcschr. --- dlls/ntdll/unix/file.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index ed949da103c..67a4d4b6c89 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -169,7 +169,6 @@ typedef struct #define IS_SEPARATOR(ch) ((ch) == '\' || (ch) == '/')
#define INVALID_NT_CHARS '*','?','<','>','|','"' -#define INVALID_DOS_CHARS INVALID_NT_CHARS,'+','=',',',';','[',']',' ','\345'
#define MAX_DIR_ENTRY_LEN 255 /* max length of a directory entry in chars */
@@ -278,6 +277,12 @@ static inline BOOL is_invalid_nt_char( WCHAR ch ) return ch <= 0x7f ? is_invalid[ch] : FALSE; }
+static inline BOOL is_invalid_unix_char( WCHAR ch ) +{ + if (ch == '/') return TRUE; + return is_invalid_nt_char( ch ); +} + /* check if the device can be a mounted volume */ static inline BOOL is_valid_mounted_device( const struct stat *st ) { @@ -3364,7 +3369,6 @@ done: static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer, int unix_len, int pos, UINT disposition, BOOL is_unix ) { - static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, '/', 0 }; NTSTATUS status; int ret; struct stat st; @@ -3391,7 +3395,7 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer { if (!*ptr) return STATUS_OBJECT_NAME_INVALID; if (is_unix) continue; - if (*ptr < 32 || wcschr( invalid_charsW, *ptr )) return STATUS_OBJECT_NAME_INVALID; + if (is_invalid_unix_char( *ptr )) return STATUS_OBJECT_NAME_INVALID; } }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/ntdll/unix/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 67a4d4b6c89..f1d7742e238 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -1369,7 +1369,8 @@ static ULONG hash_short_file_name( const WCHAR *name, int length, LPWSTR buffer }
/* Find last dot for start of the extension */ - for (p = name + 1, ext = NULL; p < end - 1; p++) if (*p == '.') ext = p; + for (ext = end - 2; ext > name; ext--) if (*ext == '.') break; + if (ext == name) ext = NULL;
/* Copy first 4 chars, replacing invalid chars with '_' */ for (i = 4, p = name, dst = buffer; i > 0; i--, p++)