1 // This file is converted by code7bit.
2 // code7bit: https://github.com/katahiromz/code7bit
3 // To revert conversion, please execute "code7bit -r <file>".
4 /*
5  * PROJECT:         ReactOS api tests
6  * LICENSE:         GPLv2+ - See COPYING in the top level directory
7  * PURPOSE:         Test for RtlGenerate8dot3Name
8  * PROGRAMMER:      Pierre Schweitzer <pierre@reactos.org>
9  */
10 
11 #include "precomp.h"
12 
13 NTSYSAPI
14 VOID
15 NTAPI
16 RtlGenerate8dot3Name(
17   _In_ PCUNICODE_STRING Name,
18   _In_ BOOLEAN AllowExtendedCharacters,
19   _Inout_ PGENERATE_NAME_CONTEXT Context,
20   _Inout_ PUNICODE_STRING Name8dot3);
21 
22 #define NAMES_COUNT 14
23 #define LOCALES_COUNT 3
24 
25 PWSTR Names[NAMES_COUNT] = { L"Menu D\u00E9marrer", L"S\u00E9lecteur de configuration clavier.lnk", L"\u00E9\u00E8\u00E0\u00F9\u00E7.txt", L"\u00E7\u00F9\u00E0\u00E8\u00E9.txt", L"\u00E9\u00E8\u00E0\u00F9.txt", L"\u00E7\u00F9\u00E0\u00E8.txt", L"\u00E9\u00E8\u00E0\u00F9\u00E7eeauc.txt", L"\u00E9e\u00E8\u00E9\u00E7c\u00F9u.txt", L"test.\u00E9x\u00E8", L"t\u00A3$t\u00A4.txt", L"Long file name.txt", L"Long file name", L"Longfilename.txt", L"Longfilename" };
26 PWSTR ShortNames1[LOCALES_COUNT][NAMES_COUNT] =
27 {
28     { 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" },
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 };
32 PWSTR ShortNames2[LOCALES_COUNT][NAMES_COUNT] =
33 {
34     { 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" },
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 };
38 PWSTR ExShortNames1[LOCALES_COUNT][NAMES_COUNT] =
39 {
40     { L"MENUD\u00C9~1", L"S\u00C9LECT~1.LNK", L"\u00C9\u00C8\u00C0\u00D9\u00C7~1.TXT", L"\u00C7\u00D9\u00C0\u00C8\u00C9~1.TXT", L"\u00C9\u00C8\u00C0\u00D9~1.TXT", L"\u00C7\u00D9\u00C0\u00C8~1.TXT", L"\u00C9\u00C8\u00C0\u00D9\u00C7E~1.TXT", L"\u00C9E\u00C8\u00C9\u00C7C~1.TXT", L"TEST~1.\u00C9X\u00C8", L"T\u00A3$T\u00A4~1.TXT", L"LONGFI~1.TXT", L"LONGFI~1", L"LONGFI~1.TXT", L"LONGFI~1" },
41     { L"MENUD\u00C9~1", L"S\u00C9LECT~1.LNK", L"\u00C9\u00C8\u00C0\u00D9\u00C7~1.TXT", L"\u00C7\u00D9\u00C0\u00C8\u00C9~1.TXT", L"\u00C9\u00C8\u00C0\u00D9~1.TXT", L"\u00C7\u00D9\u00C0\u00C8~1.TXT", L"\u00C9\u00C8\u00C0\u00D9\u00C7E~1.TXT", L"\u00C9E\u00C8\u00C9\u00C7C~1.TXT", L"TEST~1.\u00C9X\u00C8", L"T\u00A3$T_~1.TXT", L"LONGFI~1.TXT", L"LONGFI~1", L"LONGFI~1.TXT", L"LONGFI~1" },
42     { L"MENUD\u00C9~1", L"S\u00C9LECT~1.LNK", L"\u00C9CAU~1.TXT", L"UAC\u00C9~1.TXT", L"\u00C9CAU~1.TXT", L"UAC~1.TXT", L"\u00C9CAUEE~1.TXT", L"\u00C9EC\u00C9CU~1.TXT", L"TEST~1.\u00C9XC", L"T\u00A3$T\u00A4~1.TXT", L"LONGFI~1.TXT", L"LONGFI~1", L"LONGFI~1.TXT", L"LONGFI~1" },
43 };
44 PWSTR ExShortNames2[LOCALES_COUNT][NAMES_COUNT] =
45 {
46     { L"MENUD\u00C9~2", L"S\u00C9LECT~2.LNK", L"\u00C9\u00C8\u00C0\u00D9\u00C7~2.TXT", L"\u00C7\u00D9\u00C0\u00C8\u00C9~2.TXT", L"\u00C9\u00C8\u00C0\u00D9~2.TXT", L"\u00C7\u00D9\u00C0\u00C8~2.TXT", L"\u00C9\u00C8\u00C0\u00D9\u00C7E~2.TXT", L"\u00C9E\u00C8\u00C9\u00C7C~2.TXT", L"TEST~2.\u00C9X\u00C8", L"T\u00A3$T\u00A4~2.TXT", L"LONGFI~2.TXT", L"LONGFI~2", L"LONGFI~2.TXT", L"LONGFI~2" },
47     { L"MENUD\u00C9~2", L"S\u00C9LECT~2.LNK", L"\u00C9\u00C8\u00C0\u00D9\u00C7~2.TXT", L"\u00C7\u00D9\u00C0\u00C8\u00C9~2.TXT", L"\u00C9\u00C8\u00C0\u00D9~2.TXT", L"\u00C7\u00D9\u00C0\u00C8~2.TXT", L"\u00C9\u00C8\u00C0\u00D9\u00C7E~2.TXT", L"\u00C9E\u00C8\u00C9\u00C7C~2.TXT", L"TEST~2.\u00C9X\u00C8", L"T\u00A3$T_~2.TXT", L"LONGFI~2.TXT", L"LONGFI~2", L"LONGFI~2.TXT", L"LONGFI~2" },
48     { L"MENUD\u00C9~2", L"S\u00C9LECT~2.LNK", L"\u00C9CAU~2.TXT", L"UAC\u00C9~2.TXT", L"\u00C9CAU~2.TXT", L"UAC~2.TXT", L"\u00C9CAUEE~2.TXT", L"\u00C9EC\u00C9CU~2.TXT", L"TEST~2.\u00C9XC", L"T\u00A3$T\u00A4~2.TXT", L"LONGFI~2.TXT", L"LONGFI~2", L"LONGFI~2.TXT", L"LONGFI~2" },
49 };
50 
51 ULONG Locales[LOCALES_COUNT][2] =
52 {
53     {1252, 850}, // Most used for latin langs
54     {1252, 437}, // Used for English US (not only)
55     {1252, 775}, // Used for Estonian
56 };
57 
58 #define LONG_NAMES_COUNT 12
59 PWSTR LongNames[LONG_NAMES_COUNT] =
60 {
61     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",
62     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",
63 };
64 
65 PWSTR LongShortNames[LONG_NAMES_COUNT] =
66 {
67     L"LONGFI~1.TXT", L"LONGFI~2.TXT", L"LONGFI~3.TXT", L"LONGFI~4.TXT", L"LO1796~1.TXT", L"LO1796~2.TXT",
68     L"VERYLO~1.TXT", L"VERYLO~2.TXT", L"VERYLO~3.TXT", L"VERYLO~4.TXT", L"VED051~1.TXT", L"VED051~2.TXT",
69 };
70 
71 PVOID LoadCodePageData(ULONG Code)
72 {
73     char filename[MAX_PATH], sysdir[MAX_PATH];
74     HANDLE hFile;
75     PVOID Data = NULL;
76     GetSystemDirectoryA(sysdir, MAX_PATH);
77 
78     if (Code != -1)
79         StringCbPrintfA(filename, sizeof(filename), "%s\\c_%lu.nls", sysdir, Code);
80     else
81         StringCbPrintfA(filename, sizeof(filename), "%s\\l_intl.nls", sysdir);
82 
83     hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
84     if (hFile != INVALID_HANDLE_VALUE)
85     {
86         DWORD dwRead;
87         DWORD dwFileSize = GetFileSize(hFile, NULL);
88         Data = malloc(dwFileSize);
89         ReadFile(hFile, Data, dwFileSize, &dwRead, NULL);
90         CloseHandle(hFile);
91     }
92     return Data;
93 }
94 
95 /* https://www.microsoft.com/resources/msdn/goglobal/default.mspx */
96 void SetupLocale(ULONG AnsiCode, ULONG OemCode, ULONG Unicode)
97 {
98     NLSTABLEINFO NlsTable;
99     PVOID AnsiCodePageData;
100     PVOID OemCodePageData;
101     PVOID UnicodeCaseTableData;
102 
103     AnsiCodePageData = LoadCodePageData(AnsiCode);
104     OemCodePageData = LoadCodePageData(OemCode);
105     UnicodeCaseTableData = LoadCodePageData(Unicode);
106 
107     RtlInitNlsTables(AnsiCodePageData, OemCodePageData, UnicodeCaseTableData, &NlsTable);
108     RtlResetRtlTranslations(&NlsTable);
109     /* Do NOT free the buffers here, they are directly used!
110         Yes, we leak the old buffers, but this is a test anyway... */
111 
112 }
113 
114 START_TEST(RtlGenerate8dot3Name)
115 {
116     USHORT i, j;
117 
118     for (j = 0; j < LOCALES_COUNT; ++j)
119     {
120         /* Setup locale. */
121         SetupLocale(Locales[j][0], Locales[j][1], -1);
122 
123         for (i = 0; i < NAMES_COUNT; ++i)
124         {
125             WCHAR Buffer[12];
126             GENERATE_NAME_CONTEXT Context;
127             UNICODE_STRING LongName, ShortName, Expected;
128 
129             RtlZeroMemory(&Context, sizeof(GENERATE_NAME_CONTEXT));
130             RtlInitUnicodeString(&LongName, Names[i]);
131             ShortName.Buffer = Buffer;
132             ShortName.Length = 0;
133             ShortName.MaximumLength = sizeof(Buffer);
134 
135             RtlGenerate8dot3Name(&LongName, FALSE, &Context, &ShortName);
136             RtlInitUnicodeString(&Expected, ShortNames1[j][i]);
137             ok(RtlEqualUnicodeString(&Expected, &ShortName, FALSE), "%u:: Generated: %.*S. Expected: %.*S\n", j, ShortName.Length / sizeof(WCHAR), ShortName.Buffer, Expected.Length / sizeof(WCHAR), Expected.Buffer);
138 
139             ShortName.Length = 0;
140             RtlGenerate8dot3Name(&LongName, FALSE, &Context, &ShortName);
141             RtlInitUnicodeString(&Expected, ShortNames2[j][i]);
142             ok(RtlEqualUnicodeString(&Expected, &ShortName, FALSE), "%u:: Generated: %.*S. Expected: %.*S\n", j, ShortName.Length / sizeof(WCHAR), ShortName.Buffer, Expected.Length / sizeof(WCHAR), Expected.Buffer);
143 
144             RtlZeroMemory(&Context, sizeof(GENERATE_NAME_CONTEXT));
145             ShortName.Length = 0;
146             RtlGenerate8dot3Name(&LongName, TRUE, &Context, &ShortName);
147             RtlInitUnicodeString(&Expected, ExShortNames1[j][i]);
148             ok(RtlEqualUnicodeString(&Expected, &ShortName, FALSE), "%u:: Generated: %.*S. Expected: %.*S\n", j, ShortName.Length / sizeof(WCHAR), ShortName.Buffer, Expected.Length / sizeof(WCHAR), Expected.Buffer);
149 
150             ShortName.Length = 0;
151             RtlGenerate8dot3Name(&LongName, TRUE, &Context, &ShortName);
152             RtlInitUnicodeString(&Expected, ExShortNames2[j][i]);
153             ok(RtlEqualUnicodeString(&Expected, &ShortName, FALSE), "%u:: Generated: %.*S. Expected: %.*S\n", j, ShortName.Length / sizeof(WCHAR), ShortName.Buffer, Expected.Length / sizeof(WCHAR), Expected.Buffer);
154         }
155     }
156 
157     {
158         WCHAR Buffer[12];
159         GENERATE_NAME_CONTEXT Context;
160         UNICODE_STRING LongName, ShortName, Expected;
161 
162         ShortName.Buffer = Buffer;
163         ShortName.MaximumLength = sizeof(Buffer);
164 
165         for (i = 0; i < LONG_NAMES_COUNT; ++i)
166         {
167             if (i % 6 == 0) RtlZeroMemory(&Context, sizeof(GENERATE_NAME_CONTEXT));
168 
169             RtlInitUnicodeString(&LongName, LongNames[i]);
170             ShortName.Length = 0;
171 
172             RtlGenerate8dot3Name(&LongName, FALSE, &Context, &ShortName);
173             RtlInitUnicodeString(&Expected, LongShortNames[i]);
174             ok(RtlEqualUnicodeString(&Expected, &ShortName, FALSE), "%u:: Generated: %.*S. Expected: %.*S\n", i, ShortName.Length / sizeof(WCHAR), ShortName.Buffer, Expected.Length / sizeof(WCHAR), Expected.Buffer);
175         }
176     }
177 }
178