ReactOS  0.4.15-dev-2972-gda2a567
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. OEM string length can't exceed 6. */
106  UCHAR OemSizeLeft = 6;
107  for (Index = 0; (Index < DotPos) && OemSizeLeft; Index++)
108  {
109  Char = Name->Buffer[Index];
110 
111  if ((Char > L' ') && (Char != L'.') &&
112  ((Char < 127) || (AllowExtendedCharacters && RtlIsValidOemCharacter(&Char))))
113  {
114  if (RtlpIsShortIllegal(Char))
115  Char = L'_';
116  else if (Char >= L'a' && Char <= L'z')
117  Char = RtlpUpcaseUnicodeChar(Char);
118 
119  /* Beware of MB OEM codepage */
121  {
122  if (OemSizeLeft < 2)
123  break;
124  OemSizeLeft--;
125  }
126 
127  Context->NameBuffer[Context->NameLength] = Char;
128  Context->NameLength++;
129  OemSizeLeft--;
130  }
131  }
132 
133  /* Copy extension (4 valid characters max) */
134  Context->ExtensionLength = 0;
135  if (DotPos < Length)
136  {
137  Context->ExtensionBuffer[0] = L'.';
138  Context->ExtensionLength = 1;
139 
140  while (DotPos < Length && Context->ExtensionLength < 4)
141  {
142  Char = Name->Buffer[DotPos];
143 
144  if ((Char > L' ') && (Char != L'.') &&
145  ((Char < 127) || (AllowExtendedCharacters && RtlIsValidOemCharacter(&Char))))
146  {
147  if (RtlpIsShortIllegal(Char))
148  Char = L'_';
149  else if (Char >= L'a' && Char <= L'z')
150  Char = RtlpUpcaseUnicodeChar(Char);
151 
152  Context->ExtensionBuffer[Context->ExtensionLength++] = Char;
153  }
154 
155  Char = UNICODE_NULL;
156  ++DotPos;
157  }
158 
159  if (Char != UNICODE_NULL)
160  Context->ExtensionBuffer[Context->ExtensionLength - 1] = L'~';
161  }
162 
163  if (Context->NameLength <= 2)
164  {
165  Checksum = Context->Checksum = RtlpGetCheckSum(Name);
166 
167  for (Index = 0; Index < 4; Index++)
168  {
169  Context->NameBuffer[Context->NameLength + Index] =
170  (Checksum & 0xF) > 9 ? (Checksum & 0xF) + L'A' - 10 : (Checksum & 0xF) + L'0';
171  Checksum >>= 4;
172  }
173 
174  Context->CheckSumInserted = TRUE;
175  Context->NameLength += 4;
176  }
177  }
178 
179  ++Context->LastIndexValue;
180 
181  if (Context->LastIndexValue > 4 && !Context->CheckSumInserted)
182  {
183  Checksum = Context->Checksum = RtlpGetCheckSum(Name);
184 
185  for (Index = 2; Index < 6; Index++)
186  {
187  Context->NameBuffer[Index] =
188  (Checksum & 0xF) > 9 ? (Checksum & 0xF) + L'A' - 10 : (Checksum & 0xF) + L'0';
189  Checksum >>= 4;
190  }
191 
192  Context->CheckSumInserted = TRUE;
193  Context->NameLength = 6;
194  Context->LastIndexValue = 1;
195  }
196 
197  /* Calculate index length and index buffer */
198  Index = Context->LastIndexValue;
199  for (IndexLength = 1; IndexLength <= 7 && Index > 0; IndexLength++)
200  {
201  IndexBuffer[8 - IndexLength] = L'0' + (Index % 10);
202  Index /= 10;
203  }
204 
205  IndexBuffer[8 - IndexLength] = L'~';
206 
207  /* Reset name length */
208  Name8dot3->Length = 0;
209 
210  /* If name present */
211  if (Context->NameLength)
212  {
213  /* Copy name buffer */
214  Length = Context->NameLength * sizeof(WCHAR);
215  RtlCopyMemory(Name8dot3->Buffer, Context->NameBuffer, Length);
216  Name8dot3->Length = Length;
217  }
218 
219  /* Copy index buffer */
220  Length = IndexLength * sizeof(WCHAR);
221  RtlCopyMemory(Name8dot3->Buffer + (Name8dot3->Length / sizeof(WCHAR)),
222  IndexBuffer + (8 - IndexLength),
223  Length);
224  Name8dot3->Length += Length;
225 
226  /* If extension present */
227  if (Context->ExtensionLength)
228  {
229  /* Copy extension buffer */
230  Length = Context->ExtensionLength * sizeof(WCHAR);
231  RtlCopyMemory(Name8dot3->Buffer + (Name8dot3->Length / sizeof(WCHAR)),
232  Context->ExtensionBuffer,
233  Length);
234  Name8dot3->Length += Length;
235  }
236 }
237 
238 
239 /*
240  * @implemented
241  * Note: the function does not conform to the annotations.
242  * SpacesFound is not always set!
243  */
246 NTSYSAPI
247 BOOLEAN
248 NTAPI
252 {
253  static const char Illegal[] = "*?<>|\"+=,;[]:/\\\345";
254  int Dot = -1;
255  int i;
256  char Buffer[12];
258  BOOLEAN GotSpace = FALSE;
260 
261  if (!OemName)
262  {
263  OemString.Length = sizeof(Buffer);
264  OemString.MaximumLength = sizeof(Buffer);
265  OemString.Buffer = Buffer;
266  OemName = &OemString;
267  }
268 
270  if (!NT_SUCCESS(Status))
271  return FALSE;
272 
273  if ((OemName->Length > 12) || (OemName->Buffer == NULL)) return FALSE;
274 
275  /* a starting . is invalid, except for . and .. */
276  if (OemName->Buffer[0] == '.')
277  {
278  if (OemName->Length != 1 && (OemName->Length != 2 || OemName->Buffer[1] != '.')) return FALSE;
280 
281  return TRUE;
282  }
283 
284  for (i = 0; i < OemName->Length; i++)
285  {
286  switch (OemName->Buffer[i])
287  {
288  case ' ':
289  /* leading/trailing spaces not allowed */
290  if (!i || i == OemName->Length-1 || OemName->Buffer[i+1] == '.') return FALSE;
291  GotSpace = TRUE;
292  break;
293 
294  case '.':
295  if (Dot != -1) return FALSE;
296  Dot = i;
297  break;
298 
299  default:
300  if (strchr(Illegal, OemName->Buffer[i])) return FALSE;
301  break;
302  }
303  }
304  /* check file part is shorter than 8, extension shorter than 3
305  * dot cannot be last in string
306  */
307  if (Dot == -1)
308  {
309  if (OemName->Length > 8) return FALSE;
310  }
311  else
312  {
313  if (Dot > 8 || (OemName->Length - Dot > 4) || Dot == OemName->Length - 1) return FALSE;
314  }
315 
316  if (NameContainsSpaces) *NameContainsSpaces = GotSpace;
317 
318  return TRUE;
319 }
320 
321 /* EOF */
static int Hash(const char *)
Definition: reader.c:2257
*BytesInOemString PCHAR OemString
Definition: rtlfuncs.h:1560
#define IN
Definition: typedefs.h:39
BOOLEAN NTAPI RtlIsNameLegalDOS8Dot3(_In_ PUNICODE_STRING Name, _Inout_opt_ POEM_STRING OemName, _Inout_opt_ PBOOLEAN NameContainsSpaces)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_Inout_opt_ POEM_STRING _Out_opt_ PBOOLEAN NameContainsSpaces
Definition: rtlfuncs.h:3036
BOOLEAN NTAPI RtlIsValidOemCharacter(IN PWCHAR Char)
Definition: unicode.c:514
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
#define HIBYTE(W)
Definition: jmemdos.c:486
uint16_t * PWCHAR
Definition: typedefs.h:56
STRING OEM_STRING
Definition: umtypes.h:203
#define NTSYSAPI
Definition: ntoskrnl.h:14
_IRQL_requires_max_(PASSIVE_LEVEL)
Definition: dos8dot3.c:244
#define Dot(u, v)
Definition: normal.c:49
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
unsigned char BOOLEAN
Definition: bufpool.h:45
Status
Definition: gdiplustypes.h:24
BOOLEAN * NlsMbOemCodePageTag
Definition: nls.c:29
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ WDFCOLLECTION _In_ ULONG Index
VOID NTAPI RtlGenerate8dot3Name(IN PUNICODE_STRING Name, IN BOOLEAN AllowExtendedCharacters, IN OUT PGENERATE_NAME_CONTEXT Context, OUT PUNICODE_STRING Name8dot3)
Definition: dos8dot3.c:81
unsigned char UCHAR
Definition: xmlstorage.h:181
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:1584
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define _Must_inspect_result_
Definition: ms_sal.h:558
NTSYSAPI NTSTATUS WINAPI RtlUpcaseUnicodeStringToCountedOemString(STRING *, const UNICODE_STRING *, BOOLEAN)
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
unsigned short USHORT
Definition: pedump.c:61
static BOOLEAN RtlpIsShortIllegal(const WCHAR Char)
Definition: dos8dot3.c:29
#define NULL
Definition: types.h:112
WCHAR NTAPI RtlpUpcaseUnicodeChar(IN WCHAR Source)
Definition: nls.c:693
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1303
static USHORT RtlpGetCheckSum(PUNICODE_STRING Name)
Definition: dos8dot3.c:35
unsigned short * PUSHORT
Definition: retypes.h:2
_In_ BOOLEAN AllowExtendedCharacters
Definition: rtlfuncs.h:1584
const ULONG RtlpShortIllegals[]
Definition: dos8dot3.c:20
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68