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