[NTOSKRNL_VISTA]
[reactos.git] / reactos / 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 = 0;
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 if (Length > 0)
39 {
40 ReadPos = 0;
41
42 for (; ReadPos < Length; ++WritePos)
43 {
44 for (; ReadPos < Length; ++ReadPos)
45 {
46 if (ReadPos < Length - 1 && OriginalString[ReadPos] == '\\' && OriginalString[ReadPos + 1] == '\\')
47 {
48 continue;
49 }
50
51 if (OriginalString[ReadPos] != '.')
52 {
53 break;
54 }
55
56 if (ReadPos == Length - 1)
57 {
58 if (OriginalString[ReadPos - 1] == '\\')
59 {
60 if (WritePos > 1)
61 {
62 --WritePos;
63 }
64
65 continue;
66 }
67
68 OriginalString[WritePos] = '.';
69 ++WritePos;
70 continue;
71 }
72
73 if (OriginalString[ReadPos + 1] == '\\')
74 {
75 if (OriginalString[ReadPos - 1] != '\\')
76 {
77 OriginalString[WritePos] = '.';
78 ++WritePos;
79 continue;
80 }
81 }
82 else
83 {
84 if (OriginalString[ReadPos + 1] != '.' || OriginalString[ReadPos - 1] != '\\' ||
85 ((ReadPos != Length - 2) && OriginalString[ReadPos + 2] != '\\'))
86 {
87 OriginalString[WritePos] = '.';
88 ++WritePos;
89 continue;
90 }
91
92 for (WritePos -= 2; (SHORT)WritePos > 0 && OriginalString[WritePos] != '\\'; --WritePos);
93
94 if ((SHORT)WritePos < 0 || OriginalString[WritePos] != '\\')
95 {
96 return STATUS_IO_REPARSE_DATA_INVALID;
97 }
98
99 if (WritePos == 0 && ReadPos == Length - 2)
100 {
101 WritePos = 1;
102 }
103 }
104
105 ++ReadPos;
106 }
107
108 OriginalString[WritePos] = OriginalString[ReadPos];
109 ++ReadPos;
110 }
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 }