1 /*
2  * PROJECT:     ReactOS API Tests
3  * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4  * PURPOSE:     Test for RtlGetLengthWithoutLastFullDosOrNtPathElement
5  * COPYRIGHT:   Copyright 2021 Mark Jansen <mark.jansen@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
10 
11 NTSTATUS
12 NTAPI
13 RtlGetLengthWithoutLastFullDosOrNtPathElement(
14     IN ULONG Flags,
15     IN PCUNICODE_STRING Path,
16     OUT PULONG LengthOut);
17 
18 
19 typedef struct _rtl_test_data
20 {
21     LPCWSTR Path;
22     ULONG Length;
23     NTSTATUS Status;
24 } rtl_test_data;
25 
26 // Based on http://undoc.airesoft.co.uk/ntdll.dll/RtlGetLengthWithoutLastFullDosOrNtPathElement.php
27 rtl_test_data tests[] = {
28     { L"", 0, STATUS_SUCCESS, },
29     { L"C", 0, STATUS_INVALID_PARAMETER, },
30     { L"C:", 0, STATUS_INVALID_PARAMETER, },
31     { L"C:\\", 0, STATUS_SUCCESS, },
32     { L"C:\\test", 3, STATUS_SUCCESS, },
33     { L"C:\\test\\", 3, STATUS_SUCCESS, },
34     { L"C:\\test\\a", 8, STATUS_SUCCESS, },
35     { L"C:\\test\\a\\", 8, STATUS_SUCCESS, },
36     { L"C://test", 3, STATUS_SUCCESS, },
37     { L"C://test\\", 3, STATUS_SUCCESS, },
38     { L"C://test\\\\", 3, STATUS_SUCCESS, },
39     { L"C://test/", 3, STATUS_SUCCESS, },
40     { L"C://test//", 3, STATUS_SUCCESS, },
41     { L"C://test\\a", 9, STATUS_SUCCESS, },
42     { L"C://test\\\\a", 9, STATUS_SUCCESS, },
43     { L"C://test/a", 9, STATUS_SUCCESS, },
44     { L"C://test//a", 9, STATUS_SUCCESS, },
45     { L"C://test\\a\\", 9, STATUS_SUCCESS, },
46     { L"C://test//a//", 9, STATUS_SUCCESS, },
47     { L"C://test//a/", 9, STATUS_SUCCESS, },
48     { L"X", 0, STATUS_INVALID_PARAMETER, },
49     { L"X:", 0, STATUS_INVALID_PARAMETER, },
50     { L"X:\\", 0, STATUS_SUCCESS, },
51     { L"D:\\Test\\hello.ext", 8, STATUS_SUCCESS, },
52     { L"\\\\?\\C", 0, STATUS_INVALID_PARAMETER, },
53     { L"\\\\?\\C:", 0, STATUS_INVALID_PARAMETER, },
54     { L"\\\\?\\CC", 0, STATUS_INVALID_PARAMETER, },
55     { L"\\\\?\\C:\\", 4, STATUS_SUCCESS, },
56     { L"\\\\?\\::\\", 4, STATUS_SUCCESS, },
57     { L"\\\\?\\CCC", 0, STATUS_INVALID_PARAMETER, },
58     { L"\\\\?\\CCC\\", 0, STATUS_INVALID_PARAMETER, },
59     { L"\\??\\UNC\\Mytest", 8, STATUS_SUCCESS, },
60     { L"\\SystemRoot", 0, STATUS_SUCCESS, },
61     { L"\\SystemRoot\\", 0, STATUS_SUCCESS, },
62     { L"\\SystemRoot\\ntdll.dll", 12, STATUS_SUCCESS, },
63     { L"\\Device\\HarddiskVolume9000", 8, STATUS_SUCCESS, },
64     { L"\\Stuff\\doesnt\\really\\matter", 21, STATUS_SUCCESS, },
65     { L"this\\doesnt\\really\\work", 0, STATUS_INVALID_PARAMETER, },
66     { L"multi(0)disk(0)rdisk(0)partition(1)", 0, STATUS_INVALID_PARAMETER, },
67     { L"multi(0)disk(0)rdisk(0)partition(1)\\test", 0, STATUS_INVALID_PARAMETER, },
68     { L"xyz", 0, STATUS_INVALID_PARAMETER, },
69     { L"CON", 0, STATUS_INVALID_PARAMETER, },
70     { L":", 0, STATUS_INVALID_PARAMETER, },
71     { L"\\\\", 0, STATUS_SUCCESS, },
72 };
73 
74 
75 START_TEST(RtlGetLengthWithoutLastFullDosOrNtPathElement)
76 {
77     UNICODE_STRING Dum;
78     NTSTATUS Status;
79     ULONG Length;
80     RtlInitUnicodeString(&Dum, L"c:\\test\\");
81 
82     Length = 333;
83     Status = RtlGetLengthWithoutLastFullDosOrNtPathElement(0, NULL, &Length);
84     ok_int(Length, 0);
85     ok_hex(Status, STATUS_INVALID_PARAMETER);
86 
87     Status = RtlGetLengthWithoutLastFullDosOrNtPathElement(0, &Dum, NULL);
88     ok_hex(Status, STATUS_INVALID_PARAMETER);
89 
90     for (ULONG n = 0; n < 32; ++n)
91     {
92         Length = 333;
93         Status = RtlGetLengthWithoutLastFullDosOrNtPathElement((1 << n), &Dum, &Length);
94         ok_int(Length, 0);
95         ok_hex(Status, STATUS_INVALID_PARAMETER);
96     }
97 
98     for (ULONG n = 0; n < ARRAYSIZE(tests); ++n)
99     {
100         UNICODE_STRING Str;
101         Length = 333;
102 
103         RtlInitUnicodeString(&Str, tests[n].Path);
104 
105         Status = RtlGetLengthWithoutLastFullDosOrNtPathElement(0, &Str, &Length);
106         ok(Status == tests[n].Status, "Got Status=0x%lx, expected 0x%lx (%S)\n", Status, tests[n].Status, Str.Buffer);
107         ok(Length == tests[n].Length, "Got Length=0x%lx, expected 0x%lx (%S)\n", Length, tests[n].Length, Str.Buffer);
108     }
109 }
110