From 9078342c2471b870ea7d7eaacf3b3f7d0fe22d59 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 5 Jun 2002 16:53:36 +0000 Subject: [PATCH] Implemented RtlGenerate8dot3Name() and RtlIsNameLegalDOS8Dot3(). svn path=/trunk/; revision=3001 --- reactos/include/ddk/rtl.h | 27 +++- reactos/include/ddk/rtltypes.h | 13 +- reactos/lib/ntdll/def/ntdll.def | 4 +- reactos/lib/ntdll/def/ntdll.edf | 4 +- reactos/lib/ntdll/makefile | 4 +- reactos/lib/ntdll/rtl/dos8dot3.c | 245 +++++++++++++++++++++++++++++++ reactos/lib/ntdll/rtl/path.c | 77 +--------- reactos/ntoskrnl/Makefile | 3 +- reactos/ntoskrnl/ntoskrnl.def | 6 +- reactos/ntoskrnl/ntoskrnl.edf | 6 +- reactos/ntoskrnl/rtl/dos8dot3.c | 241 ++++++++++++++++++++++++++++++ 11 files changed, 534 insertions(+), 96 deletions(-) create mode 100644 reactos/lib/ntdll/rtl/dos8dot3.c create mode 100644 reactos/ntoskrnl/rtl/dos8dot3.c diff --git a/reactos/include/ddk/rtl.h b/reactos/include/ddk/rtl.h index 1557069f89b..baf3c45bfc6 100644 --- a/reactos/include/ddk/rtl.h +++ b/reactos/include/ddk/rtl.h @@ -1,4 +1,4 @@ -/* $Id: rtl.h,v 1.60 2002/02/20 20:09:52 ekohl Exp $ +/* $Id: rtl.h,v 1.61 2002/06/05 16:49:56 ekohl Exp $ * */ @@ -646,6 +646,10 @@ RtlCopyMemory ( #define RtlCopyBytes RtlCopyMemory +VOID STDCALL +RtlCopyLuid(IN PLUID LuidDest, + IN PLUID LuidSrc); + VOID STDCALL RtlCopyString ( @@ -781,6 +785,10 @@ RtlEnlargedUnsignedMultiply ( ULONG Multiplier ); +BOOLEAN STDCALL +RtlEqualLuid(IN PLUID Luid1, + IN PLUID Luid2); + BOOLEAN STDCALL RtlEqualString ( @@ -938,6 +946,12 @@ RtlFreeUnicodeString ( PUNICODE_STRING UnicodeString ); +VOID STDCALL +RtlGenerate8dot3Name(IN PUNICODE_STRING Name, + IN BOOLEAN AllowExtendedCharacters, + IN OUT PGENERATE_NAME_CONTEXT Context, + OUT PUNICODE_STRING Name8dot3); + VOID RtlGetCallersAddress ( PVOID * CallersAddress @@ -1069,13 +1083,10 @@ RtlIsGenericTableEmpty ( IN PRTL_GENERIC_TABLE Table ); -BOOLEAN -STDCALL -RtlIsNameLegalDOS8Dot3 ( - IN PUNICODE_STRING UnicodeName, - IN OUT PANSI_STRING AnsiName, - IN OUT PBOOLEAN SpacesFound - ); +BOOLEAN STDCALL +RtlIsNameLegalDOS8Dot3(IN PUNICODE_STRING UnicodeName, + IN PANSI_STRING AnsiName, + OUT PBOOLEAN SpacesFound); LARGE_INTEGER STDCALL diff --git a/reactos/include/ddk/rtltypes.h b/reactos/include/ddk/rtltypes.h index 56937df8163..be5c1ca4071 100644 --- a/reactos/include/ddk/rtltypes.h +++ b/reactos/include/ddk/rtltypes.h @@ -1,4 +1,4 @@ -/* $Id: rtltypes.h,v 1.1 2002/01/14 01:41:08 ekohl Exp $ +/* $Id: rtltypes.h,v 1.2 2002/06/05 16:49:57 ekohl Exp $ * */ @@ -170,4 +170,15 @@ typedef struct _RTL_QUERY_REGISTRY_TABLE } RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE; +typedef struct _GENERATE_NAME_CONTEXT +{ + USHORT Checksum; + BOOLEAN CheckSumInserted; + UCHAR NameLength; + WCHAR NameBuffer[8]; + ULONG ExtensionLength; + WCHAR ExtensionBuffer[4]; + ULONG LastIndexValue; +} GENERATE_NAME_CONTEXT, *PGENERATE_NAME_CONTEXT; + #endif /* __DDK_RTLTYPES_H */ diff --git a/reactos/lib/ntdll/def/ntdll.def b/reactos/lib/ntdll/def/ntdll.def index e9c3e0648c7..059767fbabe 100644 --- a/reactos/lib/ntdll/def/ntdll.def +++ b/reactos/lib/ntdll/def/ntdll.def @@ -1,4 +1,4 @@ -; $Id: ntdll.def,v 1.82 2001/12/02 23:34:41 dwelch Exp $ +; $Id: ntdll.def,v 1.83 2002/06/05 16:51:20 ekohl Exp $ ; ; ReactOS Operating System ; @@ -412,7 +412,7 @@ RtlFreeOemString@4 RtlFreeSid@4 RtlFreeUnicodeString@4 RtlFreeUserThreadStack@8 -;RtlGenerate8dot3Name +RtlGenerate8dot3Name@16 RtlGetAce@12 ;RtlGetCallersAddress ;RtlGetCompressionWorkSpaceSize diff --git a/reactos/lib/ntdll/def/ntdll.edf b/reactos/lib/ntdll/def/ntdll.edf index ba1e7c70882..ed7517495c5 100644 --- a/reactos/lib/ntdll/def/ntdll.edf +++ b/reactos/lib/ntdll/def/ntdll.edf @@ -1,4 +1,4 @@ -; $Id: ntdll.edf,v 1.71 2001/12/02 23:34:41 dwelch Exp $ +; $Id: ntdll.edf,v 1.72 2002/06/05 16:51:20 ekohl Exp $ ; ; ReactOS Operating System ; @@ -411,7 +411,7 @@ RtlFreeHeap=RtlFreeHeap@12 RtlFreeSid=RtlFreeSid@4 RtlFreeUnicodeString=RtlFreeUnicodeString@4 RtlFreeUserThreadStack=RtlFreeUserThreadStack@8 -;RtlGenerate8dot3Name +RtlGenerate8dot3Name=RtlGenerate8dot3Name@16 RtlGetAce=RtlGetAce@12 ;RtlGetCallersAddress ;RtlGetCompressionWorkSpaceSize diff --git a/reactos/lib/ntdll/makefile b/reactos/lib/ntdll/makefile index e507cac65e5..a9084e866f3 100644 --- a/reactos/lib/ntdll/makefile +++ b/reactos/lib/ntdll/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.70 2002/02/25 21:51:43 phreak Exp $ +# $Id: makefile,v 1.71 2002/06/05 16:51:41 ekohl Exp $ PATH_TO_TOP = ../.. @@ -31,7 +31,7 @@ RTL_OBJECTS = rtl/critical.o rtl/error.o rtl/heap.o rtl/largeint.o \ rtl/access.o rtl/apc.o rtl/callback.o rtl/luid.o rtl/misc.o \ rtl/registry.o rtl/exception.o rtl/intrlck.o rtl/resource.o \ rtl/handle.o rtl/atom.o rtl/message.o rtl/timezone.o \ - rtl/propvar.o rtl/security.o + rtl/propvar.o rtl/security.o rtl/dos8dot3.o STDIO_OBJECTS = stdio/sprintf.o stdio/swprintf.o diff --git a/reactos/lib/ntdll/rtl/dos8dot3.c b/reactos/lib/ntdll/rtl/dos8dot3.c new file mode 100644 index 00000000000..ce9b722b892 --- /dev/null +++ b/reactos/lib/ntdll/rtl/dos8dot3.c @@ -0,0 +1,245 @@ +/* + * ReactOS kernel + * Copyright (C) 2002 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id: dos8dot3.c,v 1.1 2002/06/05 16:50:43 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/ntdll/rtl/dos8dot3.c + * PURPOSE: Short name (8.3 name) functions + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES ******************************************************************/ + +#include +#include + +//#define NDEBUG +#include + + +/* CONSTANTS *****************************************************************/ + +const PWCHAR RtlpShortIllegals = L" ;+=[]',\"*\\<>/?:|"; + + +/* FUNCTIONS *****************************************************************/ + +static BOOLEAN +RtlpIsShortIllegal(WCHAR Char) +{ + int i; + + for (i = 0; RtlpShortIllegals[i]; i++) + { + if (Char == RtlpShortIllegals[i]) + return(TRUE); + } + + return(FALSE); +} + + +VOID STDCALL +RtlGenerate8dot3Name(IN PUNICODE_STRING Name, + IN BOOLEAN AllowExtendedCharacters, + IN OUT PGENERATE_NAME_CONTEXT Context, + OUT PUNICODE_STRING Name8dot3) +{ + WCHAR NameBuffer[8]; + WCHAR ExtBuffer[4]; + USHORT StrLength; + USHORT NameLength; + USHORT ExtLength; + USHORT CopyLength; + USHORT DotPos; + USHORT i, j; + USHORT CurrentIndex; + + memset(NameBuffer, 0, sizeof(NameBuffer)); + memset(ExtBuffer, 0, sizeof(ExtBuffer)); + + StrLength = Name->Length / sizeof(WCHAR); + + DPRINT("StrLength: %hu\n", StrLength); + + /* Find last dot in Name */ + DotPos = 0; + for (i = 0; i < StrLength; i++) + { + if (Name->Buffer[i] == L'.') + { + DotPos = i; + } + } + + if (DotPos == 0) + { + DotPos = i; + } + + DPRINT("DotPos: %hu\n", DotPos); + + /* Copy name (6 valid characters max) */ + for (i = 0, NameLength = 0; NameLength < 6 && i < DotPos; i++) + { + if ((!RtlpIsShortIllegal(Name->Buffer[i])) && + (Name->Buffer[i] != L'.')) + { + NameBuffer[NameLength++] = RtlUpcaseUnicodeChar(Name->Buffer[i]); + } + } + + DPRINT("NameBuffer: '%.08S'\n", NameBuffer); + DPRINT("NameLength: %hu\n", NameLength); + + + /* Copy extension (4 valid characters max) */ + if (DotPos < StrLength) + { + for (i = DotPos, ExtLength = 0; ExtLength < 4 && i < StrLength; i++) + { + if (!RtlpIsShortIllegal(Name->Buffer[i])) + { + ExtBuffer[ExtLength++] = RtlUpcaseUnicodeChar(Name->Buffer[i]); + } + } + } + + DPRINT("ExtBuffer: '%.04S'\n", ExtBuffer); + DPRINT("ExtLength: %hu\n", ExtLength); + + CopyLength = min(NameLength, (CurrentIndex < 10) ? 6 : 5); + + if ((Context->NameLength == CopyLength) && + (wcsncmp(Context->NameBuffer, NameBuffer, CopyLength) == 0) && + (Context->ExtensionLength = ExtLength) && + (wcsncmp(Context->ExtensionBuffer, ExtBuffer, ExtLength) == 0)) + CurrentIndex = Context->LastIndexValue + 1; + else + CurrentIndex = 1; + + DPRINT("CurrentIndex: %hu\n", CurrentIndex); + + /* Build the short name */ + for (i = 0; i < CopyLength; i++) + { + Name8dot3->Buffer[i] = NameBuffer[i]; + } + + Name8dot3->Buffer[i++] = L'~'; + if (CurrentIndex >= 10) + Name8dot3->Buffer[i++] = (CurrentIndex / 10) + L'0'; + Name8dot3->Buffer[i++] = (CurrentIndex % 10) + L'0'; + + for (j = 0; j < ExtLength; i++, j++) + { + Name8dot3->Buffer[i] = ExtBuffer[j]; + } + + Name8dot3->Length = i * sizeof(WCHAR); + + DPRINT("Name8dot3: '%wZ'\n", Name8dot3); + + /* Update context */ + Context->NameLength = CopyLength; + for (i = 0; i < CopyLength; i++) + { + Context->NameBuffer[i] = NameBuffer[i]; + } + + Context->ExtensionLength = ExtLength; + for (i = 0; i < ExtLength; i++) + { + Context->ExtensionBuffer[i] = ExtBuffer[i]; + } + + Context->LastIndexValue = CurrentIndex; +} + + +BOOLEAN STDCALL +RtlIsNameLegalDOS8Dot3(IN PUNICODE_STRING UnicodeName, + IN PANSI_STRING AnsiName, + OUT PBOOLEAN SpacesFound) +{ + PANSI_STRING name = AnsiName; + ANSI_STRING DummyString; + CHAR Buffer[12]; + char *str; + ULONG Length; + ULONG i; + NTSTATUS Status; + BOOLEAN HasSpace = FALSE; + BOOLEAN HasDot = FALSE; + + if (UnicodeName->Length > 24) + { + return(FALSE); /* name too long */ + } + + if (!name) + { + name = &DummyString; + name->Length = 0; + name->MaximumLength = 12; + name->Buffer = Buffer; + } + + Status = RtlUpcaseUnicodeStringToCountedOemString(name, + UnicodeName, + FALSE); + if (!NT_SUCCESS(Status)) + { + return(FALSE); + } + + Length = name->Length; + str = name->Buffer; + + if (!(Length == 1 && *str == '.') && + !(Length == 2 && *str == '.' && *(str + 1) == '.')) + { + for (i = 0; i < Length; i++, str++) + { + switch (*str) + { + case ' ': + HasSpace = TRUE; + break; + + case '.': + if ((HasDot) || /* two dots */ + (!i) || /* point is first char */ + (i + 1 == Length) ||/* point is last char */ + (Length - i > 4)) /* more than 3 chars of extension */ + return(FALSE); + HasDot = TRUE; + break; + } + } + } + + if (SpacesFound) + *SpacesFound = HasSpace; + + return(TRUE); +} + +/* EOF */ diff --git a/reactos/lib/ntdll/rtl/path.c b/reactos/lib/ntdll/rtl/path.c index b294cd70305..7c128dc9345 100644 --- a/reactos/lib/ntdll/rtl/path.c +++ b/reactos/lib/ntdll/rtl/path.c @@ -1,4 +1,4 @@ -/* $Id: path.c,v 1.11 2001/06/12 12:29:40 ekohl Exp $ +/* $Id: path.c,v 1.12 2002/06/05 16:50:43 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -799,79 +799,8 @@ RtlDosSearchPath_U ( } -BOOLEAN -STDCALL -RtlIsNameLegalDOS8Dot3 ( - PUNICODE_STRING UnicodeName, - PANSI_STRING AnsiName, - PBOOLEAN SpacesFound - ) -{ - PANSI_STRING name = AnsiName; - ANSI_STRING DummyString; - CHAR Buffer[12]; - char *str; - ULONG Length; - ULONG i; - NTSTATUS Status; - BOOLEAN HasSpace = FALSE; - BOOLEAN HasDot = FALSE; - - if (UnicodeName->Length > 24) - return FALSE; /* name too long */ - - if (!name) - { - name = &DummyString; - name->Length = 0; - name->MaximumLength = 12; - name->Buffer = Buffer; - } - - Status = RtlUpcaseUnicodeStringToCountedOemString (name, - UnicodeName, - FALSE); - if (!NT_SUCCESS(Status)) - return FALSE; - - Length = name->Length; - str = name->Buffer; - - if (!(Length == 1 && *str == '.') && - !(Length == 2 && *str == '.' && *(str + 1) == '.')) - { - for (i = 0; i < Length; i++, str++) - { - switch (*str) - { - case ' ': - HasSpace = TRUE; - break; - - case '.': - if ((HasDot) || /* two points */ - (!i) || /* point is first char */ - (i + 1 == Length) ||/* point is last char */ - (Length - i > 4)) /* more than 3 chars of extension */ - return FALSE; - HasDot = TRUE; - break; - } - } - } - - if (SpacesFound) - *SpacesFound = HasSpace; - - return TRUE; -} - - -BOOLEAN -STDCALL -RtlDoesFileExists_U ( - IN PWSTR FileName - ) +BOOLEAN STDCALL +RtlDoesFileExists_U(IN PWSTR FileName) { UNICODE_STRING NtFileName; OBJECT_ATTRIBUTES Attr; diff --git a/reactos/ntoskrnl/Makefile b/reactos/ntoskrnl/Makefile index 399c319c9bf..b7202559e1a 100644 --- a/reactos/ntoskrnl/Makefile +++ b/reactos/ntoskrnl/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.68 2002/05/05 14:57:42 chorns Exp $ +# $Id: Makefile,v 1.69 2002/06/05 16:53:36 ekohl Exp $ # # ReactOS Operating System # @@ -83,6 +83,7 @@ OBJECTS_RTL = \ rtl/atom.o \ rtl/bitmap.o \ rtl/ctype.o \ + rtl/dos8dot3.o \ rtl/error.o \ rtl/handle.o \ rtl/largeint.o \ diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 93b98dd9c66..02c671fd0e8 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.def,v 1.133 2002/05/02 23:45:32 dwelch Exp $ +; $Id: ntoskrnl.def,v 1.134 2002/06/05 16:53:36 ekohl Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -731,7 +731,7 @@ RtlFreeAnsiString@4 ;RtlFreeHeap RtlFreeOemString@4 RtlFreeUnicodeString@4 -;RtlGenerate8dot3Name +RtlGenerate8dot3Name@16 ;RtlGetCallersAddress ;RtlGetCompressionWorkSpaceSize RtlGetDaclSecurityDescriptor@16 @@ -752,7 +752,7 @@ RtlInitializeSid@12 ;RtlInsertUnicodePrefix RtlIntegerToChar@16 RtlIntegerToUnicodeString@12 -;RtlIsNameLegalDOS8Dot3 +RtlIsNameLegalDOS8Dot3@12 RtlLargeIntegerAdd@16 RtlLargeIntegerArithmeticShift@12 RtlLargeIntegerDivide@20 diff --git a/reactos/ntoskrnl/ntoskrnl.edf b/reactos/ntoskrnl/ntoskrnl.edf index 10a26e2c6c1..31f61291706 100644 --- a/reactos/ntoskrnl/ntoskrnl.edf +++ b/reactos/ntoskrnl/ntoskrnl.edf @@ -1,4 +1,4 @@ -; $Id: ntoskrnl.edf,v 1.119 2002/05/02 23:45:32 dwelch Exp $ +; $Id: ntoskrnl.edf,v 1.120 2002/06/05 16:53:36 ekohl Exp $ ; ; reactos/ntoskrnl/ntoskrnl.def ; @@ -731,7 +731,7 @@ RtlFreeAnsiString=RtlFreeAnsiString@4 ;RtlFreeHeap RtlFreeOemString=RtlFreeOemString@4 RtlFreeUnicodeString=RtlFreeUnicodeString@4 -;RtlGenerate8dot3Name +RtlGenerate8dot3Name=RtlGenerate8dot3Name@16 ;RtlGetCallersAddress ;RtlGetCompressionWorkSpaceSize RtlGetDaclSecurityDescriptor=RtlGetDaclSecurityDescriptor@16 @@ -752,7 +752,7 @@ RtlInitializeSid=RtlInitializeSid@12 ;RtlInsertUnicodePrefix RtlIntegerToChar=RtlIntegerToChar@16 RtlIntegerToUnicodeString=RtlIntegerToUnicodeString@12 -;RtlIsNameLegalDOS8Dot3 +RtlIsNameLegalDOS8Dot3=RtlIsNameLegalDOS8Dot3@12 RtlLargeIntegerAdd=RtlLargeIntegerAdd@16 RtlLargeIntegerArithmeticShift=RtlLargeIntegerArithmeticShift@12 RtlLargeIntegerDivide=RtlLargeIntegerDivide@20 diff --git a/reactos/ntoskrnl/rtl/dos8dot3.c b/reactos/ntoskrnl/rtl/dos8dot3.c new file mode 100644 index 00000000000..81a855ab196 --- /dev/null +++ b/reactos/ntoskrnl/rtl/dos8dot3.c @@ -0,0 +1,241 @@ +/* + * ReactOS kernel + * Copyright (C) 2002 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id: dos8dot3.c,v 1.1 2002/06/05 16:52:43 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/rtl/dos8dot3.c + * PURPOSE: Short name (8.3 name) functions + * PROGRAMMER: Eric Kohl + */ + +/* INCLUDES ******************************************************************/ + +#include +#include + +#define NDEBUG +#include + + +/* CONSTANTS *****************************************************************/ + +const PWCHAR RtlpShortIllegals = L" ;+=[]',\"*\\<>/?:|"; + + +/* FUNCTIONS *****************************************************************/ + +static BOOLEAN +RtlpIsShortIllegal(WCHAR Char) +{ + int i; + + for (i = 0; RtlpShortIllegals[i]; i++) + { + if (Char == RtlpShortIllegals[i]) + return(TRUE); + } + + return(FALSE); +} + + +VOID STDCALL +RtlGenerate8dot3Name(IN PUNICODE_STRING Name, + IN BOOLEAN AllowExtendedCharacters, + IN OUT PGENERATE_NAME_CONTEXT Context, + OUT PUNICODE_STRING Name8dot3) +{ + WCHAR NameBuffer[8]; + WCHAR ExtBuffer[4]; + USHORT StrLength; + USHORT NameLength; + USHORT ExtLength; + USHORT CopyLength; + USHORT DotPos; + USHORT i, j; + USHORT CurrentIndex; + + memset(NameBuffer, 0, sizeof(NameBuffer)); + memset(ExtBuffer, 0, sizeof(ExtBuffer)); + + StrLength = Name->Length / sizeof(WCHAR); + DPRINT("StrLength: %hu\n", StrLength); + + /* Find last dot in Name */ + DotPos = 0; + for (i = 0; i < StrLength; i++) + { + if (Name->Buffer[i] == L'.') + { + DotPos = i; + } + } + + if (DotPos == 0) + { + DotPos = i; + } + DPRINT("DotPos: %hu\n", DotPos); + + /* Copy name (6 valid characters max) */ + for (i = 0, NameLength = 0; NameLength < 6 && i < DotPos; i++) + { + if ((!RtlpIsShortIllegal(Name->Buffer[i])) && + (Name->Buffer[i] != L'.')) + { + NameBuffer[NameLength++] = RtlUpcaseUnicodeChar(Name->Buffer[i]); + } + } + DPRINT("NameBuffer: '%.08S'\n", NameBuffer); + DPRINT("NameLength: %hu\n", NameLength); + + /* Copy extension (4 valid characters max) */ + if (DotPos < StrLength) + { + for (i = DotPos, ExtLength = 0; ExtLength < 4 && i < StrLength; i++) + { + if (!RtlpIsShortIllegal(Name->Buffer[i])) + { + ExtBuffer[ExtLength++] = RtlUpcaseUnicodeChar(Name->Buffer[i]); + } + } + } + DPRINT("ExtBuffer: '%.04S'\n", ExtBuffer); + DPRINT("ExtLength: %hu\n", ExtLength); + + /* Determine next index */ + CopyLength = min(NameLength, (CurrentIndex < 10) ? 6 : 5); + if ((Context->NameLength == CopyLength) && + (wcsncmp(Context->NameBuffer, NameBuffer, CopyLength) == 0) && + (Context->ExtensionLength = ExtLength) && + (wcsncmp(Context->ExtensionBuffer, ExtBuffer, ExtLength) == 0)) + CurrentIndex = Context->LastIndexValue + 1; + else + CurrentIndex = 1; + DPRINT("CurrentIndex: %hu\n", CurrentIndex); + + /* Build the short name */ + for (i = 0; i < CopyLength; i++) + { + Name8dot3->Buffer[i] = NameBuffer[i]; + } + + Name8dot3->Buffer[i++] = L'~'; + if (CurrentIndex >= 10) + Name8dot3->Buffer[i++] = (CurrentIndex / 10) + L'0'; + Name8dot3->Buffer[i++] = (CurrentIndex % 10) + L'0'; + + for (j = 0; j < ExtLength; i++, j++) + { + Name8dot3->Buffer[i] = ExtBuffer[j]; + } + + Name8dot3->Length = i * sizeof(WCHAR); + + DPRINT("Name8dot3: '%wZ'\n", Name8dot3); + + /* Update context */ + Context->NameLength = CopyLength; + for (i = 0; i < CopyLength; i++) + { + Context->NameBuffer[i] = NameBuffer[i]; + } + + Context->ExtensionLength = ExtLength; + for (i = 0; i < ExtLength; i++) + { + Context->ExtensionBuffer[i] = ExtBuffer[i]; + } + + Context->LastIndexValue = CurrentIndex; +} + + +BOOLEAN STDCALL +RtlIsNameLegalDOS8Dot3(IN PUNICODE_STRING UnicodeName, + IN PANSI_STRING AnsiName, + OUT PBOOLEAN SpacesFound) +{ + PANSI_STRING name = AnsiName; + ANSI_STRING DummyString; + CHAR Buffer[12]; + char *str; + ULONG Length; + ULONG i; + NTSTATUS Status; + BOOLEAN HasSpace = FALSE; + BOOLEAN HasDot = FALSE; + + if (UnicodeName->Length > 24) + { + return(FALSE); /* name too long */ + } + + if (!name) + { + name = &DummyString; + name->Length = 0; + name->MaximumLength = 12; + name->Buffer = Buffer; + } + + Status = RtlUpcaseUnicodeStringToCountedOemString(name, + UnicodeName, + FALSE); + if (!NT_SUCCESS(Status)) + { + return(FALSE); + } + + Length = name->Length; + str = name->Buffer; + + if (!(Length == 1 && *str == '.') && + !(Length == 2 && *str == '.' && *(str + 1) == '.')) + { + for (i = 0; i < Length; i++, str++) + { + switch (*str) + { + case ' ': + HasSpace = TRUE; + break; + + case '.': + if ((HasDot) || /* two dots */ + (!i) || /* point is first char */ + (i + 1 == Length) ||/* point is last char */ + (Length - i > 4)) /* more than 3 chars of extension */ + return(FALSE); + HasDot = TRUE; + break; + } + } + } + + if (SpacesFound) + *SpacesFound = HasSpace; + + return(TRUE); +} + + + +/* EOF */ \ No newline at end of file