ReactOS  0.4.13-dev-66-gc714b7f
dos8dot3.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * FILE: lib/rtl/dos8dot3.c
5  * PURPOSE: Short name (8.3 name) functions
6  * PROGRAMMER: Eric Kohl
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <rtl.h>
12 
13 #define NDEBUG
14 #include <debug.h>
15 
17 
18 /* CONSTANTS *****************************************************************/
19 
20 const ULONG RtlpShortIllegals[] = { 0xFFFFFFFF, 0xFC009C04, 0x38000000, 0x10000000 };
21 
22 /* FUNCTIONS *****************************************************************/
23 
24 BOOLEAN
25 NTAPI
27 
28 static BOOLEAN
30 {
31  return (Char < 128 && (RtlpShortIllegals[Char / 32] & (1 << (Char % 32))));
32 }
33 
34 static USHORT
36 {
37  PWCHAR CurrentChar;
38  USHORT Hash;
39  USHORT Saved;
40  USHORT Length;
41 
42  if (!Name->Length)
43  return 0;
44 
45  if (Name->Length == sizeof(WCHAR))
46  return Name->Buffer[0];
47 
48  CurrentChar = Name->Buffer;
49  Hash = (*CurrentChar << 8) + *(CurrentChar + 1);
50 
51  if (Name->Length == 2 * sizeof(WCHAR))
52  return Hash;
53 
54  Saved = Hash;
55  Length = 2;
56 
57  do
58  {
59  CurrentChar += 2;
60  Hash = (Hash << 7) + *CurrentChar;
61  Hash = (Saved >> 1) + (Hash << 8);
62 
63  if (Length + 1 < Name->Length / sizeof(WCHAR))
64  {
65  Hash += *(CurrentChar + 1);
66  }
67 
68  Saved = Hash;
69  Length += 2;
70  }
71  while (Length < Name->Length / sizeof(WCHAR));
72 
73  return Hash;
74 }
75 
76 /*
77  * @implemented
78  */
79 VOID
80 NTAPI
85 {
86  ULONG Length = Name->Length / sizeof(WCHAR);
87  ULONG IndexLength;
88  ULONG Index;
89  ULONG DotPos;
90  WCHAR IndexBuffer[8];
91  WCHAR Char;
92  USHORT Checksum;
93 
94  if (!Context->NameLength)
95  {
96  DotPos = Length;
97 
98  /* Find last dot in Name */
99  for (Index = 0; Index < Length; Index++)
100  {
101  if (Name->Buffer[Index] == L'.')
102  DotPos = Index;
103  }
104 
105  /* Copy name (6 valid characters max) */
106  for (Index = 0; Index < DotPos && Context->NameLength < 6; Index++)
107  {
108  Char = Name->Buffer[Index];
109 
110  if ((Char > L' ') && (Char != L'.') &&
112  {
114  Char = L'_';
115  else if (Char >= L'a' && Char <= L'z')
117 
118  Context->NameBuffer[Context->NameLength] = Char;
119  ++Context->NameLength;
120  }
121  }
122 
123  /* Copy extension (4 valid characters max) */
124  Context->ExtensionLength = 0;
125  if (DotPos < Length)
126  {
127  Context->ExtensionBuffer[0] = L'.';
128  Context->ExtensionLength = 1;
129 
130  while (DotPos < Length && Context->ExtensionLength < 4)
131  {
132  Char = Name->Buffer[DotPos];
133 
134  if ((Char > L' ') && (Char != L'.') &&
136  {
138  Char = L'_';
139  else if (Char >= L'a' && Char <= L'z')
141 
142  Context->ExtensionBuffer[Context->ExtensionLength++] = Char;
143  }
144 
145  Char = UNICODE_NULL;
146  ++DotPos;
147  }
148 
149  if (Char != UNICODE_NULL)
150  Context->ExtensionBuffer[Context->ExtensionLength - 1] = L'~';
151  }
152 
153  if (Context->NameLength <= 2)
154  {
155  Checksum = Context->Checksum = RtlpGetCheckSum(Name);
156 
157  for (Index = 0; Index < 4; Index++)
158  {
159  Context->NameBuffer[Context->NameLength + Index] =
160  (Checksum & 0xF) > 9 ? (Checksum & 0xF) + L'A' - 10 : (Checksum & 0xF) + L'0';
161  Checksum >>= 4;
162  }
163 
164  Context->CheckSumInserted = TRUE;
165  Context->NameLength += 4;
166  }
167  }
168 
169  ++Context->LastIndexValue;
170 
171  if (Context->LastIndexValue > 4 && !Context->CheckSumInserted)
172  {
173  Checksum = Context->Checksum = RtlpGetCheckSum(Name);
174 
175  for (Index = 2; Index < 6; Index++)
176  {
177  Context->NameBuffer[Index] =
178  (Checksum & 0xF) > 9 ? (Checksum & 0xF) + L'A' - 10 : (Checksum & 0xF) + L'0';
179  Checksum >>= 4;
180  }
181 
182  Context->CheckSumInserted = TRUE;
183  Context->NameLength = 6;
184  Context->LastIndexValue = 1;
185  }
186 
187  /* Calculate index length and index buffer */
188  Index = Context->LastIndexValue;
189  for (IndexLength = 1; IndexLength <= 7 && Index > 0; IndexLength++)
190  {
191  IndexBuffer[8 - IndexLength] = L'0' + (Index % 10);
192  Index /= 10;
193  }
194 
195  IndexBuffer[8 - IndexLength] = L'~';
196 
197  /* Reset name length */
198  Name8dot3->Length = 0;
199 
200  /* If name present */
201  if (Context->NameLength)
202  {
203  /* Copy name buffer */
204  Length = Context->NameLength * sizeof(WCHAR);
205  RtlCopyMemory(Name8dot3->Buffer, Context->NameBuffer, Length);
206  Name8dot3->Length = Length;
207  }
208 
209  /* Copy index buffer */
210  Length = IndexLength * sizeof(WCHAR);
211  RtlCopyMemory(Name8dot3->Buffer + (Name8dot3->Length / sizeof(WCHAR)),
212  IndexBuffer + (8 - IndexLength),
213  Length);
214  Name8dot3->Length += Length;
215 
216  /* If extension present */
217  if (Context->ExtensionLength)
218  {
219  /* Copy extension buffer */
220  Length = Context->ExtensionLength * sizeof(WCHAR);
221  RtlCopyMemory(Name8dot3->Buffer + (Name8dot3->Length / sizeof(WCHAR)),
222  Context->ExtensionBuffer,
223  Length);
224  Name8dot3->Length += Length;
225  }
226 }
227 
228 
229 /*
230  * @implemented
231  * Note: the function does not conform to the annotations.
232  * SpacesFound is not always set!
233  */
236 NTSYSAPI
237 BOOLEAN
238 NTAPI
242 {
243  static const char Illegal[] = "*?<>|\"+=,;[]:/\\\345";
244  int Dot = -1;
245  int i;
246  char Buffer[12];
248  BOOLEAN GotSpace = FALSE;
250 
251  if (!OemName)
252  {
253  OemString.Length = sizeof(Buffer);
254  OemString.MaximumLength = sizeof(Buffer);
255  OemString.Buffer = Buffer;
256  OemName = &OemString;
257  }
258 
260  if (!NT_SUCCESS(Status))
261  return FALSE;
262 
263  if ((OemName->Length > 12) || (OemName->Buffer == NULL)) return FALSE;
264 
265  /* a starting . is invalid, except for . and .. */
266  if (OemName->Buffer[0] == '.')
267  {
268  if (OemName->Length != 1 && (OemName->Length != 2 || OemName->Buffer[1] != '.')) return FALSE;
270 
271  return TRUE;
272  }
273 
274  for (i = 0; i < OemName->Length; i++)
275  {
276  switch (OemName->Buffer[i])
277  {
278  case ' ':
279  /* leading/trailing spaces not allowed */
280  if (!i || i == OemName->Length-1 || OemName->Buffer[i+1] == '.') return FALSE;
281  GotSpace = TRUE;
282  break;
283 
284  case '.':
285  if (Dot != -1) return FALSE;
286  Dot = i;
287  break;
288 
289  default:
290  if (strchr(Illegal, OemName->Buffer[i])) return FALSE;
291  break;
292  }
293  }
294  /* check file part is shorter than 8, extension shorter than 3
295  * dot cannot be last in string
296  */
297  if (Dot == -1)
298  {
299  if (OemName->Length > 8) return FALSE;
300  }
301  else
302  {
303  if (Dot > 8 || (OemName->Length - Dot > 4) || Dot == OemName->Length - 1) return FALSE;
304  }
305 
306  if (NameContainsSpaces) *NameContainsSpaces = GotSpace;
307 
308  return TRUE;
309 }
310 
311 /* EOF */
static int Hash(const char *)
Definition: reader.c:2257
*BytesInOemString PCHAR OemString
Definition: rtlfuncs.h:1561
#define IN
Definition: typedefs.h:38
#define _Must_inspect_result_
Definition: no_sal2.h:314
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_Inout_opt_ POEM_STRING _Out_opt_ PBOOLEAN NameContainsSpaces
Definition: rtlfuncs.h:2961
BOOLEAN NTAPI RtlIsValidOemCharacter(IN PWCHAR Char)
Definition: unicode.c:514
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:54
STRING OEM_STRING
Definition: umtypes.h:203
#define NTSYSAPI
Definition: ntoskrnl.h:14
_IRQL_requires_max_(PASSIVE_LEVEL)
Definition: dos8dot3.c:234
#define Dot(u, v)
Definition: normal.c:49
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
char Char
Definition: bzip2.c:161
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI RtlGenerate8dot3Name(IN PUNICODE_STRING Name, IN BOOLEAN AllowExtendedCharacters, IN OUT PGENERATE_NAME_CONTEXT Context, OUT PUNICODE_STRING Name8dot3)
Definition: dos8dot3.c:81
static const UCHAR Index[8]
Definition: usbohci.c:18
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
char * PBOOLEAN
Definition: retypes.h:11
PUSHORT NlsUnicodeToMbOemTable
Definition: nls.c:32
static const WCHAR L[]
Definition: oid.c:1250
_In_ BOOLEAN _Inout_ PGENERATE_NAME_CONTEXT _Inout_ PUNICODE_STRING Name8dot3
Definition: rtlfuncs.h:1585
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
Status
Definition: gdiplustypes.h:24
unsigned short USHORT
Definition: pedump.c:61
static BOOLEAN RtlpIsShortIllegal(const WCHAR Char)
Definition: dos8dot3.c:29
WCHAR NTAPI RtlpUpcaseUnicodeChar(IN WCHAR Source)
Definition: nls.c:715
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString(STRING *, const UNICODE_STRING *, BOOLEAN)
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1294
static USHORT RtlpGetCheckSum(PUNICODE_STRING Name)
Definition: dos8dot3.c:35
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
unsigned short * PUSHORT
Definition: retypes.h:2
_In_ BOOLEAN AllowExtendedCharacters
Definition: rtlfuncs.h:1585
BOOLEAN NTAPI RtlIsNameLegalDOS8Dot3(_In_ PUNICODE_STRING Name, _Inout_opt_ POEM_STRING OemName, _Inout_opt_ PBOOLEAN NameContainsSpaces)
const ULONG RtlpShortIllegals[]
Definition: dos8dot3.c:20
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68