[SDK] One step further towards ReactOS source code tree restructure: the sdk folder...
[reactos.git] / reactos / sdk / lib / drivers / ntoskrnl_vista / fsrtl.c
1 /*
2 * PROJECT: ReactOS Kernel - Vista+ APIs
3 * LICENSE: GPL v2 - See COPYING in the top level directory
4 * FILE: lib/drivers/ntoskrnl_vista/fsrtl.c
5 * PURPOSE: FsRtl functions of Vista+
6 * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
7 */
8
9 #include <ntdef.h>
10 #include <ntifs.h>
11
12 NTKERNELAPI
13 NTSTATUS
14 NTAPI
15 FsRtlRemoveDotsFromPath(IN PWSTR OriginalString,
16 IN USHORT PathLength,
17 OUT USHORT *NewLength)
18 {
19 USHORT Length, ReadPos, WritePos;
20
21 Length = PathLength / sizeof(WCHAR);
22
23 if (Length == 3 && OriginalString[0] == '\\' && OriginalString[1] == '.' && OriginalString[2] == '.')
24 {
25 return STATUS_IO_REPARSE_DATA_INVALID;
26 }
27
28 if (Length == 2 && OriginalString[0] == '.' && OriginalString[1] == '.')
29 {
30 return STATUS_IO_REPARSE_DATA_INVALID;
31 }
32
33 if (Length > 2 && OriginalString[0] == '.' && OriginalString[1] == '.' && OriginalString[2] == '\\')
34 {
35 return STATUS_IO_REPARSE_DATA_INVALID;
36 }
37
38 for (ReadPos = 0, WritePos = 0; ReadPos < Length; ++WritePos)
39 {
40 for (; ReadPos > 0 && ReadPos < Length; ++ReadPos)
41 {
42 if (ReadPos < Length - 1 && OriginalString[ReadPos] == '\\' && OriginalString[ReadPos + 1] == '\\')
43 {
44 continue;
45 }
46
47 if (OriginalString[ReadPos] != '.')
48 {
49 break;
50 }
51
52 if (ReadPos == Length - 1)
53 {
54 if (OriginalString[ReadPos - 1] == '\\')
55 {
56 if (WritePos > 1)
57 {
58 --WritePos;
59 }
60
61 continue;
62 }
63
64 OriginalString[WritePos] = '.';
65 ++WritePos;
66 continue;
67 }
68
69 if (OriginalString[ReadPos + 1] == '\\')
70 {
71 if (OriginalString[ReadPos - 1] != '\\')
72 {
73 OriginalString[WritePos] = '.';
74 ++WritePos;
75 continue;
76 }
77 }
78 else
79 {
80 if (OriginalString[ReadPos + 1] != '.' || OriginalString[ReadPos - 1] != '\\' ||
81 ((ReadPos != Length - 2) && OriginalString[ReadPos + 2] != '\\'))
82 {
83 OriginalString[WritePos] = '.';
84 ++WritePos;
85 continue;
86 }
87
88 for (WritePos -= 2; (SHORT)WritePos > 0 && OriginalString[WritePos] != '\\'; --WritePos);
89
90 if ((SHORT)WritePos < 0 || OriginalString[WritePos] != '\\')
91 {
92 return STATUS_IO_REPARSE_DATA_INVALID;
93 }
94
95 if (WritePos == 0 && ReadPos == Length - 2)
96 {
97 WritePos = 1;
98 }
99 }
100
101 ++ReadPos;
102 }
103
104 if (ReadPos >= Length)
105 {
106 break;
107 }
108
109 OriginalString[WritePos] = OriginalString[ReadPos];
110 ++ReadPos;
111 }
112
113 *NewLength = WritePos * sizeof(WCHAR);
114
115 while (WritePos < Length)
116 {
117 OriginalString[WritePos++] = UNICODE_NULL;
118 }
119
120 return STATUS_SUCCESS;
121 }