mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Implemented RtlGenerate8dot3Name() and RtlIsNameLegalDOS8Dot3().
svn path=/trunk/; revision=3001
This commit is contained in:
parent
3d3be3df27
commit
9078342c24
11 changed files with 534 additions and 96 deletions
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
245
reactos/lib/ntdll/rtl/dos8dot3.c
Normal file
245
reactos/lib/ntdll/rtl/dos8dot3.c
Normal file
|
@ -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 <ddk/ntddk.h>
|
||||
#include <ntos/minmax.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <ntdll/ntdll.h>
|
||||
|
||||
|
||||
/* 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 */
|
|
@ -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;
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
241
reactos/ntoskrnl/rtl/dos8dot3.c
Normal file
241
reactos/ntoskrnl/rtl/dos8dot3.c
Normal file
|
@ -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 <ddk/ntddk.h>
|
||||
#include <ntos/minmax.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
|
||||
/* 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 */
|
Loading…
Reference in a new issue