[NTDLL_APITEST]
[reactos.git] / rostests / apitests / ntdll / RtlGenerate8dot3Name.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for RtlGenerate8dot3Name
5 * PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
6 */
7
8 #include <apitest.h>
9
10 #define WIN32_NO_STATUS
11 #include <ndk/rtlfuncs.h>
12 #include <stdio.h>
13
14 NTSYSAPI
15 VOID
16 NTAPI
17 RtlGenerate8dot3Name(
18 _In_ PCUNICODE_STRING Name,
19 _In_ BOOLEAN AllowExtendedCharacters,
20 _Inout_ PGENERATE_NAME_CONTEXT Context,
21 _Inout_ PUNICODE_STRING Name8dot3);
22
23 #define NAMES_COUNT 14
24 #define LOCALES_COUNT 3
25
26 PWSTR Names[NAMES_COUNT] = { L"Menu Démarrer", L"Sélecteur de configuration clavier.lnk", L"éèàùç.txt", L"çùàèé.txt", L"éèàù.txt", L"çùàè.txt", L"éèàùçeeauc.txt", L"éeèéçcùu.txt", L"test.éxè", L"t£$t¤.txt", L"Long file name.txt", L"Long file name", L"Longfilename.txt", L"Longfilename" };
27 PWSTR ShortNames1[LOCALES_COUNT][NAMES_COUNT] =
28 {
29 { L"MENUDM~1", L"SLECTE~1.LNK", L"5C2D~1.TXT", L"423C~1.TXT", L"925E~1.TXT", L"7E4C~1.TXT", L"EEAUC~1.TXT", L"ECU~1.TXT", L"TEST~1.X", L"T$T~1.TXT", L"LONGFI~1.TXT", L"LONGFI~1", L"LONGFI~1.TXT", L"LONGFI~1" },
30 { L"MENUDM~1", L"SLECTE~1.LNK", L"5C2D~1.TXT", L"423C~1.TXT", L"925E~1.TXT", L"7E4C~1.TXT", L"EEAUC~1.TXT", L"ECU~1.TXT", L"TEST~1.X", L"T$T~1.TXT", L"LONGFI~1.TXT", L"LONGFI~1", L"LONGFI~1.TXT", L"LONGFI~1" },
31 { L"MENUDM~1", L"SLECTE~1.LNK", L"5C2D~1.TXT", L"423C~1.TXT", L"925E~1.TXT", L"7E4C~1.TXT", L"EEAUC~1.TXT", L"ECU~1.TXT", L"TEST~1.X", L"T$T~1.TXT", L"LONGFI~1.TXT", L"LONGFI~1", L"LONGFI~1.TXT", L"LONGFI~1" },
32 };
33 PWSTR ShortNames2[LOCALES_COUNT][NAMES_COUNT] =
34 {
35 { L"MENUDM~2", L"SLECTE~2.LNK", L"5C2D~2.TXT", L"423C~2.TXT", L"925E~2.TXT", L"7E4C~2.TXT", L"EEAUC~2.TXT", L"ECU~2.TXT", L"TEST~2.X", L"T$T~2.TXT", L"LONGFI~2.TXT", L"LONGFI~2", L"LONGFI~2.TXT", L"LONGFI~2" },
36 { L"MENUDM~2", L"SLECTE~2.LNK", L"5C2D~2.TXT", L"423C~2.TXT", L"925E~2.TXT", L"7E4C~2.TXT", L"EEAUC~2.TXT", L"ECU~2.TXT", L"TEST~2.X", L"T$T~2.TXT", L"LONGFI~2.TXT", L"LONGFI~2", L"LONGFI~2.TXT", L"LONGFI~2" },
37 { L"MENUDM~2", L"SLECTE~2.LNK", L"5C2D~2.TXT", L"423C~2.TXT", L"925E~2.TXT", L"7E4C~2.TXT", L"EEAUC~2.TXT", L"ECU~2.TXT", L"TEST~2.X", L"T$T~2.TXT", L"LONGFI~2.TXT", L"LONGFI~2", L"LONGFI~2.TXT", L"LONGFI~2" },
38 };
39 PWSTR ExShortNames1[LOCALES_COUNT][NAMES_COUNT] =
40 {
41 { L"MENUDÉ~1", L"SÉLECT~1.LNK", L"ÉÈÀÙÇ~1.TXT", L"ÇÙÀÈÉ~1.TXT", L"ÉÈÀÙ~1.TXT", L"ÇÙÀÈ~1.TXT", L"ÉÈÀÙÇE~1.TXT", L"ÉEÈÉÇC~1.TXT", L"TEST~1.ÉXÈ", L"T£$T¤~1.TXT", L"LONGFI~1.TXT", L"LONGFI~1", L"LONGFI~1.TXT", L"LONGFI~1" },
42 { L"MENUDÉ~1", L"SÉLECT~1.LNK", L"ÉÈÀÙÇ~1.TXT", L"ÇÙÀÈÉ~1.TXT", L"ÉÈÀÙ~1.TXT", L"ÇÙÀÈ~1.TXT", L"ÉÈÀÙÇE~1.TXT", L"ÉEÈÉÇC~1.TXT", L"TEST~1.ÉXÈ", L"T£$T_~1.TXT", L"LONGFI~1.TXT", L"LONGFI~1", L"LONGFI~1.TXT", L"LONGFI~1" },
43 { L"MENUDÉ~1", L"SÉLECT~1.LNK", L"ÉCAU~1.TXT", L"UACÉ~1.TXT", L"ÉCAU~1.TXT", L"UAC~1.TXT", L"ÉCAUEE~1.TXT", L"ÉECÉCU~1.TXT", L"TEST~1.ÉXC", L"T£$T¤~1.TXT", L"LONGFI~1.TXT", L"LONGFI~1", L"LONGFI~1.TXT", L"LONGFI~1" },
44 };
45 PWSTR ExShortNames2[LOCALES_COUNT][NAMES_COUNT] =
46 {
47 { L"MENUDÉ~2", L"SÉLECT~2.LNK", L"ÉÈÀÙÇ~2.TXT", L"ÇÙÀÈÉ~2.TXT", L"ÉÈÀÙ~2.TXT", L"ÇÙÀÈ~2.TXT", L"ÉÈÀÙÇE~2.TXT", L"ÉEÈÉÇC~2.TXT", L"TEST~2.ÉXÈ", L"T£$T¤~2.TXT", L"LONGFI~2.TXT", L"LONGFI~2", L"LONGFI~2.TXT", L"LONGFI~2" },
48 { L"MENUDÉ~2", L"SÉLECT~2.LNK", L"ÉÈÀÙÇ~2.TXT", L"ÇÙÀÈÉ~2.TXT", L"ÉÈÀÙ~2.TXT", L"ÇÙÀÈ~2.TXT", L"ÉÈÀÙÇE~2.TXT", L"ÉEÈÉÇC~2.TXT", L"TEST~2.ÉXÈ", L"T£$T_~2.TXT", L"LONGFI~2.TXT", L"LONGFI~2", L"LONGFI~2.TXT", L"LONGFI~2" },
49 { L"MENUDÉ~2", L"SÉLECT~2.LNK", L"ÉCAU~2.TXT", L"UACÉ~2.TXT", L"ÉCAU~2.TXT", L"UAC~2.TXT", L"ÉCAUEE~2.TXT", L"ÉECÉCU~2.TXT", L"TEST~2.ÉXC", L"T£$T¤~2.TXT", L"LONGFI~2.TXT", L"LONGFI~2", L"LONGFI~2.TXT", L"LONGFI~2" },
50 };
51
52 ULONG Locales[LOCALES_COUNT][2] =
53 {
54 {1252, 850}, // Most used for latin langs
55 {1252, 437}, // Used for English US (not only)
56 {1252, 775}, // Used for Estonian
57 };
58
59 #define LONG_NAMES_COUNT 12
60 PWSTR LongNames[LONG_NAMES_COUNT] =
61 {
62 L"Long File Name 1.txt", L"Long File Name 2.txt", L"Long File Name 3.txt", L"Long File Name 4.txt", L"Long File Name 5.txt", L"Long File Name 6.txt",
63 L"Very Long File Name 1.txt", L"Very Long File Name 2.txt", L"Very Long File Name 3.txt", L"Very Long File Name 4.txt", L"Very Long File Name 5.txt", L"Very Long File Name 6.txt",
64 };
65
66 PWSTR LongShortNames[LONG_NAMES_COUNT] =
67 {
68 L"LONGFI~1.TXT", L"LONGFI~2.TXT", L"LONGFI~3.TXT", L"LONGFI~4.TXT", L"LO1796~1.TXT", L"LO1796~2.TXT",
69 L"VERYLO~1.TXT", L"VERYLO~2.TXT", L"VERYLO~3.TXT", L"VERYLO~4.TXT", L"VED051~1.TXT", L"VED051~2.TXT",
70 };
71
72 PVOID LoadCodePageData(ULONG Code)
73 {
74 char filename[MAX_PATH], sysdir[MAX_PATH];
75 HANDLE hFile;
76 PVOID Data = NULL;
77 GetSystemDirectoryA(sysdir, MAX_PATH);
78
79 if (Code != -1)
80 sprintf(filename, "%s\\c_%lu.nls", sysdir, Code);
81 else
82 sprintf(filename, "%s\\l_intl.nls", sysdir);
83
84 hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
85 if (hFile != INVALID_HANDLE_VALUE)
86 {
87 DWORD dwRead;
88 DWORD dwFileSize = GetFileSize(hFile, NULL);
89 Data = malloc(dwFileSize);
90 ReadFile(hFile, Data, dwFileSize, &dwRead, NULL);
91 CloseHandle(hFile);
92 }
93 return Data;
94 }
95
96 /* https://www.microsoft.com/resources/msdn/goglobal/default.mspx */
97 void SetupLocale(ULONG AnsiCode, ULONG OemCode, ULONG Unicode)
98 {
99 NLSTABLEINFO NlsTable;
100 PVOID AnsiCodePageData;
101 PVOID OemCodePageData;
102 PVOID UnicodeCaseTableData;
103
104 AnsiCodePageData = LoadCodePageData(AnsiCode);
105 OemCodePageData = LoadCodePageData(OemCode);
106 UnicodeCaseTableData = LoadCodePageData(Unicode);
107
108 RtlInitNlsTables(AnsiCodePageData, OemCodePageData, UnicodeCaseTableData, &NlsTable);
109 RtlResetRtlTranslations(&NlsTable);
110 /* Do NOT free the buffers here, they are directly used!
111 Yes, we leak the old buffers, but this is a test anyway... */
112
113 }
114
115 START_TEST(RtlGenerate8dot3Name)
116 {
117 USHORT i, j;
118
119 for (j = 0; j < LOCALES_COUNT; ++j)
120 {
121 /* Setup locale. */
122 SetupLocale(Locales[j][0], Locales[j][1], -1);
123
124 for (i = 0; i < NAMES_COUNT; ++i)
125 {
126 WCHAR Buffer[12];
127 GENERATE_NAME_CONTEXT Context;
128 UNICODE_STRING LongName, ShortName, Expected;
129
130 RtlZeroMemory(&Context, sizeof(GENERATE_NAME_CONTEXT));
131 RtlInitUnicodeString(&LongName, Names[i]);
132 ShortName.Buffer = Buffer;
133 ShortName.Length = 0;
134 ShortName.MaximumLength = sizeof(Buffer);
135
136 RtlGenerate8dot3Name(&LongName, FALSE, &Context, &ShortName);
137 RtlInitUnicodeString(&Expected, ShortNames1[j][i]);
138 ok(RtlEqualUnicodeString(&Expected, &ShortName, FALSE), "%u:: Generated: %.*S. Expected: %.*S\n", j, ShortName.Length / sizeof(WCHAR), ShortName.Buffer, Expected.Length / sizeof(WCHAR), Expected.Buffer);
139
140 ShortName.Length = 0;
141 RtlGenerate8dot3Name(&LongName, FALSE, &Context, &ShortName);
142 RtlInitUnicodeString(&Expected, ShortNames2[j][i]);
143 ok(RtlEqualUnicodeString(&Expected, &ShortName, FALSE), "%u:: Generated: %.*S. Expected: %.*S\n", j, ShortName.Length / sizeof(WCHAR), ShortName.Buffer, Expected.Length / sizeof(WCHAR), Expected.Buffer);
144
145 RtlZeroMemory(&Context, sizeof(GENERATE_NAME_CONTEXT));
146 ShortName.Length = 0;
147 RtlGenerate8dot3Name(&LongName, TRUE, &Context, &ShortName);
148 RtlInitUnicodeString(&Expected, ExShortNames1[j][i]);
149 ok(RtlEqualUnicodeString(&Expected, &ShortName, FALSE), "%u:: Generated: %.*S. Expected: %.*S\n", j, ShortName.Length / sizeof(WCHAR), ShortName.Buffer, Expected.Length / sizeof(WCHAR), Expected.Buffer);
150
151 ShortName.Length = 0;
152 RtlGenerate8dot3Name(&LongName, TRUE, &Context, &ShortName);
153 RtlInitUnicodeString(&Expected, ExShortNames2[j][i]);
154 ok(RtlEqualUnicodeString(&Expected, &ShortName, FALSE), "%u:: Generated: %.*S. Expected: %.*S\n", j, ShortName.Length / sizeof(WCHAR), ShortName.Buffer, Expected.Length / sizeof(WCHAR), Expected.Buffer);
155 }
156 }
157
158 {
159 WCHAR Buffer[12];
160 GENERATE_NAME_CONTEXT Context;
161 UNICODE_STRING LongName, ShortName, Expected;
162
163 ShortName.Buffer = Buffer;
164 ShortName.MaximumLength = sizeof(Buffer);
165
166 for (i = 0; i < LONG_NAMES_COUNT; ++i)
167 {
168 if (i % 6 == 0) RtlZeroMemory(&Context, sizeof(GENERATE_NAME_CONTEXT));
169
170 RtlInitUnicodeString(&LongName, LongNames[i]);
171 ShortName.Length = 0;
172
173 RtlGenerate8dot3Name(&LongName, FALSE, &Context, &ShortName);
174 RtlInitUnicodeString(&Expected, LongShortNames[i]);
175 ok(RtlEqualUnicodeString(&Expected, &ShortName, FALSE), "%u:: Generated: %.*S. Expected: %.*S\n", i, ShortName.Length / sizeof(WCHAR), ShortName.Buffer, Expected.Length / sizeof(WCHAR), Expected.Buffer);
176 }
177 }
178 }